diff --git a/app/pipeline/mapping.py b/app/pipeline/mapping.py index c4b4567..e21e1a9 100644 --- a/app/pipeline/mapping.py +++ b/app/pipeline/mapping.py @@ -41,6 +41,7 @@ from .column_constants import ( COL_RESIDENT_SIGN, COL_STAY_DOCUMENT_TYPE, COL_TRANSFER_TYPE, + COL_UNUSUAL_CODES, EMPLOYEE_ABSENT_CODE, EXPORT_SUBSIDIARY_COMMENT_CODES, PARTICIPANT_ADDRESS_COMPONENT_COLUMNS, @@ -855,6 +856,7 @@ def _apply_business_rules( # которые обнуляли колонку, если код операции, вид перевода или тип # участника не входил в разрешённый список, убраны — они выбрасывали # данные, реально присутствующие в файле. + _rule_code_list_separator(row) _rule_extra_info(row, codes, operation_lookup, participant_lookup) _rule_payer_account(row, transfer_type, codes) _rule_correspondent_accounts(row, operator_type, transfer_type, codes) @@ -870,6 +872,23 @@ def _apply_business_rules( _clear_columns(row, BLOCK_CP) +# Перечисления кодов эталонный отчёт АРМ «Комита» печатает через запятую без +# пробела ("1101,1106,1499"), а парсер склеивает повторяющиеся теги через +# "; " (см. _append_value в parser.py). Приводим к виду эталона только +# колонки-перечисления кодов: в текстовых полях "; " читается лучше. +_CODE_LIST_COLUMNS = (COL_EXTRA_CODES, COL_UNUSUAL_CODES) +_CODE_LIST_SEPARATOR = "," + + +def _rule_code_list_separator(row: dict[int, str]) -> None: + for column in _CODE_LIST_COLUMNS: + value = _get(row, column) + if "; " not in value: + continue + codes = [part.strip() for part in value.split(";") if part.strip()] + _set(row, column, _CODE_LIST_SEPARATOR.join(codes)) + + def _rule_extra_info( row: dict[int, str], codes: set[str], diff --git a/tests/unit/test_mapping.py b/tests/unit/test_mapping.py index b988c42..e4a4228 100644 --- a/tests/unit/test_mapping.py +++ b/tests/unit/test_mapping.py @@ -1968,3 +1968,33 @@ def test_col96_territory_code_card_belongs_to_foreign_card_group() -> None: groups = COLUMNS.report_groups() foreign_card_group = next(g for g in groups if g.start_index <= 97 <= g.end_index) assert foreign_card_group.start_index == 96 + + +def test_code_list_columns_use_reference_separator() -> None: + """Перечисления кодов должны совпадать с эталонным отчётом АРМ «Комита» + дословно: он печатает их через запятую без пробела, а парсер склеивает + повторяющиеся теги через "; " (см. _append_value в parser.py). На сверке + за 30.01.2023 это давало расхождение в 336 записях из 5266.""" + row = build_fixed_row_by_index( + file_name="f.xml", + record_id="R1", + operation_index=1, + operation_fields={ + "ДопКодОперации": "1; 2", + "ПризнНеобОперации": "1101; 1106; 1499", + }, + participant_fields={}, + ) + assert row[20] == "1,2" + assert row[21] == "1101,1106,1499" + + +def test_code_list_with_single_value_is_untouched() -> None: + row = build_fixed_row_by_index( + file_name="f.xml", + record_id="R1", + operation_index=1, + operation_fields={"ПризнНеобОперации": "1101"}, + participant_fields={}, + ) + assert row[21] == "1101"