946 lines
35 KiB
Python
946 lines
35 KiB
Python
from __future__ import annotations
|
||
|
||
from app.pipeline.mapping import (
|
||
FIXED_REPORT_COLUMNS,
|
||
_extract_tag_candidate_keys,
|
||
build_fixed_row,
|
||
build_fixed_row_by_index,
|
||
)
|
||
|
||
|
||
def _column_with(prefix: str) -> str:
|
||
for column in FIXED_REPORT_COLUMNS:
|
||
if column.startswith(prefix):
|
||
return column
|
||
raise AssertionError(f"Колонка с префиксом '{prefix}' не найдена")
|
||
|
||
|
||
def test_build_fixed_row_maps_known_fields() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=2,
|
||
operation_fields={
|
||
"ИдФайл": "FILE_01",
|
||
"НомерОперация": "OP_2",
|
||
"КодОперации": "5007",
|
||
"СумОперации": "100.55",
|
||
},
|
||
participant_fields={
|
||
"ИННФЛ": "123456789012",
|
||
"Тип": "01",
|
||
},
|
||
)
|
||
|
||
assert row["Имя XML файла"] == "f.xml"
|
||
assert row["Идентификатор записи"] == "R1"
|
||
assert row["Уникальный номер операции"] == "OP_2"
|
||
assert row["Код вида операции"] == "5007"
|
||
assert row["Сумма в валюте проведения"] == "100.55"
|
||
assert row[_column_with("ИНН")] == "123456789012"
|
||
assert row["Тип участника"] == "01"
|
||
|
||
|
||
def test_build_fixed_row_keeps_missing_values_empty() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={},
|
||
)
|
||
for column in FIXED_REPORT_COLUMNS:
|
||
assert column in row
|
||
assert row["Код вида операции"] == ""
|
||
assert row[_column_with("ИНН")] == ""
|
||
|
||
|
||
def test_build_fixed_row_does_not_take_operation_inn_for_participant() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"ИНН": "0000000000",
|
||
"Тип": "99",
|
||
},
|
||
participant_fields={
|
||
"ИННФЛ": "111111111111",
|
||
"Тип": "01",
|
||
},
|
||
)
|
||
assert row[_column_with("ИНН")] == "111111111111"
|
||
assert row["Тип участника"] == "01"
|
||
|
||
|
||
def test_fixed_report_columns_over_200() -> None:
|
||
assert len(FIXED_REPORT_COLUMNS) == 204
|
||
assert FIXED_REPORT_COLUMNS[126] == "Признак принадлежности к публичным лицам"
|
||
|
||
|
||
def test_build_fixed_row_uses_alternative_path_leaf_for_emitent_name() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"СведЦП.Эмитент.НаимЭмитентЦП.ФизЛицо.ФИОСтрока": "Эмитент ФЛ",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert row["Наименование/ ФИО эмитента ЦП"] == "Эмитент ФЛ"
|
||
|
||
|
||
def test_build_fixed_row_maps_dotted_participant_keys() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"УчастникФЛИП.СведФЛИП.ИННФЛИП": "123456789012",
|
||
"УчастникФЛИП.СведФЛИП.СведДокУдЛичн.НомДок": "451099",
|
||
},
|
||
)
|
||
assert row[_column_with("ИНН")] == "123456789012"
|
||
assert row["Номер"] == "451099"
|
||
|
||
|
||
def test_build_fixed_row_splits_pipe_separated_xml_tag_values() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"Индекс": "674500",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert row["Адрес по структуре (целый)"] == "674500"
|
||
|
||
|
||
def test_extract_tag_candidate_keys_supports_comma_separator() -> None:
|
||
candidates = _extract_tag_candidate_keys(
|
||
"КППЮЛ, ИдентификацияФЛ, ПризнакОргФормаИНБОЮЛ"
|
||
)
|
||
assert candidates == ("КППЮЛ", "ИдентификацияФЛ", "ПризнакОргФормаИНБОЮЛ")
|
||
|
||
|
||
def test_build_fixed_row_uses_first_suffix_value_from_index() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"УчастникФЛИП.Первый.ИННФЛИП": "111111111111",
|
||
"УчастникФЛИП.Второй.ИННФЛИП": "222222222222",
|
||
},
|
||
)
|
||
assert row[_column_with("ИНН")] == "111111111111"
|
||
|
||
|
||
def test_build_fixed_row_skips_empty_suffix_values_in_index() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"УчастникФЛИП.Первый.ИННФЛИП": "",
|
||
"УчастникФЛИП.Второй.ИННФЛИП": "222222222222",
|
||
},
|
||
)
|
||
assert row[_column_with("ИНН")] == "222222222222"
|
||
|
||
|
||
def test_structured_address_is_built_from_right_columns() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"Индекс": "674500",
|
||
"КодОКСМ": "643",
|
||
"Пункт": "Москва",
|
||
"Улица": "Тверская",
|
||
"Дом": "1",
|
||
},
|
||
)
|
||
assert row["Адрес по структуре (целый)"] == "674500, 643, Москва, Тверская, 1"
|
||
|
||
|
||
def test_one_line_address_clears_structured_and_component_columns() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"АдресСтрока": "г. Москва, Тверская, 1",
|
||
"Индекс": "674500",
|
||
"КодОКСМ": "643",
|
||
"Улица": "Тверская",
|
||
"Дом": "1",
|
||
},
|
||
)
|
||
assert row["Адрес в одной строке"] == "г. Москва, Тверская, 1"
|
||
assert row["Адрес по структуре (целый)"] == ""
|
||
assert row["Индекс"] == ""
|
||
assert row["Код страны"] == ""
|
||
assert row["Улица"] == ""
|
||
assert row["Дом"] == ""
|
||
|
||
|
||
def test_fio_columns_prefer_participant_fields_over_operation_common_fields() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"Фам": "Кузнецов",
|
||
"Имя": "Сергей",
|
||
"Отч": "Владимирович",
|
||
},
|
||
participant_fields={
|
||
"УчастникФЛИП.СведФЛИП.ФИОФЛИП.Фам": "Азимов",
|
||
"УчастникФЛИП.СведФЛИП.ФИОФЛИП.Имя": "Ислом",
|
||
"УчастникФЛИП.СведФЛИП.ФИОФЛИП.Отч": "Каримович",
|
||
},
|
||
)
|
||
assert row["Фамилия"] == "Азимов"
|
||
assert row["Имя"] == "Ислом"
|
||
assert row["Отчество"] == "Каримович"
|
||
assert row["ФИО (по структуре полностью)"] == "Азимов Ислом Каримович"
|
||
|
||
|
||
def test_one_line_fio_clears_structured_and_component_fio_columns() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"ФИОСтрока": "Азимов Ислом Каримович",
|
||
"Фам": "Азимов",
|
||
"Имя": "Ислом",
|
||
"Отч": "Каримович",
|
||
},
|
||
)
|
||
assert row["ФИО (в одной строке)"] == "Азимов Ислом Каримович"
|
||
assert row["ФИО (по структуре полностью)"] == ""
|
||
assert row["Фамилия"] == ""
|
||
assert row["Имя"] == ""
|
||
assert row["Отчество"] == ""
|
||
assert row["Наименование ЮЛ/ФИО ( по структуре полный)"] == ""
|
||
|
||
|
||
def test_structured_column_is_not_filled_directly_from_single_line_tag() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"АдресСтрока": "г. Москва, ул. Пример, д. 1",
|
||
},
|
||
)
|
||
assert row["Адрес в одной строке"] == "г. Москва, ул. Пример, д. 1"
|
||
assert (
|
||
row[
|
||
"Адрес ЮЛ/ Адрес места жительства (места нахождения) "
|
||
"ЕИО/Бенефициара (по структуре полный)"
|
||
]
|
||
== ""
|
||
)
|
||
|
||
|
||
def test_structured_column_without_component_block_joins_candidate_values() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"УчастникЮЛ.СведЕИО.ЮЛЕИО.АдрРег.Индекс": "121467",
|
||
"УчастникЮЛ.СведЕИО.ЮЛЕИО.АдрРег.КодОКСМ": "643",
|
||
"УчастникЮЛ.СведЕИО.ЮЛЕИО.АдрРег.Пункт": "Москва",
|
||
"УчастникЮЛ.СведЕИО.ЮЛЕИО.АдрРег.Улица": "Молодогвардейская",
|
||
"УчастникЮЛ.СведЕИО.ЮЛЕИО.АдрРег.Дом": "8",
|
||
"УчастникЮЛ.СведЕИО.ЮЛЕИО.АдрРег.Корп": "1",
|
||
"УчастникЮЛ.СведЕИО.ЮЛЕИО.АдрРег.Оф": "28",
|
||
},
|
||
)
|
||
assert (
|
||
row["Место государственной регистрации ЕИО/Бенефициара (структура полностью)"]
|
||
== "121467, 643, Москва, Молодогвардейская, 8, 1, 28"
|
||
)
|
||
|
||
|
||
def test_structured_column_uses_non_one_line_candidate_when_mixed_tags() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"УчастникЮЛ.БенефициарЮЛ.ФЛБенефициар.АдрРег.АдрУчредитель": (
|
||
"г. Москва, ул. Пушкина, д. 1"
|
||
),
|
||
},
|
||
)
|
||
assert row["Адрес в одной строке"] == ""
|
||
assert (
|
||
row[
|
||
"Адрес ЮЛ/ Адрес места жительства (места нахождения) "
|
||
"ЕИО/Бенефициара (по структуре полный)"
|
||
]
|
||
== "г. Москва, ул. Пушкина, д. 1"
|
||
)
|
||
|
||
|
||
def test_digital_rights_operation_clears_currency_amount_fields() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"КодПризнОперации": "8",
|
||
"КодВал": "643",
|
||
"СумОперации": "100.00",
|
||
"СумРуб": "100.00",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert row["Валюта"] == ""
|
||
assert row["Сумма в валюте проведения"] == ""
|
||
assert row["Сумма в рубл. эквиваленте"] == ""
|
||
|
||
|
||
def test_abnormal_operation_codes_only_for_6001() -> None:
|
||
row_without_6001 = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"КодОперации": "5007",
|
||
"ПризнНеобОперации": "1101",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert row_without_6001["Коды призн. необычной операции"] == ""
|
||
|
||
row_with_6001 = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"КодОперации": "6001",
|
||
"ПризнНеобОперации": "1101",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert row_with_6001["Коды призн. необычной операции"] == "1101"
|
||
|
||
|
||
def test_transfer_accounts_get_placeholder_when_required() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"ВидПереводДС": "1",
|
||
"ТипОператорДС": "4",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert row["Номер счета плательщика"] == "00000000000000000000"
|
||
assert row["Номер счета банка плательщика"] == "00000000000000000000"
|
||
assert row["Номер счета банка получателя"] == "00000000000000000000"
|
||
assert row["Номер счета получателя"] == "00000000000000000000"
|
||
|
||
|
||
def test_operator_type_conditions_clear_irrelevant_bank_fields() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"ТипОператорДС": "3",
|
||
"НаимКО": "Банк плательщика",
|
||
"СведБанкПолучатель.НаимКО": "Банк получателя",
|
||
"СведБанкПолучатель.БИККО": "044525225",
|
||
"СчетБанкПлательщик": "30101810000000000001",
|
||
"СчетБанкПолучатель": "30101810000000000002",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert row["Наименование банка плательщика"] == ""
|
||
assert row["Наименование банка получателя"] == ""
|
||
assert row["БИК банка получателя"] == ""
|
||
assert row["Номер счета банка плательщика"] == ""
|
||
assert row["Номер счета банка получателя"] == ""
|
||
|
||
|
||
def test_col96_territory_code_cleared_when_operation_is_not_5016() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"КодОперации": "5007",
|
||
"КодТерИнГос": "840",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert row["Код территории"] == ""
|
||
|
||
|
||
def test_col103_and_105_fill_info_absent_when_no_employee_and_empty() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"ПризнакСотрудник": "0",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert row["Сведения о держателе платежной карты"] == "Информация отсутствует"
|
||
assert row["Наименование иностранного банка"] == "Информация отсутствует"
|
||
|
||
|
||
def test_col103_and_105_keep_original_values_when_present() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"ПризнакСотрудник": "0",
|
||
"СведДержательКарты": "Иванов И.И.",
|
||
"НаимИнБанк": "FOREIGN BANK",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert row["Сведения о держателе платежной карты"] == "Иванов И.И."
|
||
assert row["Наименование иностранного банка"] == "FOREIGN BANK"
|
||
|
||
|
||
def test_patronymic_supports_typo_tag_ocht() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"УчастникФЛИП.СведФЛИП.ФИОФЛИП.Фам": "Азимов",
|
||
"УчастникФЛИП.СведФЛИП.ФИОФЛИП.Имя": "Ислом",
|
||
"УчастникФЛИП.СведФЛИП.ФИОФЛИП.Очт": "Каримович",
|
||
},
|
||
)
|
||
assert row["Отчество"] == "Каримович"
|
||
|
||
|
||
def test_col124_cleared_for_physical_person_and_ip() -> None:
|
||
row_fl = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={"ТипФЛЧастнаяПрактика": "1"},
|
||
participant_fields={"ТипУчастника": "2"},
|
||
)
|
||
assert row_fl["Признак филиала: / Тип ФЛЧП"] == ""
|
||
|
||
row_ip = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={"ТипФЛЧастнаяПрактика": "1"},
|
||
participant_fields={"ТипУчастника": "3"},
|
||
)
|
||
assert row_ip["Признак филиала: / Тип ФЛЧП"] == ""
|
||
|
||
|
||
def test_col125_snils_cleared_for_ip() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={"ТипУчастника": "3", "СНИЛСФЛ": "123-456-789 00"},
|
||
)
|
||
assert row["ОМС/СНИЛС/Номер телефона"] == ""
|
||
|
||
|
||
def test_one_line_address_columns_cleared_when_participant_is_resident_client() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"ПризнУчастника": "1",
|
||
"ПризнКлиент": "1",
|
||
"АдресСтрока": "г. Москва, ул. Тестовая, д. 1",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert row["Адрес в одной строке"] == ""
|
||
assert row["Место государственной регистрации ( в одной строке)"] == ""
|
||
assert (
|
||
row["Место государственной регистрации ЕИО/Бенефициара (одной строкой)"] == ""
|
||
)
|
||
|
||
|
||
def test_okato_cleared_when_country_code_is_not_russia() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"КодОКСМ": "840",
|
||
"КодСубъектаПоОКАТО": "45",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert row["Код ОКАТО"] == ""
|
||
assert row["ОКАТО"] == ""
|
||
|
||
|
||
def test_col163_ogrn_eio_benef_cleared_for_physical_person() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={"ОГРНИП": "123456789012345"},
|
||
participant_fields={"ТипУчастника": "2"},
|
||
)
|
||
assert row["ОГРН ЕИО/Бенефициара"] == ""
|
||
|
||
|
||
def test_dul_sign_for_legal_entity_does_not_use_operation_doc_fields() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={"ДокУдЛичн": "451099", "ТипУчастника": "1"},
|
||
participant_fields={},
|
||
)
|
||
assert row["Признак ДУЛ"] == ""
|
||
|
||
|
||
def test_dul_columns_128_134_keep_expected_positions() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"ВидДокКод": "21",
|
||
"СерияДок": "0104",
|
||
"НомДок": "476635",
|
||
"КемВыданДок": "ОВД",
|
||
"КодПодр": "222-022",
|
||
"ДатВыдачиДок": "23/08/2005",
|
||
"ДокУдЛичн": "1",
|
||
},
|
||
)
|
||
assert row["ДУЛ (структура полностью)"] == "1, 21, 0104, 476635, ОВД, 222-022"
|
||
assert row["Признак ДУЛ"] == "1"
|
||
assert row["Код вида документа/Наименование"] == "21"
|
||
assert row["Серия"] == "0104"
|
||
assert row["Номер"] == "476635"
|
||
assert row["Орган, выдавший документ"] == "ОВД"
|
||
assert row["КП"] == "222-022"
|
||
|
||
|
||
def test_bank_bik_columns_use_transfer_bank_paths_instead_of_common_bikko() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"БИККО": "044525111",
|
||
"ТипОператорДС": "4",
|
||
"СвединияПереводыДС.СведБанкПлательщик.БИККО": "011012100",
|
||
"СвединияПереводыДС.СведБанкПолучатель.БИККО": "022202220",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert row["БИК банка плательщика"] == "011012100"
|
||
assert row["БИК банка получателя"] == "022202220"
|
||
|
||
|
||
def test_citizenship_country_code_uses_only_direct_svedflip_value() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"УчастникФЛИП.СведФЛИП.АдрРег.КодОКСМ": "643",
|
||
"УчастникФЛИП.СведФЛИП.КодОКСМ": "762",
|
||
},
|
||
)
|
||
assert row["Код страны гражданства"] == "762"
|
||
|
||
|
||
def test_citizenship_country_code_is_empty_when_only_address_code_exists() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={"УчастникФЛИП.СведФЛИП.АдрРег.КодОКСМ": "643"},
|
||
)
|
||
assert row["Код страны гражданства"] == ""
|
||
|
||
|
||
def test_okato_column_4_uses_branch_okatofl_and_not_bank_okatoko() -> None:
|
||
row = build_fixed_row(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"ОКАТОКО": "45",
|
||
"ОКАТОФл": "10",
|
||
"АдресСтрока": "г. Москва",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert FIXED_REPORT_COLUMNS[3] == "ОКАТО"
|
||
assert row["ОКАТО"] == "10"
|
||
|
||
|
||
def test_col9_uses_operation_number_from_xml() -> None:
|
||
row = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=7,
|
||
operation_fields={"НомерОперация": "ЦФТ-БАНК_1177326777530"},
|
||
participant_fields={},
|
||
)
|
||
assert row[9] == "ЦФТ-БАНК_1177326777530"
|
||
|
||
|
||
def test_structured_cash_address_does_not_include_bank_fields() -> None:
|
||
row = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"СведенияПереводыДс.СведПриемНалДС.АдрМестоПриемаВыдача.Индекс": "675520",
|
||
"СведенияПереводыДс.СведПриемНалДС.АдрМестоПриемаВыдача.КодОКСМ": "643",
|
||
"СведенияПереводыДс.СведПриемНалДС.АдрМестоПриемаВыдача.КодСубъектаПоОКАТО": "10",
|
||
"СведенияПереводыДс.СведПриемНалДС.АдрМестоПриемаВыдача.Пункт": "Чигири с",
|
||
"СведенияПереводыДс.СведПриемНалДС.АдрМестоПриемаВыдача.Улица": "Зеленая ул",
|
||
"СведенияПереводыДс.СведПриемНалДС.АдрМестоПриемаВыдача.Дом": "1",
|
||
"СведенияПереводыДс.СведПриемНалДС.БИККО": "044525111",
|
||
"СведенияПереводыДс.СведПриемНалДС.НаимКО": "АО РСХБ",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert row[50] == "675520, 643, 10, Чигири с, Зеленая ул, 1"
|
||
assert "044525111" not in row[50]
|
||
assert "АО РСХБ" not in row[50]
|
||
|
||
|
||
def test_participant_structured_address_stays_in_142_and_components_143_plus() -> None:
|
||
row = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"УчастникФЛИП.СведФЛИП.АдрРег.Индекс": "123456",
|
||
"УчастникФЛИП.СведФЛИП.АдрРег.КодОКСМ": "643",
|
||
"УчастникФЛИП.СведФЛИП.АдрРег.КодСубъектаПоОКАТО": "45",
|
||
"УчастникФЛИП.СведФЛИП.АдрРег.Пункт": "Москва",
|
||
"УчастникФЛИП.СведФЛИП.АдрРег.Улица": "Тверская",
|
||
"УчастникФЛИП.СведФЛИП.АдрРег.Дом": "1",
|
||
},
|
||
)
|
||
assert row[141] == ""
|
||
assert row[142] == "123456, 643, 45, Москва, Тверская, 1"
|
||
assert row[143] == "123456"
|
||
assert row[144] == "643"
|
||
|
||
|
||
def test_col153_uses_only_legal_entity_registration_address_components() -> None:
|
||
row = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={"КодОКСМ": "643", "Индекс": "999999"},
|
||
participant_fields={
|
||
"УчастникЮЛ.СведЮЛ.АдрРегЮЛ.Индекс": "675520",
|
||
"УчастникЮЛ.СведЮЛ.АдрРегЮЛ.КодОКСМ": "643",
|
||
"УчастникЮЛ.СведЮЛ.АдрРегЮЛ.КодСубъектаПоОКАТО": "10",
|
||
"УчастникЮЛ.СведЮЛ.АдрРегЮЛ.Район": "Благовещенский р-н",
|
||
"УчастникЮЛ.СведЮЛ.АдрРегЮЛ.Пункт": "Чигири с",
|
||
"УчастникЮЛ.СведЮЛ.АдрРегЮЛ.Улица": "Зеленая ул",
|
||
"УчастникЮЛ.СведЮЛ.АдрРегЮЛ.Дом": "1",
|
||
},
|
||
)
|
||
assert row[153] == "675520, 643, 10, Благовещенский р-н, Чигири с, Зеленая ул, 1"
|
||
|
||
|
||
def test_cash_columns_cleared_for_cashless_transfer_type_1() -> None:
|
||
row = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"ВидПереводДС": "1",
|
||
"КодОперации": "4006",
|
||
"БИККО": "044525111",
|
||
"СведенияПереводыДс.СведПриемНалДС.БИККО": "044525111",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
for index in (50, 61, 65, 76, 84, 95, 99, 101):
|
||
assert row[index] == ""
|
||
|
||
|
||
def test_col119_is_empty_for_legal_entity_and_uses_flip_identifier() -> None:
|
||
row_ul = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={"ТипУчастника": "1", "ИдентификацияФЛ": "1"},
|
||
)
|
||
assert row_ul[119] == ""
|
||
|
||
row_flip = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"ТипУчастника": "3",
|
||
"УчастникФЛИП.ИдентификацияФЛ": "1",
|
||
},
|
||
)
|
||
assert row_flip[119] == "1"
|
||
|
||
|
||
def test_physical_person_type_2_does_not_fill_cols_119_and_122() -> None:
|
||
row = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"СтатусУчастника": "3",
|
||
"ТипУчастника": "2",
|
||
"УчастникФЛИП.ИдентификацияФЛ": "1",
|
||
"УчастникФЛИП.СведФЛИП.ИННФЛИП": "410116812922",
|
||
},
|
||
)
|
||
assert row[119] == ""
|
||
assert row[120] == "410116812922"
|
||
assert row[122] == ""
|
||
|
||
|
||
def test_col123_uses_registration_date_for_legal_entity() -> None:
|
||
row = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"ТипУчастника": "1",
|
||
"УчастникЮЛ.СведЮЛ.ДатаРегЮЛ": "23/08/2005",
|
||
"УчастникФЛИП.СведФЛИП.ДатаРождения": "01/01/1990",
|
||
},
|
||
)
|
||
assert row[123] == "23/08/2005"
|
||
|
||
|
||
def test_eio_block_is_empty_when_eio_and_beneficiary_are_absent() -> None:
|
||
row = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"ТипУчастника": "1",
|
||
"УчастникЮЛ.СведЮЛ.ИННЮЛ": "2820000210",
|
||
"УчастникЮЛ.СведЮЛ.ОГРНЮЛ": "1022801198573",
|
||
"УчастникЮЛ.СведЮЛ.АдрРегЮЛ.КодСубъектаПоОКАТО": "45",
|
||
},
|
||
)
|
||
for index in (157, 162, 163, 168, 171):
|
||
assert row[index] == ""
|
||
|
||
|
||
def test_cp_block_is_empty_without_sved_cp_and_uses_emitent_inn_when_present() -> None:
|
||
row_without_cp = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={"ИННЮЛ": "2820000210"},
|
||
)
|
||
assert row_without_cp[202] == ""
|
||
|
||
row_with_cp = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={"СведЦП.Эмитент.ИННЭмитентЦП": "7707083893"},
|
||
participant_fields={"ИННЮЛ": "2820000210"},
|
||
)
|
||
assert row_with_cp[202] == "7707083893"
|
||
|
||
|
||
def test_currency_columns_apply_only_to_conversion_and_currency_operations() -> None:
|
||
non_conversion = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"КодОперации": "6001",
|
||
"СумКонверсия": "0.00",
|
||
"ПризнВалОперации": "VO",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert non_conversion[26] == ""
|
||
assert non_conversion[27] == ""
|
||
|
||
conversion = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R2",
|
||
operation_index=2,
|
||
operation_fields={
|
||
"КодОперации": "6101",
|
||
"КодВалКонверсия": "978",
|
||
"СумКонверсия": "100.50",
|
||
"ПризнВалОперации": "VO",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert conversion[26] == "100.50"
|
||
assert conversion[27] == "VO"
|
||
|
||
zero_conversion = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R3",
|
||
operation_index=3,
|
||
operation_fields={
|
||
"КодОперации": "6126",
|
||
"КодВалКонверсия": "840",
|
||
"СумКонверсия": "0.00",
|
||
"ПризнВалОперации": "VO",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert zero_conversion[26] == ""
|
||
assert zero_conversion[27] == "VO"
|
||
|
||
for operation_code in ("6100", "6127"):
|
||
boundary_row = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id=operation_code,
|
||
operation_index=4,
|
||
operation_fields={
|
||
"КодОперации": operation_code,
|
||
"ПризнВалОперации": "VO",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert boundary_row[27] == ""
|
||
|
||
|
||
def test_bank_bik_columns_accept_canonical_transfer_block_spelling() -> None:
|
||
row = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={
|
||
"ТипОператорДС": "4",
|
||
"СведенияПереводыДС.СведБанкПлательщик.БИККО": "011012100",
|
||
"СведенияПереводыДС.СведБанкПолучатель.БИККО": "022202220",
|
||
},
|
||
participant_fields={},
|
||
)
|
||
assert row[41] == "011012100"
|
||
assert row[43] == "022202220"
|
||
|
||
|
||
def test_legal_entity_blocks_do_not_use_physical_person_identification() -> None:
|
||
row = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"ТипУчастника": "4",
|
||
"УчастникЮЛ.СведЮЛ.НаимЮЛ": "ООО Тест",
|
||
"ИдентификацияФЛ": "1",
|
||
},
|
||
)
|
||
assert row[119] == ""
|
||
assert row[122] == ""
|
||
|
||
|
||
def test_col124_is_empty_for_private_practice_participant_type_4() -> None:
|
||
row = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"ТипУчастника": "4",
|
||
"УчастникФЛИП.СведФЛИП.ТипФЛЧастнаяПрактика": "1",
|
||
},
|
||
)
|
||
assert row[124] == ""
|
||
|
||
padded_type_row = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R2",
|
||
operation_index=2,
|
||
operation_fields={},
|
||
participant_fields={
|
||
"ТипУчастника": "04",
|
||
"УчастникФЛИП.СведФЛИП.ТипФЛЧастнаяПрактика": "1",
|
||
},
|
||
)
|
||
assert padded_type_row[124] == ""
|
||
|
||
|
||
def test_col119_is_not_included_in_structured_fio_or_cleared_by_one_line_fio() -> None:
|
||
participant_fields = {
|
||
"ТипУчастника": "2",
|
||
"УчастникФЛИП.СведФЛИП.ФИОФЛИП.Фам": "Азимов",
|
||
"УчастникФЛИП.СведФЛИП.ФИОФЛИП.Имя": "Ислом",
|
||
"УчастникФЛИП.СведФЛИП.ФИОФЛИП.Отч": "Каримович",
|
||
"УчастникФЛИП.ИдентификацияФЛ": "1",
|
||
}
|
||
row = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R1",
|
||
operation_index=1,
|
||
operation_fields={},
|
||
participant_fields=participant_fields,
|
||
)
|
||
assert row[114] == "Азимов Ислом Каримович"
|
||
assert row[119] == ""
|
||
assert row[122] == ""
|
||
|
||
row_with_one_line_fio = build_fixed_row_by_index(
|
||
file_name="f.xml",
|
||
record_id="R2",
|
||
operation_index=2,
|
||
operation_fields={},
|
||
participant_fields={
|
||
**participant_fields,
|
||
"УчастникФЛИП.СведФЛИП.ФИОФЛИП.ФИОСтрока": ("Азимов Ислом Каримович"),
|
||
},
|
||
)
|
||
assert row_with_one_line_fio[119] == ""
|
||
assert row_with_one_line_fio[122] == ""
|