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.
Files changed (73) hide show
  1. folio_migration_tools/__init__.py +11 -0
  2. folio_migration_tools/__main__.py +169 -85
  3. folio_migration_tools/circulation_helper.py +96 -59
  4. folio_migration_tools/config_file_load.py +66 -0
  5. folio_migration_tools/custom_dict.py +6 -4
  6. folio_migration_tools/custom_exceptions.py +21 -19
  7. folio_migration_tools/extradata_writer.py +46 -0
  8. folio_migration_tools/folder_structure.py +63 -66
  9. folio_migration_tools/helper.py +29 -21
  10. folio_migration_tools/holdings_helper.py +57 -34
  11. folio_migration_tools/i18n_config.py +9 -0
  12. folio_migration_tools/library_configuration.py +173 -13
  13. folio_migration_tools/mapper_base.py +317 -106
  14. folio_migration_tools/mapping_file_transformation/courses_mapper.py +203 -0
  15. folio_migration_tools/mapping_file_transformation/holdings_mapper.py +83 -69
  16. folio_migration_tools/mapping_file_transformation/item_mapper.py +98 -94
  17. folio_migration_tools/mapping_file_transformation/manual_fee_fines_mapper.py +352 -0
  18. folio_migration_tools/mapping_file_transformation/mapping_file_mapper_base.py +702 -223
  19. folio_migration_tools/mapping_file_transformation/notes_mapper.py +90 -0
  20. folio_migration_tools/mapping_file_transformation/order_mapper.py +492 -0
  21. folio_migration_tools/mapping_file_transformation/organization_mapper.py +389 -0
  22. folio_migration_tools/mapping_file_transformation/ref_data_mapping.py +38 -27
  23. folio_migration_tools/mapping_file_transformation/user_mapper.py +149 -361
  24. folio_migration_tools/marc_rules_transformation/conditions.py +650 -246
  25. folio_migration_tools/marc_rules_transformation/holdings_statementsparser.py +292 -130
  26. folio_migration_tools/marc_rules_transformation/hrid_handler.py +244 -0
  27. folio_migration_tools/marc_rules_transformation/loc_language_codes.xml +20846 -0
  28. folio_migration_tools/marc_rules_transformation/marc_file_processor.py +300 -0
  29. folio_migration_tools/marc_rules_transformation/marc_reader_wrapper.py +136 -0
  30. folio_migration_tools/marc_rules_transformation/rules_mapper_authorities.py +241 -0
  31. folio_migration_tools/marc_rules_transformation/rules_mapper_base.py +681 -201
  32. folio_migration_tools/marc_rules_transformation/rules_mapper_bibs.py +395 -429
  33. folio_migration_tools/marc_rules_transformation/rules_mapper_holdings.py +531 -100
  34. folio_migration_tools/migration_report.py +85 -38
  35. folio_migration_tools/migration_tasks/__init__.py +1 -3
  36. folio_migration_tools/migration_tasks/authority_transformer.py +119 -0
  37. folio_migration_tools/migration_tasks/batch_poster.py +911 -198
  38. folio_migration_tools/migration_tasks/bibs_transformer.py +121 -116
  39. folio_migration_tools/migration_tasks/courses_migrator.py +192 -0
  40. folio_migration_tools/migration_tasks/holdings_csv_transformer.py +252 -247
  41. folio_migration_tools/migration_tasks/holdings_marc_transformer.py +321 -115
  42. folio_migration_tools/migration_tasks/items_transformer.py +264 -84
  43. folio_migration_tools/migration_tasks/loans_migrator.py +506 -195
  44. folio_migration_tools/migration_tasks/manual_fee_fines_transformer.py +187 -0
  45. folio_migration_tools/migration_tasks/migration_task_base.py +364 -74
  46. folio_migration_tools/migration_tasks/orders_transformer.py +373 -0
  47. folio_migration_tools/migration_tasks/organization_transformer.py +451 -0
  48. folio_migration_tools/migration_tasks/requests_migrator.py +130 -62
  49. folio_migration_tools/migration_tasks/reserves_migrator.py +253 -0
  50. folio_migration_tools/migration_tasks/user_transformer.py +180 -139
  51. folio_migration_tools/task_configuration.py +46 -0
  52. folio_migration_tools/test_infrastructure/__init__.py +0 -0
  53. folio_migration_tools/test_infrastructure/mocked_classes.py +406 -0
  54. folio_migration_tools/transaction_migration/legacy_loan.py +148 -34
  55. folio_migration_tools/transaction_migration/legacy_request.py +65 -25
  56. folio_migration_tools/transaction_migration/legacy_reserve.py +47 -0
  57. folio_migration_tools/transaction_migration/transaction_result.py +12 -1
  58. folio_migration_tools/translations/en.json +476 -0
  59. folio_migration_tools-1.9.10.dist-info/METADATA +169 -0
  60. folio_migration_tools-1.9.10.dist-info/RECORD +67 -0
  61. {folio_migration_tools-1.2.1.dist-info → folio_migration_tools-1.9.10.dist-info}/WHEEL +1 -2
  62. folio_migration_tools-1.9.10.dist-info/entry_points.txt +3 -0
  63. folio_migration_tools/generate_schemas.py +0 -46
  64. folio_migration_tools/mapping_file_transformation/mapping_file_mapping_base_impl.py +0 -44
  65. folio_migration_tools/mapping_file_transformation/user_mapper_base.py +0 -212
  66. folio_migration_tools/marc_rules_transformation/bibs_processor.py +0 -163
  67. folio_migration_tools/marc_rules_transformation/holdings_processor.py +0 -284
  68. folio_migration_tools/report_blurbs.py +0 -219
  69. folio_migration_tools/transaction_migration/legacy_fee_fine.py +0 -36
  70. folio_migration_tools-1.2.1.dist-info/METADATA +0 -134
  71. folio_migration_tools-1.2.1.dist-info/RECORD +0 -50
  72. folio_migration_tools-1.2.1.dist-info/top_level.txt +0 -1
  73. {folio_migration_tools-1.2.1.dist-info → folio_migration_tools-1.9.10.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,187 @@
1
+ import csv
2
+ import json
3
+ import logging
4
+ import sys
5
+ import time
6
+ import traceback
7
+ from typing import List, Optional
8
+
9
+ import i18n
10
+ from folio_uuid.folio_namespaces import FOLIONamespaces
11
+
12
+ from folio_migration_tools.custom_exceptions import (
13
+ TransformationFieldMappingError,
14
+ TransformationProcessError,
15
+ TransformationRecordFailedError,
16
+ )
17
+ from folio_migration_tools.helper import Helper
18
+ from folio_migration_tools.library_configuration import (
19
+ FileDefinition,
20
+ LibraryConfiguration,
21
+ )
22
+ from folio_migration_tools.mapping_file_transformation.manual_fee_fines_mapper import (
23
+ ManualFeeFinesMapper,
24
+ )
25
+ from folio_migration_tools.mapping_file_transformation.mapping_file_mapper_base import (
26
+ MappingFileMapperBase,
27
+ )
28
+ from folio_migration_tools.migration_tasks.migration_task_base import MigrationTaskBase
29
+ from folio_migration_tools.task_configuration import AbstractTaskConfiguration
30
+
31
+
32
+ class ManualFeeFinesTransformer(MigrationTaskBase):
33
+ class TaskConfiguration(AbstractTaskConfiguration):
34
+ name: str
35
+ feefines_map: str
36
+ migration_task_type: str
37
+ files: List[FileDefinition]
38
+ feefines_owner_map: Optional[str]
39
+ feefines_type_map: Optional[str]
40
+ service_point_map: Optional[str]
41
+
42
+ @staticmethod
43
+ def get_object_type() -> FOLIONamespaces:
44
+ return FOLIONamespaces.fees_fines
45
+
46
+ def __init__(
47
+ self,
48
+ task_configuration: TaskConfiguration,
49
+ library_config: LibraryConfiguration,
50
+ folio_client,
51
+ use_logging: bool = True,
52
+ ):
53
+ csv.register_dialect("tsv", delimiter="\t")
54
+
55
+ super().__init__(library_config, task_configuration, folio_client, use_logging)
56
+ self.object_type_name = self.get_object_type().name
57
+ self.task_configuration = task_configuration
58
+ self.check_source_files(
59
+ self.folder_structure.legacy_records_folder, self.task_configuration.files
60
+ )
61
+ self.total_records = 0
62
+ self.feefines_map = self.setup_records_map(
63
+ self.folder_structure.mapping_files_folder / self.task_configuration.feefines_map
64
+ )
65
+ self.results_path = self.folder_structure.created_objects_path
66
+ self.failed_files: List[str] = []
67
+
68
+ self.folio_keys = []
69
+ self.folio_keys = MappingFileMapperBase.get_mapped_folio_properties_from_map(
70
+ self.feefines_map
71
+ )
72
+
73
+ self.mapper = ManualFeeFinesMapper(
74
+ self.folio_client,
75
+ self.library_configuration,
76
+ self.task_configuration,
77
+ self.feefines_map,
78
+ feefines_owner_map=self.load_ref_data_mapping_file(
79
+ "account.ownerId",
80
+ self.folder_structure.mapping_files_folder
81
+ / self.task_configuration.feefines_owner_map,
82
+ self.folio_keys,
83
+ False,
84
+ ),
85
+ feefines_type_map=self.load_ref_data_mapping_file(
86
+ "account.feeFineId",
87
+ self.folder_structure.mapping_files_folder
88
+ / self.task_configuration.feefines_type_map,
89
+ self.folio_keys,
90
+ False,
91
+ ),
92
+ service_point_map=self.load_ref_data_mapping_file(
93
+ "feefineaction.createdAt",
94
+ self.folder_structure.mapping_files_folder
95
+ / self.task_configuration.service_point_map,
96
+ self.folio_keys,
97
+ False,
98
+ ),
99
+ ignore_legacy_identifier=True,
100
+ )
101
+
102
+ def do_work(self):
103
+ logging.info("Getting started!")
104
+ for file in self.task_configuration.files:
105
+ logging.info("Processing %s", file)
106
+ try:
107
+ self.process_single_file(file)
108
+ except Exception as ee:
109
+ error_str = (
110
+ f"Processing of {file} failed:\n{ee}."
111
+ "Check source files for empty rows or missing reference data"
112
+ )
113
+ logging.exception(error_str)
114
+ self.mapper.migration_report.add("FailedFiles", f"{file} - {ee}")
115
+ sys.exit()
116
+
117
+ def process_single_file(self, file_def: FileDefinition):
118
+ full_path = self.folder_structure.legacy_records_folder / file_def.file_name
119
+ with open(full_path, encoding="utf-8-sig") as records_file:
120
+ self.mapper.migration_report.add_general_statistics(
121
+ i18n.t("Number of files processed")
122
+ )
123
+ start = time.time()
124
+
125
+ for idx, record in enumerate(self.mapper.get_objects(records_file, full_path)):
126
+ try:
127
+ if idx == 0:
128
+ logging.info("First legacy record:")
129
+ logging.info(json.dumps(record, indent=4))
130
+
131
+ self.mapper.report_legacy_mapping_no_schema(record)
132
+
133
+ composite_feefine, legacy_id = self.mapper.do_map(
134
+ record, f"Row {idx + 1}", FOLIONamespaces.fees_fines
135
+ )
136
+
137
+ self.mapper.perform_additional_mapping(legacy_id, composite_feefine, record)
138
+
139
+ self.mapper.report_folio_mapping(
140
+ composite_feefine, self.mapper.composite_feefine_schema
141
+ )
142
+
143
+ self.mapper.store_objects(composite_feefine)
144
+
145
+ if idx == 0:
146
+ logging.info("First FOLIO record:")
147
+ logging.info(json.dumps(composite_feefine, indent=4))
148
+
149
+ except TransformationProcessError as process_error:
150
+ self.mapper.handle_transformation_process_error(idx, process_error)
151
+ except TransformationRecordFailedError as data_error:
152
+ self.mapper.handle_transformation_record_failed_error(idx, data_error)
153
+ except TransformationFieldMappingError as mapping_error:
154
+ self.mapper.handle_transformation_field_mapping_error(idx, mapping_error)
155
+
156
+ except AttributeError as attribute_error:
157
+ traceback.print_exc()
158
+ logging.fatal(attribute_error)
159
+ logging.info("Quitting...")
160
+ sys.exit(1)
161
+ except Exception as exception:
162
+ self.mapper.handle_generic_exception(idx, exception)
163
+
164
+ self.print_progress(idx, start)
165
+
166
+ def wrap_up(self):
167
+ logging.info("Done. Transformer wrapping up...")
168
+ self.extradata_writer.flush()
169
+ with open(self.folder_structure.migration_reports_file, "w") as migration_report_file:
170
+ logging.info(
171
+ "Writing migration- and mapping report to %s",
172
+ self.folder_structure.migration_reports_file,
173
+ )
174
+ self.mapper.migration_report.write_migration_report(
175
+ i18n.t("Manual fee/fine transformation report"),
176
+ migration_report_file,
177
+ self.start_datetime,
178
+ )
179
+
180
+ Helper.print_mapping_report(
181
+ migration_report_file,
182
+ self.total_records,
183
+ self.mapper.mapped_folio_fields,
184
+ self.mapper.mapped_legacy_fields,
185
+ )
186
+
187
+ self.clean_out_empty_logs()