folio-migration-tools 1.10.2__py3-none-any.whl → 1.10.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. folio_migration_tools/__init__.py +10 -2
  2. folio_migration_tools/__main__.py +7 -0
  3. folio_migration_tools/circulation_helper.py +23 -8
  4. folio_migration_tools/colors.py +7 -0
  5. folio_migration_tools/config_file_load.py +7 -0
  6. folio_migration_tools/custom_dict.py +17 -0
  7. folio_migration_tools/custom_exceptions.py +40 -4
  8. folio_migration_tools/extradata_writer.py +12 -0
  9. folio_migration_tools/folder_structure.py +16 -0
  10. folio_migration_tools/helper.py +7 -0
  11. folio_migration_tools/holdings_helper.py +11 -5
  12. folio_migration_tools/i18n_config.py +6 -0
  13. folio_migration_tools/library_configuration.py +19 -5
  14. folio_migration_tools/mapper_base.py +15 -0
  15. folio_migration_tools/mapping_file_transformation/__init__.py +1 -0
  16. folio_migration_tools/mapping_file_transformation/courses_mapper.py +17 -0
  17. folio_migration_tools/mapping_file_transformation/holdings_mapper.py +19 -0
  18. folio_migration_tools/mapping_file_transformation/item_mapper.py +24 -0
  19. folio_migration_tools/mapping_file_transformation/manual_fee_fines_mapper.py +18 -0
  20. folio_migration_tools/mapping_file_transformation/mapping_file_mapper_base.py +26 -9
  21. folio_migration_tools/mapping_file_transformation/notes_mapper.py +16 -0
  22. folio_migration_tools/mapping_file_transformation/order_mapper.py +40 -27
  23. folio_migration_tools/mapping_file_transformation/organization_mapper.py +40 -33
  24. folio_migration_tools/mapping_file_transformation/ref_data_mapping.py +17 -0
  25. folio_migration_tools/mapping_file_transformation/user_mapper.py +16 -0
  26. folio_migration_tools/marc_rules_transformation/__init__.py +1 -0
  27. folio_migration_tools/marc_rules_transformation/conditions.py +49 -36
  28. folio_migration_tools/marc_rules_transformation/holdings_statementsparser.py +9 -3
  29. folio_migration_tools/marc_rules_transformation/hrid_handler.py +16 -1
  30. folio_migration_tools/marc_rules_transformation/marc_file_processor.py +15 -1
  31. folio_migration_tools/marc_rules_transformation/marc_reader_wrapper.py +7 -0
  32. folio_migration_tools/marc_rules_transformation/rules_mapper_base.py +35 -29
  33. folio_migration_tools/marc_rules_transformation/rules_mapper_bibs.py +23 -18
  34. folio_migration_tools/marc_rules_transformation/rules_mapper_holdings.py +46 -27
  35. folio_migration_tools/migration_report.py +14 -6
  36. folio_migration_tools/migration_tasks/__init__.py +2 -0
  37. folio_migration_tools/migration_tasks/batch_poster.py +34 -18
  38. folio_migration_tools/migration_tasks/bibs_transformer.py +16 -0
  39. folio_migration_tools/migration_tasks/courses_migrator.py +15 -0
  40. folio_migration_tools/migration_tasks/holdings_csv_transformer.py +18 -3
  41. folio_migration_tools/migration_tasks/holdings_marc_transformer.py +17 -0
  42. folio_migration_tools/migration_tasks/inventory_batch_poster.py +424 -0
  43. folio_migration_tools/migration_tasks/items_transformer.py +16 -0
  44. folio_migration_tools/migration_tasks/loans_migrator.py +17 -2
  45. folio_migration_tools/migration_tasks/manual_fee_fines_transformer.py +16 -0
  46. folio_migration_tools/migration_tasks/marc_import.py +407 -0
  47. folio_migration_tools/migration_tasks/migration_task_base.py +49 -17
  48. folio_migration_tools/migration_tasks/orders_transformer.py +16 -0
  49. folio_migration_tools/migration_tasks/organization_transformer.py +17 -2
  50. folio_migration_tools/migration_tasks/requests_migrator.py +15 -0
  51. folio_migration_tools/migration_tasks/reserves_migrator.py +15 -0
  52. folio_migration_tools/migration_tasks/user_importer.py +347 -0
  53. folio_migration_tools/migration_tasks/user_transformer.py +16 -0
  54. folio_migration_tools/task_configuration.py +7 -0
  55. folio_migration_tools/transaction_migration/__init__.py +1 -0
  56. folio_migration_tools/transaction_migration/legacy_loan.py +16 -0
  57. folio_migration_tools/transaction_migration/legacy_request.py +14 -0
  58. folio_migration_tools/transaction_migration/legacy_reserve.py +14 -0
  59. folio_migration_tools/transaction_migration/transaction_result.py +16 -0
  60. {folio_migration_tools-1.10.2.dist-info → folio_migration_tools-1.10.3.dist-info}/METADATA +1 -1
  61. folio_migration_tools-1.10.3.dist-info/RECORD +66 -0
  62. folio_migration_tools-1.10.2.dist-info/RECORD +0 -63
  63. {folio_migration_tools-1.10.2.dist-info → folio_migration_tools-1.10.3.dist-info}/WHEEL +0 -0
  64. {folio_migration_tools-1.10.2.dist-info → folio_migration_tools-1.10.3.dist-info}/entry_points.txt +0 -0
@@ -1,3 +1,9 @@
1
+ """Mapper for transforming notes to FOLIO Notes format.
2
+
3
+ Provides the NotesMapper class for mapping legacy notes to FOLIO Notes records.
4
+ Handles note types, content, and object associations.
5
+ """
6
+
1
7
  import logging
2
8
  import i18n
3
9
 
@@ -20,6 +26,16 @@ class NotesMapper(MappingFileMapperBase):
20
26
  object_type: FOLIONamespaces,
21
27
  ignore_legacy_identifier: bool = False,
22
28
  ) -> None:
29
+ """Initialize NotesMapper for handling note transformations.
30
+
31
+ Args:
32
+ library_configuration (LibraryConfiguration): Library configuration.
33
+ task_configuration: Task configuration for note migration.
34
+ folio_client (FolioClient): FOLIO API client.
35
+ record_map (dict): Mapping configuration for note fields.
36
+ object_type (FOLIONamespaces): Type of object containing notes.
37
+ ignore_legacy_identifier (bool): Whether to ignore legacy identifiers.
38
+ """
23
39
  self.folio_client: FolioClient = folio_client
24
40
  self.setup_notes_schema()
25
41
  super().__init__(
@@ -1,3 +1,10 @@
1
+ """Mapper for transforming order data to FOLIO Orders format.
2
+
3
+ Provides the OrderMapper class for mapping legacy purchase order data to FOLIO
4
+ Orders and PurchaseOrderLines. Handles composite orders with embedded lines,
5
+ acquisition units, fund distributions, and vendor references.
6
+ """
7
+
1
8
  import json
2
9
  import logging
3
10
  import os
@@ -41,6 +48,23 @@ class CompositeOrderMapper(MappingFileMapperBase):
41
48
  funds_map,
42
49
  funds_expense_class_map=None,
43
50
  ):
51
+ """Initialize CompositeOrderMapper for purchase order transformations.
52
+
53
+ Args:
54
+ folio_client (FolioClient): FOLIO API client.
55
+ library_configuration (LibraryConfiguration): Library configuration.
56
+ task_configuration: Task configuration for orders migration.
57
+ composite_order_map (dict): Mapping configuration for order fields.
58
+ organizations_id_map (dict): Mapping of legacy to FOLIO organizations.
59
+ instance_id_map (dict): Mapping of legacy to FOLIO instances.
60
+ acquisition_method_map: Mapping of legacy to FOLIO acquisition methods.
61
+ payment_status_map: Mapping of legacy to FOLIO payment statuses.
62
+ receipt_status_map: Mapping of legacy to FOLIO receipt statuses.
63
+ workflow_status_map: Mapping of legacy to FOLIO workflow statuses.
64
+ location_map: Mapping of legacy to FOLIO locations.
65
+ funds_map: Mapping of legacy to FOLIO funds.
66
+ funds_expense_class_map: Mapping for fund expense classes.
67
+ """
44
68
  # Get organization schema
45
69
  self.composite_order_schema = CompositeOrderMapper.get_latest_acq_schemas_from_github(
46
70
  "folio-org", "mod-orders", "mod-orders", "composite_purchase_order"
@@ -139,19 +163,16 @@ class CompositeOrderMapper(MappingFileMapperBase):
139
163
 
140
164
  @staticmethod
141
165
  def get_latest_acq_schemas_from_github(owner, repo, module, object):
142
- """
143
- Given a repository owner, a repository, a module name and the name
144
- of a FOLIO acquisition object, returns a schema for that object that
145
- also includes the schemas of any other referenced acq objects.
166
+ """Fetch acquisition object schema from GitHub with referenced schemas.
146
167
 
147
168
  Args:
148
- owner (_type_): _description_
149
- repo (_type_): _description_
150
- module (_type_): _description_
151
- object (_type_): _description_
169
+ owner (str): GitHub repository owner.
170
+ repo (str): GitHub repository name.
171
+ module (str): Module name within the repository.
172
+ object (str): Object name whose schema is to be fetched.
152
173
 
153
174
  Returns:
154
- _type_: _description_
175
+ Dict: _description_
155
176
  """
156
177
  try:
157
178
  # Authenticate when calling GitHub, using an API key stored in .env
@@ -206,22 +227,18 @@ class CompositeOrderMapper(MappingFileMapperBase):
206
227
 
207
228
  @staticmethod
208
229
  def get_submodules_of_latest_release(owner, repo, github_headers):
209
- """
210
- Given a repository owner and a repository, identifies the latest
211
- release of the repository and returns the submodules associated with
212
- this release.
230
+ """Get submodules associated with the latest release of a repository.
213
231
 
214
232
  Args:
215
- owner (_type_): _description_
216
- repo (_type_): _description_
217
- github_headers (_type_): _description_
233
+ owner (str): GitHub repository owner.
234
+ repo (str): GitHub repository name.
235
+ github_headers (dict): Headers to use for GitHub API requests.
218
236
 
219
237
  Returns:
220
- _type_: _description_
238
+ list: List of submodules associated with the latest release.
221
239
 
222
240
 
223
241
  """
224
-
225
242
  github_path = "https://api.github.com/repos"
226
243
 
227
244
  # Get metadata for the latest release
@@ -258,20 +275,16 @@ class CompositeOrderMapper(MappingFileMapperBase):
258
275
 
259
276
  @staticmethod
260
277
  def build_extended_object(object_schema, submodule_path, github_headers):
261
- """
262
- Takes an object schema (for example an organization) and the path to a
263
- submodule repository and returns the same schema with the full schemas
264
- of subordinate objects (for example aliases).
278
+ """Extend an object schema with full schemas of subordinate objects.
265
279
 
266
280
  Args:
267
- object_schema (_type_): _description_
268
- submodule_path (_type_): _description_
269
- github_headers (_type_): _description_
281
+ object_schema (dict): The schema of the object to be extended.
282
+ submodule_path (str): The path to the submodule containing schemas.
283
+ github_headers (dict): Headers to use for GitHub API requests.
270
284
 
271
285
  Returns:
272
- _type_: _description_
286
+ dict: The extended object schema.
273
287
  """
274
-
275
288
  supported_types = [
276
289
  "string",
277
290
  "boolean",
@@ -1,3 +1,10 @@
1
+ """Mapper for transforming organization data to FOLIO Organizations format.
2
+
3
+ Provides the OrganizationMapper class for mapping legacy vendor/organization data
4
+ to FOLIO Organization records. Handles embedded interfaces, contacts, categories,
5
+ and extradata object creation.
6
+ """
7
+
1
8
  import json
2
9
  import logging
3
10
  import os
@@ -30,6 +37,18 @@ class OrganizationMapper(MappingFileMapperBase):
30
37
  email_categories_map,
31
38
  phone_categories_map,
32
39
  ):
40
+ """Initialize OrganizationMapper for organization transformations.
41
+
42
+ Args:
43
+ folio_client (FolioClient): FOLIO API client.
44
+ library_configuration (LibraryConfiguration): Library configuration.
45
+ task_config: Task configuration for organizations migration.
46
+ organization_map (dict): Mapping configuration for organization fields.
47
+ organization_types_map: Mapping of legacy to FOLIO organization types.
48
+ address_categories_map: Mapping of legacy to FOLIO address categories.
49
+ email_categories_map: Mapping of legacy to FOLIO email categories.
50
+ phone_categories_map: Mapping of legacy to FOLIO phone categories.
51
+ """
33
52
  # Build composite organization schema
34
53
  if os.environ.get("GITHUB_TOKEN"):
35
54
  logging.info("Using GITHUB_TOKEN environment variable for GitHub API Access")
@@ -119,15 +138,14 @@ class OrganizationMapper(MappingFileMapperBase):
119
138
  email_categories_map,
120
139
  phone_categories_map,
121
140
  ):
122
- """
141
+ """Set up reference data mappings for organization categories and types.
123
142
 
124
143
  Args:
125
- organization_types_map (_type_): _description_
126
- address_categories_map (_type_): _description_
127
- email_categories_map (_type_): _description_
128
- phone_categories_map (_type_): _description_
144
+ organization_types_map (dict): Mapping for organization types.
145
+ address_categories_map (dict): Mapping for address categories.
146
+ email_categories_map (dict): Mapping for email categories.
147
+ phone_categories_map (dict): Mapping for phone categories.
129
148
  """
130
-
131
149
  categories_shared_args = (
132
150
  self.folio_client,
133
151
  "/organizations-storage/categories",
@@ -169,19 +187,16 @@ class OrganizationMapper(MappingFileMapperBase):
169
187
 
170
188
  @staticmethod
171
189
  def get_latest_acq_schemas_from_github(owner, repo, module, object):
172
- """
173
- Given a repository owner, a repository, a module name and the name
174
- of a FOLIO acquisition object, returns a schema for that object that
175
- also includes the schemas of any other referenced acq objects.
190
+ """Fetch acquisition object schema from GitHub with referenced schemas.
176
191
 
177
192
  Args:
178
- owner (_type_): _description_
179
- repo (_type_): _description_
180
- module (_type_): _description_
181
- object (_type_): _description_
193
+ owner (str): GitHub repository owner.
194
+ repo (str): GitHub repository name.
195
+ module (str): Module name within the repository.
196
+ object (str): Object name whose schema is to be fetched.
182
197
 
183
198
  Returns:
184
- _type_: _description_
199
+ dict: The extended object schema.
185
200
  """
186
201
  try:
187
202
  # Authenticate when calling GitHub, using an API key stored in .env
@@ -232,20 +247,16 @@ class OrganizationMapper(MappingFileMapperBase):
232
247
 
233
248
  @staticmethod
234
249
  def get_submodules_of_latest_release(owner, repo, github_headers):
235
- """
236
- Given a repository owner and a repository, identifies the latest
237
- release of the repository and returns the submodules associated with
238
- this release.
250
+ """Get submodules associated with the latest release of a repository.
239
251
 
240
252
  Args:
241
- owner (_type_): _description_
242
- repo (_type_): _description_
243
- github_headers (_type_): _description_
253
+ owner (str): GitHub repository owner.
254
+ repo (str): GitHub repository name.
255
+ github_headers (dict): Headers to use for GitHub API requests.
244
256
 
245
257
  Returns:
246
- _type_: _description_
258
+ list: List of submodules associated with the latest release.
247
259
  """
248
-
249
260
  github_path = "https://api.github.com/repos"
250
261
 
251
262
  # Get metadata for the latest release
@@ -280,20 +291,16 @@ class OrganizationMapper(MappingFileMapperBase):
280
291
 
281
292
  @staticmethod
282
293
  def build_extended_object(object_schema, submodule_path, github_headers):
283
- """
284
- Takes an object schema (for example an organization) and the path to a
285
- submodule repository and returns the same schema with the full schemas
286
- of subordinate objects (for example aliases).
294
+ """Extend an object schema with full schemas of subordinate objects.
287
295
 
288
296
  Args:
289
- object_schema (_type_): _description_
290
- submodule_path (_type_): _description_
291
- github_headers (_type_): _description_
297
+ object_schema (dict): The base object schema to extend.
298
+ submodule_path (str): Path to the submodule containing additional schemas.
299
+ github_headers (dict): Headers to use for GitHub API requests.
292
300
 
293
301
  Returns:
294
- _type_: _description_
302
+ dict: The extended object schema.
295
303
  """
296
-
297
304
  supported_types = ["string", "boolean", "number", "integer", "text", "object", "array"]
298
305
 
299
306
  try:
@@ -1,3 +1,10 @@
1
+ """Reference data mapping utilities.
2
+
3
+ Provides the RefDataMapping class for mapping legacy reference data values to FOLIO
4
+ reference data UUIDs. Handles lookups in FOLIO, wildcard matching, and default values
5
+ for common reference data types like locations, material types, and patron groups.
6
+ """
7
+
1
8
  import json
2
9
  import logging
3
10
  import sys
@@ -17,6 +24,16 @@ class RefDataMapping(object):
17
24
  key_type,
18
25
  blurb_id,
19
26
  ):
27
+ """Initialize RefDataMapping for reference data transformations.
28
+
29
+ Args:
30
+ folio_client (FolioClient): FOLIO API client for fetching reference data.
31
+ ref_data_path: API path to reference data endpoint.
32
+ array_name: Name of the data array in the API response.
33
+ the_map: Mapping configuration for data transformation.
34
+ key_type: Type of key being mapped.
35
+ blurb_id: Identifier for blurbs related to this mapping.
36
+ """
20
37
  self.name = array_name
21
38
  self.cache: dict = {}
22
39
  self.blurb_id = blurb_id
@@ -1,3 +1,9 @@
1
+ """Mapper for transforming user/patron data to FOLIO Users format.
2
+
3
+ Provides the UserMapper class for mapping legacy patron data to FOLIO User records
4
+ using configured mapping files.
5
+ """
6
+
1
7
  import csv
2
8
  import json
3
9
  import logging
@@ -31,6 +37,16 @@ class UserMapper(MappingFileMapperBase):
31
37
  departments_mapping,
32
38
  groups_map,
33
39
  ):
40
+ """Initialize UserMapper for user transformations.
41
+
42
+ Args:
43
+ folio_client (FolioClient): FOLIO API client.
44
+ task_config: Task configuration for users migration.
45
+ library_config: Library configuration.
46
+ user_map: Mapping configuration for user fields.
47
+ departments_mapping: Mapping of legacy to FOLIO departments.
48
+ groups_map: Mapping of legacy to FOLIO user groups.
49
+ """
34
50
  try:
35
51
  user_schema = folio_client.get_from_github(
36
52
  "folio-org", "mod-user-import", "/ramls/schemas/userdataimport.json"
@@ -0,0 +1 @@
1
+ """MARC record transformation using FOLIO mapping rules."""
@@ -1,3 +1,11 @@
1
+ """MARC rules conditions processing.
2
+
3
+ A reimplementation of FOLIO's MARC transformation rules. Handles
4
+ evaluation of rule conditions including field presence, indicator values, subfield
5
+ patterns, and parameter validation. Supports complex boolean logic for controlling
6
+ when transformation rules should be applied.
7
+ """
8
+
1
9
  import logging
2
10
  import re
3
11
  import traceback
@@ -36,6 +44,15 @@ class Conditions:
36
44
  folio_release: FolioRelease,
37
45
  default_call_number_type_name="",
38
46
  ):
47
+ """Initialize Conditions processor for MARC field transformation rules.
48
+
49
+ Args:
50
+ folio (FolioClient): FOLIO API client.
51
+ mapper (RulesMapperBase): Base mapper for rules processing.
52
+ object_type: Type of FOLIO object being transformed.
53
+ folio_release (FolioRelease): FOLIO release version.
54
+ default_call_number_type_name (str): Default call number type name.
55
+ """
39
56
  self.filter_chars = r"[.,\/#!$%\^&\*;:{}=\-_`~()]"
40
57
  self.filter_chars_dop = r"[.,\/#!$%\^&\*;:{}=\_`~()]"
41
58
  self.folio_release: FolioRelease = folio_release
@@ -161,10 +178,11 @@ class Conditions:
161
178
  return attr(legacy_id, value, parameter, marc_field)
162
179
 
163
180
  def condition_trim_punctuation(self, legacy_id, value, parameter, marc_field: field.Field):
164
- """
165
- Strip leading and trailing whitespace, as well as any trailing commas or periods, unless
166
- the period is preceded by a single alpha character (eg. "John D."). Also preserves any
167
- trailing "-" (eg. "1981-"). This condition was introduced in Poppy.
181
+ """Strip whitespace and trailing punctuation, preserving initials and hyphens.
182
+
183
+ Removes leading/trailing whitespace and trailing commas/periods, unless
184
+ the period is preceded by a single alpha character (eg. "John D.").
185
+ Also preserves any trailing "-" (eg. "1981-"). Introduced in Poppy.
168
186
  """
169
187
  pattern1 = re.compile(r"^(.*?)\s.[.]$")
170
188
  pattern2 = re.compile(r"^(.*?)\s.,[.]$")
@@ -314,7 +332,7 @@ class Conditions:
314
332
  def condition_remove_prefix_by_indicator(
315
333
  self, legacy_id, value, parameter, marc_field: field.Field
316
334
  ):
317
- """Returns the index title according to the rules"""
335
+ """Returns the index title according to the rules."""
318
336
  ind2 = marc_field.indicator2
319
337
  reg_str = r"[\s:\/]{0,3}$"
320
338
  if ind2 not in map(str, range(1, 9)):
@@ -759,12 +777,11 @@ class Conditions:
759
777
  def condition_set_electronic_access_relations_id(
760
778
  self, legacy_id, value, parameter, marc_field: field.Field
761
779
  ):
762
- """
763
- This method handles the mapping of electronic access relationship IDs.
764
- If the record type being mapped is FOLIO holdings, it provides an (optional) alternative
765
- mapping based on a provided name parameter, bypassing the FOLIO MARC-to-Holdings mapping
766
- engine behavior. This requires use of a supplemental mapping rules file in the
767
- HoldingsMarcTransformer task definition containing the name parameter.
780
+ """Map electronic access relationship IDs with optional holdings-specific behavior.
781
+
782
+ For FOLIO holdings, provides an optional alternative mapping based on a name
783
+ parameter, bypassing the FOLIO MARC-to-Holdings mapping engine. Requires a
784
+ supplemental mapping rules file in the HoldingsMarcTransformer task definition.
768
785
  """
769
786
  if self.object_type == "holdings" and "name" in parameter:
770
787
  try:
@@ -808,7 +825,7 @@ class Conditions:
808
825
  def condition_set_note_staff_only_via_indicator(
809
826
  self, legacy_id, value, parameter, marc_field: field.Field
810
827
  ):
811
- """Returns true of false depending on the first indicator"""
828
+ """Returns true of false depending on the first indicator."""
812
829
  # https://www.loc.gov/marc/bibliographic/bd541.html
813
830
  ind1 = marc_field.indicator1
814
831
  self.mapper.migration_report.add(
@@ -869,11 +886,10 @@ class Conditions:
869
886
  ) from e
870
887
 
871
888
  def condition_set_receipt_status(self, legacy_id, value, parameter, marc_field: field.Field):
872
- """
873
- This method maps the receipt status based on the 008 field.
874
- This condition is not available in FOLIO's MARC mapping engine and
875
- will require use of a supplemental mapping rules file in the
876
- HoldingsMarcTransformer task definition.
889
+ """Map receipt status from MARC 008 field.
890
+
891
+ Requires a supplemental mapping rules file in HoldingsMarcTransformer
892
+ as this condition is not available in FOLIO's MARC mapping engine.
877
893
  """
878
894
  if len(value) < 7:
879
895
  self.mapper.migration_report.add(
@@ -911,11 +927,10 @@ class Conditions:
911
927
  def condition_set_acquisition_method(
912
928
  self, legacy_id, value, parameter, marc_field: field.Field
913
929
  ):
914
- """
915
- This method maps the acquisition method based on the 008 field.
916
- This condition is not available in FOLIO's MARC mapping engine and
917
- will require use of a supplemental mapping rules file in the
918
- HoldingsMarcTransformer task definition.
930
+ """Map acquisition method from MARC 008 field.
931
+
932
+ Requires a supplemental mapping rules file in HoldingsMarcTransformer
933
+ as this condition is not available in FOLIO's MARC mapping engine.
919
934
  """
920
935
  if len(value) < 8:
921
936
  self.mapper.migration_report.add(
@@ -953,11 +968,10 @@ class Conditions:
953
968
  return ""
954
969
 
955
970
  def condition_set_retention_policy(self, legacy_id, value, parameter, marc_field: field.Field):
956
- """
957
- This method maps the retention policy based on the 008 field.
958
- This condition is not available in FOLIO's MARC mapping engine and
959
- will require use of a supplemental mapping rules file in the
960
- HoldingsMarcTransformer task definition.
971
+ """Map retention policy from MARC 008 field.
972
+
973
+ Requires a supplemental mapping rules file in HoldingsMarcTransformer
974
+ as this condition is not available in FOLIO's MARC mapping engine.
961
975
  """
962
976
  if len(value) < 13:
963
977
  self.mapper.migration_report.add(
@@ -1037,11 +1051,11 @@ class Conditions:
1037
1051
  return ""
1038
1052
 
1039
1053
  def condition_set_ill_policy(self, legacy_id, value, parameter, marc_field: field.Field):
1054
+ """Map ILL policy from MARC 008 field.
1055
+
1056
+ Requires a supplemental mapping rules file in HoldingsMarcTransformer
1057
+ as this condition is not available in FOLIO's MARC mapping engine.
1040
1058
  """
1041
- This method maps the ILL policy based on the 008 field.
1042
- This condition is not available in FOLIO's MARC mapping engine and
1043
- will require use of a supplemental mapping rules file in the
1044
- HoldingsMarcTransformer task definition."""
1045
1059
  if len(value) < 21:
1046
1060
  self.mapper.migration_report.add(
1047
1061
  "ILLPolicyMapping", i18n.t("008 is too short") + f": {value}"
@@ -1077,11 +1091,10 @@ class Conditions:
1077
1091
  def condition_set_digitization_policy(
1078
1092
  self, legacy_id, value, parameter, marc_field: field.Field
1079
1093
  ):
1080
- """
1081
- This method maps the digitization policy based on the 008 field.
1082
- This condition is not available in FOLIO's MARC mapping engine and
1083
- will require use of a supplemental mapping rules file in the
1084
- HoldingsMarcTransformer task definition.
1094
+ """Map digitization policy from MARC 008 field.
1095
+
1096
+ Requires a supplemental mapping rules file in HoldingsMarcTransformer
1097
+ as this condition is not available in FOLIO's MARC mapping engine.
1085
1098
  """
1086
1099
  if len(value) < 22:
1087
1100
  self.mapper.migration_report.add(
@@ -1,3 +1,10 @@
1
+ """MARC holdings statements parser.
2
+
3
+ Parses MARC21 holdings statements from fields 853-855, 863-865, 866-868 and converts
4
+ them to FOLIO-compatible holdings statements. Handles enumeration, chronology, and
5
+ holdings notes with proper formatting and validation.
6
+ """
7
+
1
8
  import calendar
2
9
  import contextlib
3
10
  import logging
@@ -20,7 +27,7 @@ class HoldingsStatementsParser:
20
27
  legacy_ids: List[str],
21
28
  dedupe_results: bool = True,
22
29
  ) -> dict:
23
- """_summary_
30
+ """_summary_.
24
31
 
25
32
  Args:
26
33
  marc_record (Record): pymarc Record object
@@ -36,7 +43,6 @@ class HoldingsStatementsParser:
36
43
  Returns:
37
44
  dict: A dictionary containing parsed holdings statements and related information.
38
45
  """ # noqa: E501
39
-
40
46
  # Textual holdings statements
41
47
  return_dict: dict = {"statements": [], "migration_report": [], "hlm_stmts": []}
42
48
  HoldingsStatementsParser.get_textual_statements(
@@ -178,7 +184,7 @@ class HoldingsStatementsParser:
178
184
  def get_textual_statements(
179
185
  marc_record: Record, field_textual: str, return_dict: dict, legacy_ids: List[str]
180
186
  ):
181
- """Returns the textual statements from the relevant marc fields
187
+ """Returns the textual statements from the relevant marc fields.
182
188
 
183
189
  Args:
184
190
  marc_record (Record): _description_
@@ -1,3 +1,10 @@
1
+ """HRID (Human Readable ID) handling for MARC transformations.
2
+
3
+ Manages HRID generation and 001/003/035 field manipulation during MARC transformation.
4
+ Supports both FOLIO-generated HRIDs and preservation of legacy 001 fields as HRIDs.
5
+ Handles creation of 035 fields from previous 001/003 combinations.
6
+ """
7
+
1
8
  import json
2
9
  import logging
3
10
  from typing import Set
@@ -22,6 +29,14 @@ class HRIDHandler:
22
29
  migration_report: MigrationReport,
23
30
  deactivate035_from001: bool,
24
31
  ):
32
+ """Initialize HRID handler for managing FOLIO Human-Readable IDs.
33
+
34
+ Args:
35
+ folio_client (FolioClient): FOLIO API client.
36
+ handling (HridHandling): HRID handling configuration.
37
+ migration_report (MigrationReport): Report for tracking operations.
38
+ deactivate035_from001 (bool): Whether to deactivate 035 fields derived from 001.
39
+ """
25
40
  self.unique_001s: Set[str] = set()
26
41
  self.deactivate035_from001: bool = deactivate035_from001
27
42
  self.hrid_path = "/hrid-settings-storage/hrid-settings"
@@ -45,7 +60,7 @@ class HRIDHandler:
45
60
  marc_record: Record,
46
61
  legacy_ids: list[str],
47
62
  ) -> None:
48
- """Create HRID if not mapped. Add hrid as MARC record 001
63
+ """Create HRID if not mapped. Add hrid as MARC record 001.
49
64
 
50
65
  Args:
51
66
  namespace (FOLIONamespaces): determening the type of hrid setting to update
@@ -1,3 +1,10 @@
1
+ """MARC file processing orchestration.
2
+
3
+ Orchestrates the processing of MARC records through the transformation pipeline.
4
+ Handles record reading, validation, transformation via rules mappers, and output
5
+ writing. Manages error handling, progress reporting, and batch processing.
6
+ """
7
+
1
8
  import logging
2
9
  import os
3
10
  import sys
@@ -29,6 +36,13 @@ class MarcFileProcessor:
29
36
  folder_structure: FolderStructure,
30
37
  created_objects_file: TextIO,
31
38
  ):
39
+ """Initialize MARC file processor for processing MARC records.
40
+
41
+ Args:
42
+ mapper (RulesMapperBase): MARC rules mapper for transformations.
43
+ folder_structure (FolderStructure): Folder structure for file paths.
44
+ created_objects_file (TextIO): File handle for writing created objects.
45
+ """
32
46
  self.object_type: FOLIONamespaces = folder_structure.object_type
33
47
  self.folder_structure: FolderStructure = folder_structure
34
48
  self.mapper: RulesMapperBase = mapper
@@ -51,7 +65,7 @@ class MarcFileProcessor:
51
65
  self.parent_hrids = {entity[1]: entity[2] for entity in mapper.parent_id_map.values()}
52
66
 
53
67
  def process_record(self, idx: int, marc_record: Record, file_def: FileDefinition):
54
- """processes a marc holdings record and saves it
68
+ """Processes a marc holdings record and saves it.
55
69
 
56
70
  Args:
57
71
  idx (int): Index in file being parsed
@@ -1,3 +1,10 @@
1
+ """MARC record reader wrapper.
2
+
3
+ Provides a wrapper around pymarc's MARCReader with enhanced error handling,
4
+ encoding detection, and record validation. Supports multiple MARC file formats
5
+ and handles corrupted records gracefully.
6
+ """
7
+
1
8
  import logging
2
9
  import sys
3
10
  from io import IOBase