This commit is contained in:
Raykov-MS 2026-08-25 17:17:05 +03:00
parent fb83c8c805
commit 7beeb710ce
4 changed files with 70 additions and 10 deletions

View File

@ -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)

View File

@ -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<index>\d+)\])?\."
r"(?P<field>КодДок|ИноеНаимДок|ДатаДок|НомДок|СодДок)$"
)
_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(

View File

@ -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,

View File

@ -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: