From 7beeb710ce4bef74ba5caafd1ced6776348e32e6 Mon Sep 17 00:00:00 2001 From: Raykov-MS Date: Tue, 25 Aug 2026 17:17:05 +0300 Subject: [PATCH] fix --- app/pipeline/column_constants.py | 1 + app/pipeline/mapping.py | 37 ++++++++++++++++++++++++++++++-- app/pipeline/mapping_table.json | 8 +++---- tests/unit/test_mapping.py | 34 +++++++++++++++++++++++++---- 4 files changed, 70 insertions(+), 10 deletions(-) diff --git a/app/pipeline/column_constants.py b/app/pipeline/column_constants.py index 9271b04..28d4998 100644 --- a/app/pipeline/column_constants.py +++ b/app/pipeline/column_constants.py @@ -72,6 +72,7 @@ COL_EIO_ADDRESS_ONE_LINE = _index(167) # ЕИО и ценные бумаги. COL_EIO_INN = _index(163) +COL_EIO_OTHER_INFO = _index(164) COL_EIO_REG_PLACE_ONE_LINE = _index(178) COL_EIO_REG_PLACE_STRUCTURED = _index(179) COL_CP_ISSUER_INN = _index(202) diff --git a/app/pipeline/mapping.py b/app/pipeline/mapping.py index 29639b8..585965e 100644 --- a/app/pipeline/mapping.py +++ b/app/pipeline/mapping.py @@ -22,6 +22,7 @@ from .column_constants import ( COL_CURRENCY, COL_EIO_ADDRESS_ONE_LINE, COL_EIO_INN, + COL_EIO_OTHER_INFO, COL_EIO_REG_PLACE_ONE_LINE, COL_EIO_REG_PLACE_STRUCTURED, COL_EMPLOYEE_SIGN, @@ -145,6 +146,15 @@ _OPERATION_DOCUMENT_FIELD = re.compile( r"(?:^|\.)ОснованиеОп(?:\[(?P\d+)\])?\." r"(?PКодДок|ИноеНаимДок|ДатаДок|НомДок|СодДок)$" ) +_EIO_PERSON_BASE_PATHS = ("УчастникЮЛ.СведЕИО.ФЛЕИО",) +_EIO_OTHER_INFO_FIELDS = ( + ("СНИЛС", "СНИЛСФЛ"), + ("ОМС", "ПолисНомер"), + ("Номер телефона", "ТелефонНомер"), + ("Дата рождения", "ДатаРождения"), + ("Тип ФЛ, занимающегося частной практикой", "ТипФЛЧастнаяПрактика"), + ("Регистрационный номер", "РегнНомер"), +) _EIO_BLOCK_NAMES = ( "СведЕИО", "БенефициарЮЛ", @@ -470,6 +480,11 @@ def build_fixed_row_by_index( COL_OPERATION_DOCUMENTS, _format_operation_documents(operation_lookup), ) + _set( + row, + COL_EIO_OTHER_INFO, + _format_eio_other_info(participant_eio_lookup), + ) if not is_continuation: _apply_participant_identity_rules(row, participant_lookup) # Сначала убираем запрещённые однострочные адреса, чтобы структурная @@ -671,8 +686,26 @@ def _format_operation_documents(lookup: _PayloadLookup) -> str: fields = [ document.get(field_name, "") for field_name in _OPERATION_DOCUMENT_FIELDS ] - formatted_documents.append(f"{position}. {', '.join(fields)}") - return "; ".join(formatted_documents) + fields.insert(1, "") + formatted_documents.append(f"{position}, {', '.join(fields)};") + return "\n".join(formatted_documents) + + +def _format_eio_other_info(lookup: _PayloadLookup) -> str: + values: list[tuple[str, str]] = [] + for label, field_name in _EIO_OTHER_INFO_FIELDS: + value = "" + for base_path in _EIO_PERSON_BASE_PATHS: + value = _lookup_pick_scoped_value(lookup, f"{base_path}.{field_name}") + if value: + break + values.append((label, value)) + + if not any(value for _, value in values): + return "" + lines = [f"{label}: {value}" for label, value in values] + lines.append("Дата регистрации: ") + return "\n".join(lines) def _apply_participant_identity_rules( diff --git a/app/pipeline/mapping_table.json b/app/pipeline/mapping_table.json index 2842685..ba8479a 100644 --- a/app/pipeline/mapping_table.json +++ b/app/pipeline/mapping_table.json @@ -3265,12 +3265,12 @@ "column_name": "Иные сведения ЕИО/Бенефициара", "block": "eio", "report_group": "eio", - "xml_tag": "СНИЛСФЛ|ПолисНомер|ТелефонНомер", - "xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/УчастникОП/УчастникЮЛ/СведЕИО/ФЛЕИО/СНИЛСФЛ | /СообщОперКО/ИнформЧасть/СведКО/Операция/УчастникОП/УчастникЮЛ/БенефициарЮЛ/ФЛБенефициар/СНИЛСФЛ | /СообщОперКО/ИнформЧасть/СведКО/Операция/УчастникОП/УчастникЮЛ/СведЕИО/ФЛЕИО/ПолисНомер | /СообщОперКО/ИнформЧасть/СведКО/Операция/УчастникОП/УчастникЮЛ/БенефициарЮЛ/ФЛБенефициар/ПолисНомер | /СообщОперКО/ИнформЧасть/СведКО/Операция/УчастникОП/УчастникЮЛ/СведЕИО/ФЛЕИО/ТелефонНомер | /СообщОперКО/ИнформЧасть/СведКО/Операция/УчастникОП/УчастникЮЛ/БенефициарЮЛ/ФЛБенефициар/ТелефонНомер", + "xml_tag": "СНИЛСФЛ|ПолисНомер|ТелефонНомер|ДатаРождения|ТипФЛЧастнаяПрактика|РегнНомер", + "xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/УчастникОП/УчастникЮЛ/СведЕИО/ФЛЕИО/СНИЛСФЛ | /СообщОперКО/ИнформЧасть/СведКО/Операция/УчастникОП/УчастникЮЛ/СведЕИО/ФЛЕИО/ПолисНомер | /СообщОперКО/ИнформЧасть/СведКО/Операция/УчастникОП/УчастникЮЛ/СведЕИО/ФЛЕИО/ТелефонНомер | /СообщОперКО/ИнформЧасть/СведКО/Операция/УчастникОП/УчастникЮЛ/СведЕИО/ФЛЕИО/ДатаРождения | /СообщОперКО/ИнформЧасть/СведКО/Операция/УчастникОП/УчастникЮЛ/СведЕИО/ФЛЕИО/ТипФЛЧастнаяПрактика | /СообщОперКО/ИнформЧасть/СведКО/Операция/УчастникОП/УчастникЮЛ/СведЕИО/ФЛЕИО/РегнНомер", "source_scope": "participant", "allow_short_lookup": false, - "allow_direct_mapping": true, - "structured_value": true, + "allow_direct_mapping": false, + "structured_value": false, "structured_group": "", "structured_role": "", "structured_order": 0, diff --git a/tests/unit/test_mapping.py b/tests/unit/test_mapping.py index 4a7760e..642be10 100644 --- a/tests/unit/test_mapping.py +++ b/tests/unit/test_mapping.py @@ -848,9 +848,9 @@ def test_operation_documents_keep_positions_and_join_multiple_documents() -> Non ) assert row[107] == ( - "1. 13, , 29/01/2026, 253, Размещение денежных средств; " - "2. 99, Депозитный договор, 29/01/2026, Р202307/0001/93/Э, ; " - "3. 99, Общие условия размещения депозитов, 17/11/2020, Р202307/0001, " + "1, 13, , , 29/01/2026, 253, Размещение денежных средств;\n" + "2, 99, , Депозитный договор, 29/01/2026, Р202307/0001/93/Э, ;\n" + "3, 99, , Общие условия размещения депозитов, 17/11/2020, Р202307/0001, ;" ) @@ -1128,10 +1128,36 @@ def test_eio_other_info_combines_snils_and_phone() -> None: participant_fields={ "УчастникЮЛ.СведЕИО.ФЛЕИО.СНИЛСФЛ": "123-456-789 00", "УчастникЮЛ.СведЕИО.ФЛЕИО.ТелефонНомер": "+7 999 123-45-67", + "УчастникЮЛ.СведЕИО.ФЛЕИО.ДатаРождения": "03/07/1984", + "УчастникЮЛ.СведЕИО.ФЛЕИО.ТипФЛЧастнаяПрактика": "2", + "УчастникЮЛ.СведЕИО.ФЛЕИО.РегнНомер": "77-12345", }, ) - assert row[164] == "123-456-789 00, +7 999 123-45-67" + assert row[164] == ( + "СНИЛС: 123-456-789 00\n" + "ОМС: \n" + "Номер телефона: +7 999 123-45-67\n" + "Дата рождения: 03/07/1984\n" + "Тип ФЛ, занимающегося частной практикой: 2\n" + "Регистрационный номер: 77-12345\n" + "Дата регистрации: " + ) + + +def test_eio_other_info_stays_empty_for_beneficiary_only_fields() -> None: + row = build_fixed_row_by_index( + file_name="f.xml", + record_id="R1", + operation_index=1, + operation_fields={}, + participant_fields={ + "УчастникЮЛ.БенефициарЮЛ.ФЛБенефициар.СНИЛСФЛ": "074-115-177 38", + "УчастникЮЛ.БенефициарЮЛ.ФЛБенефициар.ДатаРождения": "18/02/1981", + }, + ) + + assert row[164] == "" def test_participant_and_beneficiary_inn_are_scoped_regardless_of_field_order() -> None: