folio-migration-tools 1.2.1__py3-none-any.whl → 1.9.10__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 +11 -0
- folio_migration_tools/__main__.py +169 -85
- folio_migration_tools/circulation_helper.py +96 -59
- folio_migration_tools/config_file_load.py +66 -0
- folio_migration_tools/custom_dict.py +6 -4
- folio_migration_tools/custom_exceptions.py +21 -19
- folio_migration_tools/extradata_writer.py +46 -0
- folio_migration_tools/folder_structure.py +63 -66
- folio_migration_tools/helper.py +29 -21
- folio_migration_tools/holdings_helper.py +57 -34
- folio_migration_tools/i18n_config.py +9 -0
- folio_migration_tools/library_configuration.py +173 -13
- folio_migration_tools/mapper_base.py +317 -106
- folio_migration_tools/mapping_file_transformation/courses_mapper.py +203 -0
- folio_migration_tools/mapping_file_transformation/holdings_mapper.py +83 -69
- folio_migration_tools/mapping_file_transformation/item_mapper.py +98 -94
- folio_migration_tools/mapping_file_transformation/manual_fee_fines_mapper.py +352 -0
- folio_migration_tools/mapping_file_transformation/mapping_file_mapper_base.py +702 -223
- folio_migration_tools/mapping_file_transformation/notes_mapper.py +90 -0
- folio_migration_tools/mapping_file_transformation/order_mapper.py +492 -0
- folio_migration_tools/mapping_file_transformation/organization_mapper.py +389 -0
- folio_migration_tools/mapping_file_transformation/ref_data_mapping.py +38 -27
- folio_migration_tools/mapping_file_transformation/user_mapper.py +149 -361
- folio_migration_tools/marc_rules_transformation/conditions.py +650 -246
- folio_migration_tools/marc_rules_transformation/holdings_statementsparser.py +292 -130
- folio_migration_tools/marc_rules_transformation/hrid_handler.py +244 -0
- folio_migration_tools/marc_rules_transformation/loc_language_codes.xml +20846 -0
- folio_migration_tools/marc_rules_transformation/marc_file_processor.py +300 -0
- folio_migration_tools/marc_rules_transformation/marc_reader_wrapper.py +136 -0
- folio_migration_tools/marc_rules_transformation/rules_mapper_authorities.py +241 -0
- folio_migration_tools/marc_rules_transformation/rules_mapper_base.py +681 -201
- folio_migration_tools/marc_rules_transformation/rules_mapper_bibs.py +395 -429
- folio_migration_tools/marc_rules_transformation/rules_mapper_holdings.py +531 -100
- folio_migration_tools/migration_report.py +85 -38
- folio_migration_tools/migration_tasks/__init__.py +1 -3
- folio_migration_tools/migration_tasks/authority_transformer.py +119 -0
- folio_migration_tools/migration_tasks/batch_poster.py +911 -198
- folio_migration_tools/migration_tasks/bibs_transformer.py +121 -116
- folio_migration_tools/migration_tasks/courses_migrator.py +192 -0
- folio_migration_tools/migration_tasks/holdings_csv_transformer.py +252 -247
- folio_migration_tools/migration_tasks/holdings_marc_transformer.py +321 -115
- folio_migration_tools/migration_tasks/items_transformer.py +264 -84
- folio_migration_tools/migration_tasks/loans_migrator.py +506 -195
- folio_migration_tools/migration_tasks/manual_fee_fines_transformer.py +187 -0
- folio_migration_tools/migration_tasks/migration_task_base.py +364 -74
- folio_migration_tools/migration_tasks/orders_transformer.py +373 -0
- folio_migration_tools/migration_tasks/organization_transformer.py +451 -0
- folio_migration_tools/migration_tasks/requests_migrator.py +130 -62
- folio_migration_tools/migration_tasks/reserves_migrator.py +253 -0
- folio_migration_tools/migration_tasks/user_transformer.py +180 -139
- folio_migration_tools/task_configuration.py +46 -0
- folio_migration_tools/test_infrastructure/__init__.py +0 -0
- folio_migration_tools/test_infrastructure/mocked_classes.py +406 -0
- folio_migration_tools/transaction_migration/legacy_loan.py +148 -34
- folio_migration_tools/transaction_migration/legacy_request.py +65 -25
- folio_migration_tools/transaction_migration/legacy_reserve.py +47 -0
- folio_migration_tools/transaction_migration/transaction_result.py +12 -1
- folio_migration_tools/translations/en.json +476 -0
- folio_migration_tools-1.9.10.dist-info/METADATA +169 -0
- folio_migration_tools-1.9.10.dist-info/RECORD +67 -0
- {folio_migration_tools-1.2.1.dist-info → folio_migration_tools-1.9.10.dist-info}/WHEEL +1 -2
- folio_migration_tools-1.9.10.dist-info/entry_points.txt +3 -0
- folio_migration_tools/generate_schemas.py +0 -46
- folio_migration_tools/mapping_file_transformation/mapping_file_mapping_base_impl.py +0 -44
- folio_migration_tools/mapping_file_transformation/user_mapper_base.py +0 -212
- folio_migration_tools/marc_rules_transformation/bibs_processor.py +0 -163
- folio_migration_tools/marc_rules_transformation/holdings_processor.py +0 -284
- folio_migration_tools/report_blurbs.py +0 -219
- folio_migration_tools/transaction_migration/legacy_fee_fine.py +0 -36
- folio_migration_tools-1.2.1.dist-info/METADATA +0 -134
- folio_migration_tools-1.2.1.dist-info/RECORD +0 -50
- folio_migration_tools-1.2.1.dist-info/top_level.txt +0 -1
- {folio_migration_tools-1.2.1.dist-info → folio_migration_tools-1.9.10.dist-info/licenses}/LICENSE +0 -0
|
@@ -1,52 +1,68 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import re
|
|
3
|
+
import traceback
|
|
4
|
+
from typing import Union
|
|
3
5
|
|
|
4
|
-
import
|
|
6
|
+
import i18n
|
|
5
7
|
from folioclient import FolioClient
|
|
8
|
+
from pymarc import field
|
|
9
|
+
|
|
6
10
|
from folio_migration_tools.custom_exceptions import (
|
|
7
11
|
TransformationFieldMappingError,
|
|
8
12
|
TransformationProcessError,
|
|
9
13
|
TransformationRecordFailedError,
|
|
10
14
|
)
|
|
15
|
+
from folio_migration_tools.helper import Helper
|
|
16
|
+
from folio_migration_tools.library_configuration import FolioRelease
|
|
11
17
|
from folio_migration_tools.marc_rules_transformation.rules_mapper_base import (
|
|
12
18
|
RulesMapperBase,
|
|
13
19
|
)
|
|
14
|
-
from pymarc import field
|
|
15
|
-
from folio_migration_tools.helper import Helper
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
# flake8: noqa: s
|
|
18
22
|
|
|
19
23
|
|
|
20
24
|
class Conditions:
|
|
25
|
+
holdings_type_map = {
|
|
26
|
+
"u": "Unknown",
|
|
27
|
+
"v": "Multi-part monograph",
|
|
28
|
+
"x": "Monograph",
|
|
29
|
+
"y": "Serial",
|
|
30
|
+
}
|
|
31
|
+
|
|
21
32
|
def __init__(
|
|
22
33
|
self,
|
|
23
34
|
folio: FolioClient,
|
|
24
35
|
mapper: RulesMapperBase,
|
|
25
36
|
object_type,
|
|
37
|
+
folio_release: FolioRelease,
|
|
26
38
|
default_call_number_type_name="",
|
|
27
39
|
):
|
|
28
40
|
self.filter_chars = r"[.,\/#!$%\^&\*;:{}=\-_`~()]"
|
|
29
41
|
self.filter_chars_dop = r"[.,\/#!$%\^&\*;:{}=\_`~()]"
|
|
42
|
+
self.folio_release: FolioRelease = folio_release
|
|
30
43
|
self.filter_last_chars = r",$"
|
|
31
44
|
self.folio = folio
|
|
32
|
-
self.default_contributor_type =
|
|
33
|
-
self.mapper = mapper
|
|
45
|
+
self.default_contributor_type: dict = {}
|
|
46
|
+
self.mapper: RulesMapperBase = mapper
|
|
34
47
|
self.ref_data_dicts = {}
|
|
35
|
-
self.setup_reference_data_for_all()
|
|
36
48
|
if object_type == "bibs":
|
|
49
|
+
self.setup_reference_data_for_all()
|
|
37
50
|
self.setup_reference_data_for_bibs()
|
|
51
|
+
elif object_type == "auth":
|
|
52
|
+
self.setup_reference_data_for_auth()
|
|
38
53
|
else:
|
|
39
|
-
self.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
self.condition_cache = {}
|
|
54
|
+
self.setup_reference_data_for_all()
|
|
55
|
+
self.setup_reference_data_for_items_and_holdings(default_call_number_type_name)
|
|
56
|
+
self.object_type = object_type
|
|
57
|
+
self.condition_cache: dict = {}
|
|
43
58
|
|
|
44
59
|
def setup_reference_data_for_bibs(self):
|
|
45
60
|
logging.info("Setting up reference data for bib transformation")
|
|
46
|
-
logging.info("%s\tcontrib_name_types", len(self.folio.contrib_name_types))
|
|
47
|
-
logging.info("%s\tcontributor_types", len(self.folio.contributor_types))
|
|
48
|
-
logging.info("%s\talt_title_types", len(self.folio.alt_title_types))
|
|
49
|
-
logging.info("%s\tidentifier_types", len(self.folio.identifier_types))
|
|
61
|
+
logging.info("%s\tcontrib_name_types", len(self.folio.contrib_name_types)) # type: ignore
|
|
62
|
+
logging.info("%s\tcontributor_types", len(self.folio.contributor_types)) # type: ignore
|
|
63
|
+
logging.info("%s\talt_title_types", len(self.folio.alt_title_types)) # type: ignore
|
|
64
|
+
logging.info("%s\tidentifier_types", len(self.folio.identifier_types)) # type: ignore
|
|
65
|
+
logging.info("%s\tsubject_types", len(self.folio.subject_types)) # type: ignore
|
|
50
66
|
# Raise for empty settings
|
|
51
67
|
if not self.folio.contributor_types:
|
|
52
68
|
raise TransformationProcessError("", "No contributor_types in FOLIO")
|
|
@@ -56,43 +72,39 @@ class Conditions:
|
|
|
56
72
|
raise TransformationProcessError("", "No identifier_types in FOLIO")
|
|
57
73
|
if not self.folio.alt_title_types:
|
|
58
74
|
raise TransformationProcessError("", "No alt_title_types in FOLIO")
|
|
75
|
+
if not self.folio.subject_types:
|
|
76
|
+
raise TransformationProcessError("", "No subject_types in FOLIO")
|
|
59
77
|
|
|
60
78
|
# Set defaults
|
|
61
79
|
logging.info("Setting defaults")
|
|
62
|
-
self.default_contributor_name_type = self.folio.contrib_name_types[0]["id"]
|
|
80
|
+
self.default_contributor_name_type: str = self.folio.contrib_name_types[0]["id"] # type: ignore
|
|
63
81
|
logging.info("Contributor name type:\t%s", self.default_contributor_name_type)
|
|
64
82
|
self.default_contributor_type = next(
|
|
65
|
-
ct for ct in self.folio.contributor_types if ct["code"] == "ctb"
|
|
83
|
+
ct for ct in self.folio.contributor_types if ct["code"] == "ctb" # type: ignore
|
|
66
84
|
)
|
|
67
85
|
logging.info("Contributor type:\t%s", self.default_contributor_type["id"])
|
|
68
86
|
|
|
69
|
-
def setup_reference_data_for_items_and_holdings(
|
|
70
|
-
self
|
|
71
|
-
):
|
|
72
|
-
logging.info(f"{len(self.folio.locations)}\tlocations")
|
|
87
|
+
def setup_reference_data_for_items_and_holdings(self, default_call_number_type_name):
|
|
88
|
+
logging.info(f"{len(self.folio.locations)}\tlocations") # type: ignore
|
|
73
89
|
self.default_call_number_type = {}
|
|
74
|
-
logging.info("%s\tholding_note_types", len(self.folio.holding_note_types))
|
|
75
|
-
logging.info("%s\tcall_number_types", len(self.folio.call_number_types))
|
|
76
|
-
self.
|
|
77
|
-
|
|
78
|
-
)
|
|
79
|
-
logging.info("%s\tholdings types", len(self.holdings_types))
|
|
90
|
+
logging.info("%s\tholding_note_types", len(self.folio.holding_note_types)) # type: ignore
|
|
91
|
+
logging.info("%s\tcall_number_types", len(self.folio.call_number_types)) # type: ignore
|
|
92
|
+
self.setup_and_validate_holdings_types()
|
|
93
|
+
self.ill_policies = self.folio.folio_get_all("/ill-policies", "illPolicies")
|
|
80
94
|
# Raise for empty settings
|
|
81
95
|
if not self.folio.holding_note_types:
|
|
82
96
|
raise TransformationProcessError("", "No holding_note_types in FOLIO")
|
|
83
97
|
if not self.folio.call_number_types:
|
|
84
98
|
raise TransformationProcessError("", "No call_number_types in FOLIO")
|
|
85
|
-
if not self.holdings_types:
|
|
86
|
-
raise TransformationProcessError("", "No holdings_types in FOLIO")
|
|
87
99
|
if not self.folio.locations:
|
|
88
100
|
raise TransformationProcessError("", "No locations in FOLIO")
|
|
89
101
|
|
|
90
102
|
# Set defaults
|
|
91
103
|
logging.info("Defaults")
|
|
92
|
-
self.default_call_number_type = next(
|
|
104
|
+
self.default_call_number_type: dict = next(
|
|
93
105
|
(
|
|
94
106
|
ct
|
|
95
|
-
for ct in self.folio.call_number_types
|
|
107
|
+
for ct in self.folio.call_number_types # type: ignore
|
|
96
108
|
if ct["name"] == default_call_number_type_name
|
|
97
109
|
),
|
|
98
110
|
None,
|
|
@@ -106,36 +118,51 @@ class Conditions:
|
|
|
106
118
|
"Please specify another UUID as the default Callnumber Type"
|
|
107
119
|
),
|
|
108
120
|
)
|
|
109
|
-
logging.info(
|
|
110
|
-
|
|
111
|
-
|
|
121
|
+
logging.info("Default Callnumber type Name:\t%s", self.default_call_number_type["name"])
|
|
122
|
+
|
|
123
|
+
def setup_and_validate_holdings_types(self):
|
|
124
|
+
self.holdings_types = self.folio.holdings_types
|
|
125
|
+
if not self.holdings_types:
|
|
126
|
+
raise TransformationProcessError("", "No holdings_types in FOLIO")
|
|
127
|
+
missing_holdings_types = [
|
|
128
|
+
ht
|
|
129
|
+
for ht in self.holdings_type_map.values()
|
|
130
|
+
if ht not in [ht_ref["name"] for ht_ref in self.holdings_types] # type: ignore
|
|
131
|
+
]
|
|
132
|
+
if any(missing_holdings_types):
|
|
133
|
+
raise TransformationProcessError(
|
|
134
|
+
"",
|
|
135
|
+
"Holdings types are missing from the tenant. Please set them up",
|
|
136
|
+
missing_holdings_types,
|
|
137
|
+
)
|
|
138
|
+
logging.info("%s\tholdings types", len(self.holdings_types)) # type: ignore
|
|
112
139
|
|
|
113
140
|
def setup_reference_data_for_all(self):
|
|
141
|
+
logging.info(f"{len(self.folio.class_types)}\tclass_types") # type: ignore
|
|
114
142
|
logging.info(
|
|
115
|
-
f"{len(self.folio.electronic_access_relationships)}\telectronic_access_relationships"
|
|
143
|
+
f"{len(self.folio.electronic_access_relationships)}\telectronic_access_relationships" # type: ignore
|
|
116
144
|
)
|
|
117
|
-
|
|
118
|
-
self.statistical_codes
|
|
119
|
-
self.folio.folio_get_all(
|
|
120
|
-
"/statistical-codes",
|
|
121
|
-
"statisticalCodes",
|
|
122
|
-
"?query=cql.allRecords=1",
|
|
123
|
-
1000,
|
|
124
|
-
)
|
|
125
|
-
)
|
|
126
|
-
logging.info(f"{len(self.statistical_codes)} \tstatistical_codes")
|
|
145
|
+
self.statistical_codes = self.folio.statistical_codes
|
|
146
|
+
logging.info(f"{len(self.statistical_codes)} \tstatistical_codes") # type: ignore
|
|
127
147
|
|
|
128
148
|
# Raise for empty settings
|
|
129
149
|
if not self.folio.class_types:
|
|
130
150
|
raise TransformationProcessError("", "No class_types in FOLIO")
|
|
131
151
|
|
|
152
|
+
def setup_reference_data_for_auth(self):
|
|
153
|
+
self.authority_note_types = list(
|
|
154
|
+
self.folio.folio_get_all(
|
|
155
|
+
"/authority-note-types", "authorityNoteTypes", self.folio.cql_all, 1000
|
|
156
|
+
)
|
|
157
|
+
)
|
|
158
|
+
logging.info(f"{len(self.authority_note_types)} \tAuthority note types")
|
|
159
|
+
logging.info(f"{len(self.folio.identifier_types)} \tidentifier types") # type: ignore
|
|
160
|
+
|
|
132
161
|
def get_condition(
|
|
133
|
-
self, name, legacy_id, value, parameter=None, marc_field: field.Field = None
|
|
162
|
+
self, name, legacy_id, value, parameter=None, marc_field: Union[None, field.Field] = None
|
|
134
163
|
):
|
|
135
164
|
try:
|
|
136
|
-
return self.condition_cache.get(name)(
|
|
137
|
-
legacy_id, value, parameter, marc_field
|
|
138
|
-
)
|
|
165
|
+
return self.condition_cache.get(name)(legacy_id, value, parameter, marc_field) # type: ignore
|
|
139
166
|
# Exception should only handle the missing condition from the cache.
|
|
140
167
|
# All other exceptions should propagate up
|
|
141
168
|
except Exception:
|
|
@@ -143,19 +170,113 @@ class Conditions:
|
|
|
143
170
|
self.condition_cache[name] = attr
|
|
144
171
|
return attr(legacy_id, value, parameter, marc_field)
|
|
145
172
|
|
|
146
|
-
def
|
|
147
|
-
|
|
148
|
-
|
|
173
|
+
def condition_trim_punctuation(self, legacy_id, value, parameter, marc_field: field.Field):
|
|
174
|
+
"""
|
|
175
|
+
Strip leading and trailing whitespace, as well as any trailing commas or periods, unless
|
|
176
|
+
the period is preceded by a single alpha character (eg. "John D."). Also preserves any
|
|
177
|
+
trailing "-" (eg. "1981-"). This condition was introduced in Poppy.
|
|
178
|
+
"""
|
|
179
|
+
pattern1 = re.compile(r"^(.*?)\s.[.]$")
|
|
180
|
+
pattern2 = re.compile(r"^(.*?)\s.,[.]$")
|
|
181
|
+
value = value.strip()
|
|
182
|
+
if pattern1.match(value) or value.endswith("-"):
|
|
183
|
+
return value
|
|
184
|
+
elif pattern2.match(value):
|
|
185
|
+
return value.rstrip(",")
|
|
186
|
+
elif value.endswith(".") or value.endswith(","):
|
|
187
|
+
return value[:-1]
|
|
188
|
+
return value
|
|
189
|
+
|
|
190
|
+
def condition_trim_period(self, legacy_id, value, parameter, marc_field: field.Field):
|
|
149
191
|
return value.strip().rstrip(".").rstrip(",")
|
|
150
192
|
|
|
151
193
|
def condition_trim(self, legacy_id, value, parameter, marc_field: field.Field):
|
|
152
194
|
return value.strip()
|
|
153
195
|
|
|
196
|
+
def condition_set_contributor_type_id_by_code_or_name(
|
|
197
|
+
self, legacy_id, value, parameter, marc_field: field.Field
|
|
198
|
+
):
|
|
199
|
+
contributor_code_subfield = parameter.get("contributorCodeSubfield", "4")
|
|
200
|
+
for subfield in marc_field.get_subfields(contributor_code_subfield):
|
|
201
|
+
normalized_subfield = re.sub(r"[^A-Za-z0-9 ]+", "", subfield.strip())
|
|
202
|
+
t = self.get_ref_data_tuple_by_code(
|
|
203
|
+
self.folio.contributor_types, "contrib_types_c", normalized_subfield
|
|
204
|
+
)
|
|
205
|
+
if not t:
|
|
206
|
+
self.mapper.migration_report.add(
|
|
207
|
+
"ContributorTypeMapping",
|
|
208
|
+
(
|
|
209
|
+
f'Mapping failed for ${contributor_code_subfield} "{subfield}" '
|
|
210
|
+
f"({normalized_subfield}) "
|
|
211
|
+
),
|
|
212
|
+
)
|
|
213
|
+
Helper.log_data_issue(
|
|
214
|
+
legacy_id,
|
|
215
|
+
f"Mapping failed for ${contributor_code_subfield}",
|
|
216
|
+
f'{subfield}" ({normalized_subfield}) ',
|
|
217
|
+
)
|
|
218
|
+
else:
|
|
219
|
+
self.mapper.migration_report.add(
|
|
220
|
+
"ContributorTypeMapping",
|
|
221
|
+
(
|
|
222
|
+
i18n.t(
|
|
223
|
+
'Contributor type code "%{code}" found for $%{code_subfield}',
|
|
224
|
+
code=t[1],
|
|
225
|
+
code_subfield=contributor_code_subfield,
|
|
226
|
+
)
|
|
227
|
+
+ f' "{subfield}" ({normalized_subfield}))'
|
|
228
|
+
),
|
|
229
|
+
)
|
|
230
|
+
return t[0]
|
|
231
|
+
fallback_name_field = "j" if marc_field.tag in ["111", "711"] else "e"
|
|
232
|
+
contributor_name_subfield = parameter.get("contributorNameSubfield", fallback_name_field)
|
|
233
|
+
for subfield in marc_field.get_subfields(contributor_name_subfield):
|
|
234
|
+
normalized_subfield = re.sub(r"[^A-Za-z0-9 ]+", "", subfield.strip())
|
|
235
|
+
t = self.get_ref_data_tuple_by_name(
|
|
236
|
+
self.folio.contributor_types, "contrib_types_n", normalized_subfield
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
if not t:
|
|
240
|
+
self.mapper.migration_report.add(
|
|
241
|
+
"ContributorTypeMapping",
|
|
242
|
+
(
|
|
243
|
+
f"Mapping failed for {marc_field.tag} ${contributor_name_subfield} "
|
|
244
|
+
f"{subfield} (Normalized: {normalized_subfield}) "
|
|
245
|
+
),
|
|
246
|
+
)
|
|
247
|
+
Helper.log_data_issue(
|
|
248
|
+
legacy_id,
|
|
249
|
+
f"Mapping failed for {marc_field.tag} ${contributor_name_subfield}",
|
|
250
|
+
f'{subfield}" ({normalized_subfield}) ',
|
|
251
|
+
)
|
|
252
|
+
else:
|
|
253
|
+
self.mapper.migration_report.add(
|
|
254
|
+
"ContributorTypeMapping",
|
|
255
|
+
(
|
|
256
|
+
f"Contributor type name {t[1]} found for {marc_field.tag} "
|
|
257
|
+
f"${contributor_name_subfield} {normalized_subfield} ({subfield}) "
|
|
258
|
+
),
|
|
259
|
+
)
|
|
260
|
+
return t[0]
|
|
261
|
+
return ""
|
|
262
|
+
|
|
263
|
+
def condition_set_holdings_type_id(self, legacy_id, value, parameter, marc_field: field.Field):
|
|
264
|
+
self.mapper.migration_report.add("HoldingsTypeMapping", i18n.t("Condition in rules hit"))
|
|
265
|
+
return ""
|
|
266
|
+
|
|
154
267
|
def condition_concat_subfields_by_name(
|
|
155
268
|
self, legacy_id, value, parameter, marc_field: field.Field
|
|
156
269
|
):
|
|
157
270
|
subfields_to_concat = parameter.get("subfieldsToConcat", [])
|
|
158
|
-
|
|
271
|
+
subfields_to_stop_concat = parameter.get("subfieldsToStopConcat", [])
|
|
272
|
+
concat_subfields = []
|
|
273
|
+
subfields = marc_field.subfields
|
|
274
|
+
for t in subfields:
|
|
275
|
+
if t[0] in subfields_to_stop_concat:
|
|
276
|
+
break
|
|
277
|
+
elif t[0] in subfields_to_concat:
|
|
278
|
+
concat_subfields.append(t[1])
|
|
279
|
+
concat_string = " ".join(concat_subfields)
|
|
159
280
|
return f"{value} {concat_string}"
|
|
160
281
|
|
|
161
282
|
def condition_get_value_if_subfield_is_empty(
|
|
@@ -164,14 +285,14 @@ class Conditions:
|
|
|
164
285
|
if value.strip():
|
|
165
286
|
return value.strip()
|
|
166
287
|
self.mapper.migration_report.add(
|
|
167
|
-
|
|
168
|
-
|
|
288
|
+
"AddedValueFromParameter",
|
|
289
|
+
i18n.t(
|
|
290
|
+
"Tag: %{tag}. Added value: %{value}", tag=marc_field.tag, value=parameter["value"]
|
|
291
|
+
),
|
|
169
292
|
)
|
|
170
293
|
return parameter["value"]
|
|
171
294
|
|
|
172
|
-
def condition_remove_ending_punc(
|
|
173
|
-
self, legacy_id, value, parameter, marc_field: field.Field
|
|
174
|
-
):
|
|
295
|
+
def condition_remove_ending_punc(self, legacy_id, value, parameter, marc_field: field.Field):
|
|
175
296
|
v = value
|
|
176
297
|
chars = ".;:,/+=- "
|
|
177
298
|
while any(v) > 0 and v[-1] in chars:
|
|
@@ -188,14 +309,14 @@ class Conditions:
|
|
|
188
309
|
self.folio.instance_formats, "instance_formats_code", value
|
|
189
310
|
)
|
|
190
311
|
self.mapper.migration_report.add(
|
|
191
|
-
|
|
192
|
-
|
|
312
|
+
"InstanceFormat",
|
|
313
|
+
i18n.t("Successful match") + f' - "{value}"->{t[1]}',
|
|
193
314
|
)
|
|
194
315
|
return t[0]
|
|
195
316
|
except Exception:
|
|
196
317
|
self.mapper.migration_report.add(
|
|
197
|
-
|
|
198
|
-
|
|
318
|
+
"InstanceFormat",
|
|
319
|
+
i18n.t('Code from 338$b NOT found in FOLIO: "%{value}"', value=value),
|
|
199
320
|
)
|
|
200
321
|
|
|
201
322
|
return ""
|
|
@@ -212,25 +333,17 @@ class Conditions:
|
|
|
212
333
|
num_take = int(ind2)
|
|
213
334
|
return re.sub(reg_str, "", value[num_take:])
|
|
214
335
|
|
|
215
|
-
def condition_capitalize(
|
|
216
|
-
self, legacy_id, value, parameter, marc_field: field.Field
|
|
217
|
-
):
|
|
336
|
+
def condition_capitalize(self, legacy_id, value, parameter, marc_field: field.Field):
|
|
218
337
|
return value.capitalize()
|
|
219
338
|
|
|
220
|
-
def condition_clean_isbn(
|
|
221
|
-
self, legacy_id, value, parameter, marc_field: field.Field
|
|
222
|
-
):
|
|
339
|
+
def condition_clean_isbn(self, legacy_id, value, parameter, marc_field: field.Field):
|
|
223
340
|
return value
|
|
224
341
|
|
|
225
|
-
def condition_set_issuance_mode_id(
|
|
226
|
-
self, legacy_id, value, parameter, marc_field: field.Field
|
|
227
|
-
):
|
|
342
|
+
def condition_set_issuance_mode_id(self, legacy_id, value, parameter, marc_field: field.Field):
|
|
228
343
|
# mode of issuance is handled elsewhere in the mapping.
|
|
229
344
|
return ""
|
|
230
345
|
|
|
231
|
-
def condition_set_publisher_role(
|
|
232
|
-
self, legacy_id, value, parameter, marc_field: field.Field
|
|
233
|
-
):
|
|
346
|
+
def condition_set_publisher_role(self, legacy_id, value, parameter, marc_field: field.Field):
|
|
234
347
|
roles = {
|
|
235
348
|
"0": "Production",
|
|
236
349
|
"1": "Publication",
|
|
@@ -240,7 +353,7 @@ class Conditions:
|
|
|
240
353
|
}
|
|
241
354
|
role = roles.get(marc_field.indicator2, "")
|
|
242
355
|
self.mapper.migration_report.add(
|
|
243
|
-
|
|
356
|
+
"MappedPublisherRoleFromIndicator2",
|
|
244
357
|
f"{marc_field.tag} ind2 {marc_field.indicator2}->{role}",
|
|
245
358
|
)
|
|
246
359
|
return role
|
|
@@ -262,33 +375,50 @@ class Conditions:
|
|
|
262
375
|
parameter["names"][0],
|
|
263
376
|
)
|
|
264
377
|
self.mapper.migration_report.add(
|
|
265
|
-
|
|
378
|
+
"MappedIdentifierTypes", f"{marc_field.tag} -> {t[1]}"
|
|
266
379
|
)
|
|
267
380
|
return t[0]
|
|
268
|
-
identifier_type = next(
|
|
269
|
-
(
|
|
381
|
+
identifier_type: dict = next(
|
|
382
|
+
(
|
|
383
|
+
f
|
|
384
|
+
for f in self.folio.identifier_types # type: ignore
|
|
385
|
+
if (
|
|
386
|
+
f["name"] in parameter.get("names", "non existant")
|
|
387
|
+
or f["name"] in parameter.get("name", "non existant")
|
|
388
|
+
)
|
|
389
|
+
),
|
|
270
390
|
None,
|
|
271
391
|
)
|
|
272
|
-
self.mapper.migration_report.add(
|
|
273
|
-
Blurbs.MappedIdentifierTypes, identifier_type["name"]
|
|
274
|
-
)
|
|
392
|
+
self.mapper.migration_report.add("MappedIdentifierTypes", identifier_type["name"])
|
|
275
393
|
my_id = identifier_type["id"]
|
|
276
394
|
if not my_id:
|
|
277
395
|
raise TransformationFieldMappingError(
|
|
278
396
|
legacy_id,
|
|
279
|
-
|
|
397
|
+
i18n.t("no matching identifier_types in %{names}", names=parameter["names"]),
|
|
280
398
|
marc_field,
|
|
281
399
|
)
|
|
282
400
|
return my_id
|
|
283
401
|
|
|
284
402
|
def condition_set_holding_note_type_id_by_name(
|
|
285
403
|
self, legacy_id, value, parameter, marc_field: field.Field
|
|
404
|
+
):
|
|
405
|
+
self.mapper.migration_report.add(
|
|
406
|
+
"Exceptions",
|
|
407
|
+
(
|
|
408
|
+
"Condition set_holding_note_type_id_by_name is deprecated. "
|
|
409
|
+
"Use set_holdings_note_type_id instead"
|
|
410
|
+
),
|
|
411
|
+
)
|
|
412
|
+
return self.condition_set_holdings_note_type_id(legacy_id, value, parameter, marc_field)
|
|
413
|
+
|
|
414
|
+
def condition_set_holdings_note_type_id(
|
|
415
|
+
self, legacy_id, value, parameter, marc_field: field.Field
|
|
286
416
|
):
|
|
287
417
|
try:
|
|
288
418
|
t = self.get_ref_data_tuple_by_name(
|
|
289
419
|
self.folio.holding_note_types, "holding_note_types", parameter["name"]
|
|
290
420
|
)
|
|
291
|
-
self.mapper.migration_report.add(
|
|
421
|
+
self.mapper.migration_report.add("MappedNoteTypes", t[1])
|
|
292
422
|
return t[0]
|
|
293
423
|
except Exception as ee:
|
|
294
424
|
logging.error(ee)
|
|
@@ -297,7 +427,25 @@ class Conditions:
|
|
|
297
427
|
f'Holdings note type mapping error.\tParameter: {parameter.get("name", "")}\t'
|
|
298
428
|
f"MARC Field: {marc_field}. Is mapping rules and ref data aligned?",
|
|
299
429
|
parameter.get("name", ""),
|
|
430
|
+
) from ee
|
|
431
|
+
|
|
432
|
+
def condition_set_authority_note_type_id(
|
|
433
|
+
self, legacy_id, _, parameter, marc_field: field.Field
|
|
434
|
+
):
|
|
435
|
+
try:
|
|
436
|
+
t = self.get_ref_data_tuple_by_name(
|
|
437
|
+
self.authority_note_types, "authority_note_types", parameter["name"]
|
|
300
438
|
)
|
|
439
|
+
self.mapper.migration_report.add("MappedNoteTypes", t[1])
|
|
440
|
+
return t[0]
|
|
441
|
+
except Exception as ee:
|
|
442
|
+
logging.error(ee)
|
|
443
|
+
raise TransformationProcessError(
|
|
444
|
+
legacy_id,
|
|
445
|
+
f'Authority note type mapping error.\tParameter: {parameter.get("name", "")}\t'
|
|
446
|
+
f"MARC Field: {marc_field}. Is mapping rules and ref data aligned?",
|
|
447
|
+
parameter.get("name", ""),
|
|
448
|
+
) from ee
|
|
301
449
|
|
|
302
450
|
def condition_set_classification_type_id(
|
|
303
451
|
self, legacy_id, value, parameter, marc_field: field.Field
|
|
@@ -306,7 +454,7 @@ class Conditions:
|
|
|
306
454
|
t = self.get_ref_data_tuple_by_name(
|
|
307
455
|
self.folio.class_types, "class_types", parameter["name"]
|
|
308
456
|
)
|
|
309
|
-
self.mapper.migration_report.add(
|
|
457
|
+
self.mapper.migration_report.add("MappedClassificationTypes", t[1])
|
|
310
458
|
return t[0]
|
|
311
459
|
except Exception:
|
|
312
460
|
raise TransformationRecordFailedError(
|
|
@@ -316,40 +464,9 @@ class Conditions:
|
|
|
316
464
|
parameter.get("name", ""),
|
|
317
465
|
)
|
|
318
466
|
|
|
319
|
-
def condition_char_select(
|
|
320
|
-
self, legacy_id, value, parameter, marc_field: field.Field
|
|
321
|
-
):
|
|
467
|
+
def condition_char_select(self, legacy_id, value, parameter, marc_field: field.Field):
|
|
322
468
|
return value[parameter["from"] : parameter["to"]]
|
|
323
469
|
|
|
324
|
-
def condition_set_receipt_status(
|
|
325
|
-
self, legacy_id, value, parameter, marc_field: field.Field
|
|
326
|
-
):
|
|
327
|
-
if len(value) < 7:
|
|
328
|
-
self.mapper.migration_report.add(
|
|
329
|
-
Blurbs.ReceiptStatusMapping, f"008 is too short: {value}"
|
|
330
|
-
)
|
|
331
|
-
return ""
|
|
332
|
-
try:
|
|
333
|
-
status_map = {
|
|
334
|
-
"0": "Unknown",
|
|
335
|
-
"1": "Other receipt or acquisition status",
|
|
336
|
-
"2": "Received and complete or ceased",
|
|
337
|
-
"3": "On order",
|
|
338
|
-
"4": "Currently received",
|
|
339
|
-
"5": "Not currently received",
|
|
340
|
-
"6": "External access",
|
|
341
|
-
}
|
|
342
|
-
mapped_value = status_map[value[6]]
|
|
343
|
-
self.mapper.migration_report.add(
|
|
344
|
-
Blurbs.ReceiptStatusMapping, f"{value[6]} mapped to {mapped_value}"
|
|
345
|
-
)
|
|
346
|
-
|
|
347
|
-
return
|
|
348
|
-
except Exception:
|
|
349
|
-
self.mapper.migration_report.add(
|
|
350
|
-
Blurbs.ReceiptStatusMapping, f"{value[6]} not found in map."
|
|
351
|
-
)
|
|
352
|
-
return "Unknown"
|
|
353
470
|
|
|
354
471
|
def condition_set_identifier_type_id_by_name(
|
|
355
472
|
self, legacy_id, value, parameter, marc_field: field.Field
|
|
@@ -359,16 +476,17 @@ class Conditions:
|
|
|
359
476
|
self.folio.identifier_types, "identifier_types", parameter["name"]
|
|
360
477
|
)
|
|
361
478
|
self.mapper.migration_report.add(
|
|
362
|
-
|
|
479
|
+
"MappedIdentifierTypes", f"{marc_field.tag} -> {t[1]}"
|
|
363
480
|
)
|
|
364
481
|
return t[0]
|
|
365
|
-
except Exception:
|
|
366
|
-
|
|
482
|
+
except Exception as ee:
|
|
483
|
+
logging.exception("Identifier type")
|
|
484
|
+
raise TransformationProcessError(
|
|
367
485
|
legacy_id,
|
|
368
|
-
f'Unmapped identifier
|
|
369
|
-
f"MARC Field: {marc_field}. Is mapping rules and ref data aligned?",
|
|
486
|
+
f'Unmapped identifier type : "{parameter["name"]}"\tMARC Field: {marc_field}'
|
|
487
|
+
f"MARC Field: {marc_field}. Is mapping rules and ref data aligned? ",
|
|
370
488
|
{parameter["name"]},
|
|
371
|
-
)
|
|
489
|
+
) from ee
|
|
372
490
|
|
|
373
491
|
def condition_set_contributor_name_type_id(
|
|
374
492
|
self, legacy_id, value, parameter, marc_field: field.Field
|
|
@@ -378,31 +496,25 @@ class Conditions:
|
|
|
378
496
|
self.folio.contrib_name_types, "contrib_name_types", parameter["name"]
|
|
379
497
|
)
|
|
380
498
|
self.mapper.migration_report.add(
|
|
381
|
-
|
|
499
|
+
"MappedContributorNameTypes", f"{marc_field.tag} -> {t[1]}"
|
|
382
500
|
)
|
|
383
501
|
return t[0]
|
|
384
502
|
except Exception:
|
|
385
|
-
self.mapper.migration_report.add(
|
|
386
|
-
Blurbs.UnmappedContributorNameTypes, parameter["name"]
|
|
387
|
-
)
|
|
503
|
+
self.mapper.migration_report.add("UnmappedContributorNameTypes", parameter["name"])
|
|
388
504
|
return self.default_contributor_name_type
|
|
389
505
|
|
|
390
|
-
def condition_set_note_type_id(
|
|
391
|
-
self, legacy_id, value, parameter, marc_field: field.Field
|
|
392
|
-
):
|
|
506
|
+
def condition_set_note_type_id(self, legacy_id, value, parameter, marc_field: field.Field):
|
|
393
507
|
try:
|
|
394
508
|
t = self.get_ref_data_tuple_by_name(
|
|
395
509
|
self.folio.instance_note_types, "instance_not_types", parameter["name"]
|
|
396
510
|
)
|
|
397
511
|
self.mapper.migration_report.add(
|
|
398
|
-
|
|
512
|
+
"MappedNoteTypes",
|
|
399
513
|
f"{marc_field.tag} ({parameter.get('name', '')}) -> {t[1]}",
|
|
400
514
|
)
|
|
401
515
|
return t[0]
|
|
402
516
|
except Exception:
|
|
403
|
-
raise ValueError(
|
|
404
|
-
f"Instance note type not found for {marc_field} {parameter}"
|
|
405
|
-
)
|
|
517
|
+
raise ValueError(f"Instance note type not found for {marc_field} {parameter}")
|
|
406
518
|
|
|
407
519
|
def condition_set_contributor_type_id(
|
|
408
520
|
self, legacy_id, value, parameter, marc_field: field.Field
|
|
@@ -414,8 +526,13 @@ class Conditions:
|
|
|
414
526
|
)
|
|
415
527
|
if not t:
|
|
416
528
|
self.mapper.migration_report.add(
|
|
417
|
-
|
|
418
|
-
|
|
529
|
+
"ContributorTypeMapping",
|
|
530
|
+
i18n.t(
|
|
531
|
+
'Mapping failed for %{tag} "%{subfield}" (%{normalized_subfield})',
|
|
532
|
+
tag="$4",
|
|
533
|
+
subfield=subfield,
|
|
534
|
+
normalized_subfield=normalized_subfield,
|
|
535
|
+
),
|
|
419
536
|
)
|
|
420
537
|
Helper.log_data_issue(
|
|
421
538
|
legacy_id,
|
|
@@ -424,8 +541,14 @@ class Conditions:
|
|
|
424
541
|
)
|
|
425
542
|
else:
|
|
426
543
|
self.mapper.migration_report.add(
|
|
427
|
-
|
|
428
|
-
|
|
544
|
+
"ContributorTypeMapping",
|
|
545
|
+
i18n.t(
|
|
546
|
+
'Contributor type code "%{code}" found for $%{code_subfield}',
|
|
547
|
+
code=t[1],
|
|
548
|
+
code_subfield="4",
|
|
549
|
+
normalized_subfield=normalized_subfield,
|
|
550
|
+
)
|
|
551
|
+
+ f' "%{subfield}" (%{normalized_subfield}))',
|
|
429
552
|
)
|
|
430
553
|
return t[0]
|
|
431
554
|
subfield_code = "j" if marc_field.tag in ["111", "711"] else "e"
|
|
@@ -437,50 +560,49 @@ class Conditions:
|
|
|
437
560
|
|
|
438
561
|
if not t:
|
|
439
562
|
self.mapper.migration_report.add(
|
|
440
|
-
|
|
441
|
-
|
|
563
|
+
"ContributorTypeMapping",
|
|
564
|
+
i18n.t(
|
|
565
|
+
'Mapping failed for %{tag} "%{subfield}" (Normalized: %{normalized_subfield})',
|
|
566
|
+
tag=f"{marc_field.tag} $e",
|
|
567
|
+
subfield=subfield,
|
|
568
|
+
normalized_subfield=normalized_subfield,
|
|
569
|
+
),
|
|
442
570
|
)
|
|
443
571
|
Helper.log_data_issue(
|
|
444
572
|
legacy_id,
|
|
445
|
-
"Mapping failed for $e",
|
|
573
|
+
f"Mapping failed for {marc_field.tag} $e",
|
|
446
574
|
f'{subfield}" ({normalized_subfield}) ',
|
|
447
575
|
)
|
|
448
576
|
else:
|
|
449
577
|
self.mapper.migration_report.add(
|
|
450
|
-
|
|
451
|
-
|
|
578
|
+
"ContributorTypeMapping",
|
|
579
|
+
i18n.t(
|
|
580
|
+
"Contributor type name %{name} found for %{tag}",
|
|
581
|
+
name=t[1],
|
|
582
|
+
tag=marc_field.tag,
|
|
583
|
+
)
|
|
584
|
+
+ f" $e {normalized_subfield} ({subfield}) ",
|
|
452
585
|
)
|
|
453
586
|
return t[0]
|
|
454
587
|
return self.default_contributor_type["id"]
|
|
455
588
|
|
|
456
|
-
def
|
|
457
|
-
self,
|
|
458
|
-
):
|
|
459
|
-
try:
|
|
460
|
-
if value:
|
|
461
|
-
if value.strip() not in self.mapper.instance_id_map:
|
|
462
|
-
raise ValueError()
|
|
463
|
-
return self.mapper.instance_id_map[value.strip()]["folio_id"]
|
|
464
|
-
Helper.log_data_issue(
|
|
465
|
-
"", "No instance id provided", marc_field.format_field()
|
|
466
|
-
)
|
|
467
|
-
return ""
|
|
468
|
-
except Exception:
|
|
469
|
-
raise TransformationRecordFailedError(
|
|
470
|
-
legacy_id,
|
|
471
|
-
"Old instance id not in map",
|
|
472
|
-
f"{marc_field.format_field()}",
|
|
473
|
-
)
|
|
589
|
+
def condition_set_url_relationship(self, legacy_id, value, parameter, marc_field: field.Field):
|
|
590
|
+
return self._extracted_from_condition_set_electronic_access_relations_id_2("8", marc_field)
|
|
474
591
|
|
|
475
|
-
def
|
|
592
|
+
def condition_set_call_number_type_by_indicator(
|
|
476
593
|
self, legacy_id, value, parameter, marc_field: field.Field
|
|
477
594
|
):
|
|
478
|
-
|
|
479
|
-
"
|
|
595
|
+
self.mapper.migration_report.add(
|
|
596
|
+
"Exceptions",
|
|
597
|
+
(
|
|
598
|
+
"Condition set_call_number_type_by_indicator is deprecated. "
|
|
599
|
+
"Change to set_call_number_type_id"
|
|
600
|
+
),
|
|
480
601
|
)
|
|
602
|
+
return self.condition_set_call_number_type_id(legacy_id, value, parameter, marc_field)
|
|
481
603
|
|
|
482
|
-
def
|
|
483
|
-
self, legacy_id, value, parameter, marc_field:
|
|
604
|
+
def condition_set_call_number_type_id(
|
|
605
|
+
self, legacy_id, value, parameter, marc_field: field.Field
|
|
484
606
|
):
|
|
485
607
|
first_level_map = {
|
|
486
608
|
"0": "Library of Congress classification",
|
|
@@ -497,8 +619,8 @@ class Conditions:
|
|
|
497
619
|
# CallNumber type specified in $2. This needs further mapping
|
|
498
620
|
if marc_field.indicator1 == "7" and "2" in marc_field:
|
|
499
621
|
self.mapper.migration_report.add(
|
|
500
|
-
|
|
501
|
-
|
|
622
|
+
"CallNumberTypeMapping",
|
|
623
|
+
i18n.t("Unhandled call number type in $2 (ind1 == 7)" + str(marc_field["2"])),
|
|
502
624
|
)
|
|
503
625
|
return self.default_call_number_type["id"]
|
|
504
626
|
|
|
@@ -506,10 +628,13 @@ class Conditions:
|
|
|
506
628
|
call_number_type_name_temp = first_level_map.get(marc_field.indicator1, "")
|
|
507
629
|
if not call_number_type_name_temp:
|
|
508
630
|
self.mapper.migration_report.add(
|
|
509
|
-
|
|
631
|
+
"CallNumberTypeMapping",
|
|
510
632
|
(
|
|
511
|
-
|
|
512
|
-
|
|
633
|
+
i18n.t(
|
|
634
|
+
'Unhandled call number type in ind1: "%{ind1}".\n Returning default Callnumber type: %{type}',
|
|
635
|
+
ind1=marc_field.indicator1,
|
|
636
|
+
type=self.default_call_number_type["name"],
|
|
637
|
+
)
|
|
513
638
|
),
|
|
514
639
|
)
|
|
515
640
|
return self.default_call_number_type["id"]
|
|
@@ -518,13 +643,13 @@ class Conditions:
|
|
|
518
643
|
)
|
|
519
644
|
if t:
|
|
520
645
|
self.mapper.migration_report.add(
|
|
521
|
-
|
|
522
|
-
|
|
646
|
+
"CallNumberTypeMapping",
|
|
647
|
+
i18n.t("Mapped from Indicator 1") + f" {marc_field.indicator1} -> {t[1]}",
|
|
523
648
|
)
|
|
524
649
|
return t[0]
|
|
525
650
|
|
|
526
651
|
self.mapper.migration_report.add(
|
|
527
|
-
|
|
652
|
+
"CallNumberTypeMapping",
|
|
528
653
|
(
|
|
529
654
|
"Mapping failed. Setting default CallNumber type: "
|
|
530
655
|
f'{self.default_call_number_type["name"]}'
|
|
@@ -538,19 +663,21 @@ class Conditions:
|
|
|
538
663
|
):
|
|
539
664
|
for subfield in marc_field.get_subfields("4", "e"):
|
|
540
665
|
normalized_subfield = re.sub(r"[^A-Za-z0-9 ]+", "", subfield.strip())
|
|
541
|
-
for cont_type in self.folio.contributor_types:
|
|
666
|
+
for cont_type in self.folio.contributor_types: # type: ignore
|
|
542
667
|
if normalized_subfield in [cont_type["code"], cont_type["name"]]:
|
|
543
668
|
return cont_type["name"]
|
|
544
|
-
|
|
669
|
+
try:
|
|
670
|
+
return value
|
|
671
|
+
except IndexError:
|
|
672
|
+
logging.debug("Exception occurred: %s", traceback.format_exc())
|
|
673
|
+
return ""
|
|
545
674
|
|
|
546
|
-
def condition_set_alternative_title_type_id(
|
|
547
|
-
self, legacy_id, value, parameter, marc_field
|
|
548
|
-
):
|
|
675
|
+
def condition_set_alternative_title_type_id(self, legacy_id, value, parameter, marc_field):
|
|
549
676
|
try:
|
|
550
677
|
t = self.get_ref_data_tuple_by_name(
|
|
551
678
|
self.folio.alt_title_types, "alt_title_types", parameter["name"]
|
|
552
679
|
)
|
|
553
|
-
self.mapper.migration_report.add(
|
|
680
|
+
self.mapper.migration_report.add("MappedAlternativeTitleTypes", t[1])
|
|
554
681
|
return t[0]
|
|
555
682
|
except Exception:
|
|
556
683
|
raise TransformationProcessError(
|
|
@@ -558,85 +685,70 @@ class Conditions:
|
|
|
558
685
|
f"Alternative title type not found for {parameter['name']} {marc_field}",
|
|
559
686
|
)
|
|
560
687
|
|
|
561
|
-
def setup_location_code_from_second_column(self):
|
|
562
|
-
try:
|
|
563
|
-
other_columns = [
|
|
564
|
-
f for f in self.mapper.location_map[0].keys() if f not in ["folio_code"]
|
|
565
|
-
]
|
|
566
|
-
if len(other_columns) > 1:
|
|
567
|
-
raise TransformationProcessError(
|
|
568
|
-
"",
|
|
569
|
-
"Other location map columns could not be used since more than one",
|
|
570
|
-
other_columns,
|
|
571
|
-
)
|
|
572
|
-
elif len(other_columns) == 1:
|
|
573
|
-
logging.info(f"{other_columns[0]} will be used for location mapping")
|
|
574
|
-
return {
|
|
575
|
-
lm[other_columns[0]]: lm["folio_code"]
|
|
576
|
-
for lm in self.mapper.location_map
|
|
577
|
-
}
|
|
578
|
-
except Exception as ee:
|
|
579
|
-
raise TransformationProcessError("", f"{ee}", self.mapper.location_map)
|
|
580
|
-
|
|
581
688
|
def condition_set_location_id_by_code(
|
|
582
689
|
self, legacy_id, value, parameter, marc_field: field.Field
|
|
583
690
|
):
|
|
584
691
|
self.mapper.migration_report.add(
|
|
585
|
-
|
|
692
|
+
"Exceptions",
|
|
586
693
|
(
|
|
587
694
|
"set_location_id_by_code condition used in rules. "
|
|
588
695
|
"Deprecated condition. Switch to set_permanent_location_id"
|
|
589
696
|
),
|
|
590
697
|
)
|
|
591
|
-
return self.condition_set_permanent_location_id(
|
|
592
|
-
legacy_id, value, parameter, marc_field
|
|
593
|
-
)
|
|
698
|
+
return self.condition_set_permanent_location_id(legacy_id, value, parameter, marc_field)
|
|
594
699
|
|
|
595
700
|
def condition_set_permanent_location_id(
|
|
596
701
|
self, legacy_id, value, parameter, marc_field: field.Field
|
|
597
702
|
):
|
|
598
|
-
# Setup mapping if not already set up
|
|
599
703
|
if "legacy_locations" not in self.ref_data_dicts:
|
|
600
704
|
try:
|
|
601
|
-
d = {
|
|
602
|
-
lm["legacy_code"]: lm["folio_code"]
|
|
603
|
-
for lm in self.mapper.location_map
|
|
604
|
-
}
|
|
705
|
+
d = {lm["legacy_code"]: lm["folio_code"] for lm in self.mapper.location_map} # type: ignore
|
|
605
706
|
self.ref_data_dicts["legacy_locations"] = d
|
|
707
|
+
for folio_code in d.values():
|
|
708
|
+
t = self.get_ref_data_tuple_by_code(
|
|
709
|
+
self.folio.locations, "locations", folio_code
|
|
710
|
+
)
|
|
711
|
+
if not t:
|
|
712
|
+
raise TransformationProcessError(
|
|
713
|
+
"", "No FOLIO location found for code", folio_code
|
|
714
|
+
)
|
|
715
|
+
if "*" not in d:
|
|
716
|
+
raise TransformationProcessError(
|
|
717
|
+
"",
|
|
718
|
+
(
|
|
719
|
+
"Fallback location mapping missing. Add a row with a * in the "
|
|
720
|
+
"legacy_code column and a location code to map unmapped locations to"
|
|
721
|
+
),
|
|
722
|
+
"",
|
|
723
|
+
)
|
|
606
724
|
except KeyError as ke:
|
|
607
725
|
if "folio_code" in str(ke):
|
|
608
726
|
raise TransformationProcessError(
|
|
609
727
|
legacy_id, "Your location map lacks the column folio_code"
|
|
610
|
-
)
|
|
728
|
+
) from ke
|
|
611
729
|
if "legacy_code" in str(ke):
|
|
612
|
-
|
|
613
|
-
"
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
self.ref_data_dicts[
|
|
617
|
-
"legacy_locations"
|
|
618
|
-
] = self.setup_location_code_from_second_column()
|
|
730
|
+
raise TransformationProcessError(
|
|
731
|
+
legacy_id, "Your location map lacks the column legacy_code"
|
|
732
|
+
) from ke
|
|
733
|
+
|
|
619
734
|
# Get the right code from the location map
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
735
|
+
mapped_code = self.ref_data_dicts["legacy_locations"].get(value.strip(), "").strip()
|
|
736
|
+
if not mapped_code:
|
|
737
|
+
mapped_code = self.ref_data_dicts["legacy_locations"].get("*", "").strip()
|
|
738
|
+
if mapped_code:
|
|
739
|
+
self.mapper.migration_report.add(
|
|
740
|
+
"LocationMapping", i18n.t("Fallback mapping") + f": {value}->{mapped_code}"
|
|
741
|
+
)
|
|
626
742
|
# Get the FOLIO UUID for the code and return it
|
|
627
|
-
t = self.get_ref_data_tuple_by_code(
|
|
628
|
-
self.folio.locations, "locations", mapped_code
|
|
629
|
-
)
|
|
743
|
+
t = self.get_ref_data_tuple_by_code(self.folio.locations, "locations", mapped_code)
|
|
630
744
|
if not t:
|
|
631
745
|
self.mapper.migration_report.add(
|
|
632
|
-
|
|
746
|
+
"LocationMapping", i18n.t("Unmapped code") + f": '{value}'"
|
|
633
747
|
)
|
|
634
748
|
raise TransformationRecordFailedError(
|
|
635
749
|
legacy_id, "Could not map location from legacy code", value
|
|
636
750
|
)
|
|
637
|
-
self.mapper.migration_report.add(
|
|
638
|
-
Blurbs.LocationMapping, f"'{value}' ({mapped_code}) -> {t[1]}"
|
|
639
|
-
)
|
|
751
|
+
self.mapper.migration_report.add("LocationMapping", f"'{value}' ({mapped_code}) -> {t[1]}")
|
|
640
752
|
return t[0]
|
|
641
753
|
|
|
642
754
|
def get_ref_data_tuple_by_code(self, ref_data, ref_name, code):
|
|
@@ -657,17 +769,13 @@ class Conditions:
|
|
|
657
769
|
self.ref_data_dicts[dict_key] = d
|
|
658
770
|
return self.ref_data_dicts.get(dict_key, {}).get(key_value.lower(), ())
|
|
659
771
|
|
|
660
|
-
def condition_remove_substring(
|
|
661
|
-
self, legacy_id, value, parameter, marc_field: field.Field
|
|
662
|
-
):
|
|
772
|
+
def condition_remove_substring(self, legacy_id, value, parameter, marc_field: field.Field):
|
|
663
773
|
return value.replace(parameter["substring"], "")
|
|
664
774
|
|
|
665
|
-
def condition_set_instance_type_id(
|
|
666
|
-
self, legacy_id, value, parameter, marc_field: field.Field
|
|
667
|
-
):
|
|
775
|
+
def condition_set_instance_type_id(self, legacy_id, value, parameter, marc_field: field.Field):
|
|
668
776
|
if marc_field.tag not in ["008", "336"]:
|
|
669
777
|
self.mapper.migration_report.add(
|
|
670
|
-
|
|
778
|
+
"InstanceTypeMapping",
|
|
671
779
|
(
|
|
672
780
|
f"Unhandled MARC tag {marc_field.tag}. Instance Type ID is only mapped "
|
|
673
781
|
"from 336 "
|
|
@@ -678,14 +786,31 @@ class Conditions:
|
|
|
678
786
|
def condition_set_electronic_access_relations_id(
|
|
679
787
|
self, legacy_id, value, parameter, marc_field: field.Field
|
|
680
788
|
):
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
)
|
|
789
|
+
"""
|
|
790
|
+
This method handles the mapping of electronic access relationship IDs.
|
|
791
|
+
If the record type being mapped is FOLIO holdings, it provides an (optional) alternative
|
|
792
|
+
mapping based on a provided name parameter, bypassing the FOLIO MARC-to-Holdings mapping
|
|
793
|
+
engine behavior. This requires use of a supplemental mapping rules file in the
|
|
794
|
+
HoldingsMarcTransformer task definition containing the name parameter.
|
|
795
|
+
"""
|
|
796
|
+
if self.object_type == "holdings" and "name" in parameter:
|
|
797
|
+
try:
|
|
798
|
+
t = self.get_ref_data_tuple_by_name(
|
|
799
|
+
self.folio.electronic_access_relationships,
|
|
800
|
+
"electronic_access_relationships",
|
|
801
|
+
parameter["name"],
|
|
802
|
+
)
|
|
803
|
+
self.mapper.migration_report.add("MappedElectronicRelationshipTypes", t[1])
|
|
804
|
+
return t[0]
|
|
805
|
+
except Exception:
|
|
806
|
+
raise TransformationProcessError(
|
|
807
|
+
legacy_id,
|
|
808
|
+
f"Electronic access relationship not found for {parameter['name']} {marc_field}",
|
|
809
|
+
)
|
|
810
|
+
return self._extracted_from_condition_set_electronic_access_relations_id_2("3", marc_field)
|
|
684
811
|
|
|
685
812
|
# TODO Rename this here and in `condition_set_url_relationship` and `condition_set_electronic_access_relations_id`
|
|
686
|
-
def _extracted_from_condition_set_electronic_access_relations_id_2(
|
|
687
|
-
self, arg0, marc_field
|
|
688
|
-
):
|
|
813
|
+
def _extracted_from_condition_set_electronic_access_relations_id_2(self, arg0, marc_field):
|
|
689
814
|
enum = {
|
|
690
815
|
"0": "resource",
|
|
691
816
|
"1": "version of resource",
|
|
@@ -703,7 +828,7 @@ class Conditions:
|
|
|
703
828
|
name,
|
|
704
829
|
)
|
|
705
830
|
|
|
706
|
-
self.mapper.migration_report.add(
|
|
831
|
+
self.mapper.migration_report.add("MappedElectronicRelationshipTypes", t[1])
|
|
707
832
|
|
|
708
833
|
return t[0]
|
|
709
834
|
|
|
@@ -714,9 +839,288 @@ class Conditions:
|
|
|
714
839
|
# https://www.loc.gov/marc/bibliographic/bd541.html
|
|
715
840
|
ind1 = marc_field.indicator1
|
|
716
841
|
self.mapper.migration_report.add(
|
|
717
|
-
|
|
718
|
-
f"{marc_field.tag} indicator1: {ind1} (
|
|
842
|
+
"StaffOnlyViaIndicator",
|
|
843
|
+
f"{marc_field.tag} indicator1: {ind1} ("
|
|
844
|
+
+ i18n.t("0 is staff-only, all other values are public")
|
|
845
|
+
+ ")",
|
|
719
846
|
)
|
|
720
|
-
if ind1
|
|
847
|
+
if ind1 == "0":
|
|
721
848
|
return "true"
|
|
722
849
|
return "false"
|
|
850
|
+
|
|
851
|
+
def condition_set_subject_type_id(self, legacy_id, value, parameter, marc_field: field.Field):
|
|
852
|
+
try:
|
|
853
|
+
t = self.get_ref_data_tuple_by_name(
|
|
854
|
+
self.folio.subject_types, "subject_types", parameter["name"]
|
|
855
|
+
)
|
|
856
|
+
self.mapper.migration_report.add("MappedSubjectTypes", t[1])
|
|
857
|
+
return t[0]
|
|
858
|
+
except Exception:
|
|
859
|
+
raise TransformationProcessError(
|
|
860
|
+
legacy_id,
|
|
861
|
+
f"Subject type not found for {parameter['name']} {marc_field}",
|
|
862
|
+
)
|
|
863
|
+
|
|
864
|
+
def condition_set_subject_source_id(self, legacy_id, value, parameter, marc_field: field.Field):
|
|
865
|
+
try:
|
|
866
|
+
t = self.get_ref_data_tuple_by_name(
|
|
867
|
+
self.folio.folio_get_all("/subject-sources", "subjectSources"), "subject_sources", parameter["name"]
|
|
868
|
+
)
|
|
869
|
+
self.mapper.migration_report.add("MappedSubjectSources", t[1])
|
|
870
|
+
return t[0]
|
|
871
|
+
except Exception:
|
|
872
|
+
raise TransformationProcessError(
|
|
873
|
+
legacy_id,
|
|
874
|
+
f"Subject source not found for {parameter['name']} {marc_field}",
|
|
875
|
+
)
|
|
876
|
+
|
|
877
|
+
def condition_set_subject_source_id_by_code(self, legacy_id, value, parameter, marc_field: field.Field):
|
|
878
|
+
try:
|
|
879
|
+
t = self.get_ref_data_tuple_by_code(
|
|
880
|
+
self.folio.folio_get_all("/subject-sources", "subjectSources"), "subject_sources", value
|
|
881
|
+
)
|
|
882
|
+
self.mapper.migration_report.add("MappedSubjectSources", t[1])
|
|
883
|
+
return t[0]
|
|
884
|
+
except Exception:
|
|
885
|
+
raise TransformationProcessError(
|
|
886
|
+
legacy_id,
|
|
887
|
+
f"Subject source not found for {value} {marc_field}",
|
|
888
|
+
)
|
|
889
|
+
|
|
890
|
+
def condition_set_receipt_status(
|
|
891
|
+
self, legacy_id, value, parameter, marc_field: field.Field
|
|
892
|
+
):
|
|
893
|
+
"""
|
|
894
|
+
This method maps the receipt status based on the 008 field.
|
|
895
|
+
This condition is not available in FOLIO's MARC mapping engine and
|
|
896
|
+
will require use of a supplemental mapping rules file in the
|
|
897
|
+
HoldingsMarcTransformer task definition.
|
|
898
|
+
"""
|
|
899
|
+
if len(value) < 7:
|
|
900
|
+
self.mapper.migration_report.add(
|
|
901
|
+
"ReceiptStatusMapping", i18n.t("008 is too short") + f": {value}"
|
|
902
|
+
)
|
|
903
|
+
return ""
|
|
904
|
+
|
|
905
|
+
status_map = {
|
|
906
|
+
"0": "Unknown",
|
|
907
|
+
"1": "Other receipt or acquisition status",
|
|
908
|
+
"2": "Received and complete or ceased",
|
|
909
|
+
"3": "On order",
|
|
910
|
+
"4": "Currently received",
|
|
911
|
+
"5": "Not currently received",
|
|
912
|
+
"6": "External access",
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
try:
|
|
916
|
+
mapped_value = status_map[value[6]]
|
|
917
|
+
self.mapper.migration_report.add(
|
|
918
|
+
"ReceiptStatusMapping",
|
|
919
|
+
i18n.t(
|
|
920
|
+
"%{value} mapped to %{mapped_value}",
|
|
921
|
+
value=value[6],
|
|
922
|
+
mapped_value=mapped_value,
|
|
923
|
+
),
|
|
924
|
+
)
|
|
925
|
+
return mapped_value
|
|
926
|
+
except Exception:
|
|
927
|
+
self.mapper.migration_report.add(
|
|
928
|
+
"ReceiptStatusMapping", i18n.t("%{value} not found in map.", value=value[6])
|
|
929
|
+
)
|
|
930
|
+
return ""
|
|
931
|
+
|
|
932
|
+
def condition_set_acquisition_method(
|
|
933
|
+
self, legacy_id, value, parameter, marc_field: field.Field
|
|
934
|
+
):
|
|
935
|
+
"""
|
|
936
|
+
This method maps the acquisition method based on the 008 field.
|
|
937
|
+
This condition is not available in FOLIO's MARC mapping engine and
|
|
938
|
+
will require use of a supplemental mapping rules file in the
|
|
939
|
+
HoldingsMarcTransformer task definition.
|
|
940
|
+
"""
|
|
941
|
+
if len(value) < 8:
|
|
942
|
+
self.mapper.migration_report.add(
|
|
943
|
+
"ReceiptStatusMapping", i18n.t("008 is too short") + f": {value}"
|
|
944
|
+
)
|
|
945
|
+
return ""
|
|
946
|
+
|
|
947
|
+
try:
|
|
948
|
+
acq_methods = {
|
|
949
|
+
"c": "Cooperative or consortial purchase",
|
|
950
|
+
"d": "Deposit",
|
|
951
|
+
"e": "Exchange",
|
|
952
|
+
"f": "Free",
|
|
953
|
+
"g": "Gift",
|
|
954
|
+
"l": "Legal deposit",
|
|
955
|
+
"m": "Membership",
|
|
956
|
+
"n": "Non-library purchase",
|
|
957
|
+
"p": "Purchase",
|
|
958
|
+
"q": "Lease",
|
|
959
|
+
"u": "Unknown",
|
|
960
|
+
"z": "Other method of acquisition",
|
|
961
|
+
}
|
|
962
|
+
mapped_value = acq_methods[value[7]]
|
|
963
|
+
self.mapper.migration_report.add(
|
|
964
|
+
"MethodOfAcquisitionMapping",
|
|
965
|
+
i18n.t(
|
|
966
|
+
"%{value} mapped to %{mapped_value}", value=value[7], mapped_value=mapped_value
|
|
967
|
+
),
|
|
968
|
+
)
|
|
969
|
+
return mapped_value
|
|
970
|
+
except Exception:
|
|
971
|
+
self.mapper.migration_report.add(
|
|
972
|
+
"MethodOfAcquisitionMapping", i18n.t("%{value} not found in map.", value=value[8])
|
|
973
|
+
)
|
|
974
|
+
return ""
|
|
975
|
+
|
|
976
|
+
def condition_set_retention_policy(
|
|
977
|
+
self, legacy_id, value, parameter, marc_field: field.Field
|
|
978
|
+
):
|
|
979
|
+
"""
|
|
980
|
+
This method maps the retention policy based on the 008 field.
|
|
981
|
+
This condition is not available in FOLIO's MARC mapping engine and
|
|
982
|
+
will require use of a supplemental mapping rules file in the
|
|
983
|
+
HoldingsMarcTransformer task definition.
|
|
984
|
+
"""
|
|
985
|
+
if len(value) < 13:
|
|
986
|
+
self.mapper.migration_report.add(
|
|
987
|
+
"RetentionPolicyMapping", i18n.t("008 is too short") + f": {value}"
|
|
988
|
+
)
|
|
989
|
+
return ""
|
|
990
|
+
value = value.replace("|", " ").replace("#", " ") # Replace pipe with space for mapping consistency
|
|
991
|
+
try:
|
|
992
|
+
retention_policies = {
|
|
993
|
+
"0": "Unknown",
|
|
994
|
+
"1": "Other general retention policy",
|
|
995
|
+
"2": "Retained except as replaced by updates",
|
|
996
|
+
"3": "Sample issue retained",
|
|
997
|
+
"4": "Retained until replaced by microform",
|
|
998
|
+
"5": "Retained until replaced by cumulation, replacement volume, or revision",
|
|
999
|
+
"6": "Retained for a limited period",
|
|
1000
|
+
"7": "Not retained",
|
|
1001
|
+
"8": "Permanently retained",
|
|
1002
|
+
}
|
|
1003
|
+
mapped_value = retention_policies[value[12]]
|
|
1004
|
+
self.mapper.migration_report.add(
|
|
1005
|
+
"RetentionPolicyMapping",
|
|
1006
|
+
i18n.t(
|
|
1007
|
+
"%{value} mapped to %{mapped_value}",
|
|
1008
|
+
value=value[12],
|
|
1009
|
+
mapped_value=mapped_value,
|
|
1010
|
+
),
|
|
1011
|
+
)
|
|
1012
|
+
if value[12] == "6":
|
|
1013
|
+
policy_types = {
|
|
1014
|
+
"l": "Latest",
|
|
1015
|
+
"p": "Previous",
|
|
1016
|
+
}
|
|
1017
|
+
unit_types = {
|
|
1018
|
+
"m": "Day",
|
|
1019
|
+
"w": "Month",
|
|
1020
|
+
"y": "Year",
|
|
1021
|
+
"e": "Edition",
|
|
1022
|
+
"i": "Issue",
|
|
1023
|
+
"s": "Supplement"
|
|
1024
|
+
}
|
|
1025
|
+
try:
|
|
1026
|
+
specific_retention_policy = ""
|
|
1027
|
+
if value[13].strip() or value[15].strip():
|
|
1028
|
+
if value[14].strip() and int(value[14]) > 1:
|
|
1029
|
+
specific_retention_policy = f"{policy_types.get(value[13], '')} {value[14]} {unit_types.get(value[15], '')}s retained".strip()
|
|
1030
|
+
else:
|
|
1031
|
+
specific_retention_policy = f"{policy_types.get(value[13], '')} {unit_types.get(value[15], '')} retained".strip()
|
|
1032
|
+
if specific_retention_policy:
|
|
1033
|
+
self.mapper.migration_report.add(
|
|
1034
|
+
"RetentionPolicyMapping",
|
|
1035
|
+
i18n.t(
|
|
1036
|
+
"Retention policy 6 indicates a limited period. Specific retention period will be mapped from 008/13-15",
|
|
1037
|
+
)
|
|
1038
|
+
)
|
|
1039
|
+
return specific_retention_policy
|
|
1040
|
+
else:
|
|
1041
|
+
raise ValueError(
|
|
1042
|
+
"Specific retention policy is empty or invalid in 008/13-15"
|
|
1043
|
+
)
|
|
1044
|
+
except ValueError:
|
|
1045
|
+
self.mapper.migration_report.add(
|
|
1046
|
+
"RetentionPolicyMapping",
|
|
1047
|
+
i18n.t("Invalid specific retention policy in 008/13-15: %{value}", value=value[13:16]),
|
|
1048
|
+
)
|
|
1049
|
+
return mapped_value
|
|
1050
|
+
except Exception:
|
|
1051
|
+
self.mapper.migration_report.add(
|
|
1052
|
+
"RetentionPolicyMapping", i18n.t("%{value} not found in map.", value=value[12])
|
|
1053
|
+
)
|
|
1054
|
+
return ""
|
|
1055
|
+
|
|
1056
|
+
def condition_set_ill_policy(
|
|
1057
|
+
self, legacy_id, value, parameter, marc_field: field.Field
|
|
1058
|
+
):
|
|
1059
|
+
"""
|
|
1060
|
+
This method maps the ILL policy based on the 008 field.
|
|
1061
|
+
This condition is not available in FOLIO's MARC mapping engine and
|
|
1062
|
+
will require use of a supplemental mapping rules file in the
|
|
1063
|
+
HoldingsMarcTransformer task definition."""
|
|
1064
|
+
if len(value) < 21:
|
|
1065
|
+
self.mapper.migration_report.add(
|
|
1066
|
+
"ILLPolicyMapping", i18n.t("008 is too short") + f": {value}"
|
|
1067
|
+
)
|
|
1068
|
+
return ""
|
|
1069
|
+
try:
|
|
1070
|
+
ill_policies = {
|
|
1071
|
+
"a": "Will lend",
|
|
1072
|
+
"b": "Will not lend",
|
|
1073
|
+
"c": "Will lend hard copy only",
|
|
1074
|
+
"l": "Limited lending policy",
|
|
1075
|
+
"u": "Unknown",
|
|
1076
|
+
}
|
|
1077
|
+
mapped_value = ill_policies[value[20]]
|
|
1078
|
+
self.mapper.migration_report.add(
|
|
1079
|
+
"ILLPolicyMapping",
|
|
1080
|
+
i18n.t("%{value} mapped to %{mapped_value}", value=value[20], mapped_value=mapped_value),
|
|
1081
|
+
)
|
|
1082
|
+
ill_policy_id = self.get_ref_data_tuple_by_name(
|
|
1083
|
+
self.ill_policies, "ill_policies", mapped_value
|
|
1084
|
+
)
|
|
1085
|
+
return ill_policy_id[0] if ill_policy_id else ""
|
|
1086
|
+
except Exception:
|
|
1087
|
+
self.mapper.migration_report.add(
|
|
1088
|
+
"ILLPolicyMapping", i18n.t("%{value} not found in map.", value=value[20])
|
|
1089
|
+
)
|
|
1090
|
+
return ""
|
|
1091
|
+
|
|
1092
|
+
def condition_set_digitization_policy(
|
|
1093
|
+
self, legacy_id, value, parameter, marc_field: field.Field
|
|
1094
|
+
):
|
|
1095
|
+
"""
|
|
1096
|
+
This method maps the digitization policy based on the 008 field.
|
|
1097
|
+
This condition is not available in FOLIO's MARC mapping engine and
|
|
1098
|
+
will require use of a supplemental mapping rules file in the
|
|
1099
|
+
HoldingsMarcTransformer task definition.
|
|
1100
|
+
"""
|
|
1101
|
+
if len(value) < 22:
|
|
1102
|
+
self.mapper.migration_report.add(
|
|
1103
|
+
"DigitizationPolicyMapping", i18n.t("008 is too short") + f": {value}"
|
|
1104
|
+
)
|
|
1105
|
+
return ""
|
|
1106
|
+
try:
|
|
1107
|
+
digitization_policies = {
|
|
1108
|
+
"a": "Will reproduce",
|
|
1109
|
+
"b": "Will not reproduce",
|
|
1110
|
+
"u": "Unknown",
|
|
1111
|
+
}
|
|
1112
|
+
mapped_value = digitization_policies[value[21]]
|
|
1113
|
+
self.mapper.migration_report.add(
|
|
1114
|
+
"DigitizationPolicyMapping",
|
|
1115
|
+
i18n.t(
|
|
1116
|
+
"%{value} mapped to %{mapped_value}",
|
|
1117
|
+
value=value[21],
|
|
1118
|
+
mapped_value=mapped_value,
|
|
1119
|
+
),
|
|
1120
|
+
)
|
|
1121
|
+
return mapped_value
|
|
1122
|
+
except Exception:
|
|
1123
|
+
self.mapper.migration_report.add(
|
|
1124
|
+
"DigitizationPolicyMapping", i18n.t("%{value} not found in map.", value=value[21])
|
|
1125
|
+
)
|
|
1126
|
+
return ""
|