Stop dropping XML values in the transfer and cash blocks
The customer's ruling of 24.09.2026 is that every value present in the XML must reach the report, taking into account which block holds it. Two defects broke that for operation code 5016 with transfer types 4 and 5. Wrong paths in mapping_table.json. Columns 48-63 spelled the block as "СведенияПереводыДс" and columns 49-59 spelled the address as "АдрМестоПриемаВыдача"; the schema uses "СведенияПереводыДС" and "АдрМестаПриемаВыдача". Those columns carry allow_short_lookup=false, so they can only match on a fully scoped path and never matched at all: the whole cash receipt block (AV-BI) and the transfer status (BJ) stayed empty on every file. The existing test passed only because it fed the same misspellings. Rules that deleted data instead of filling it: - Rules 38, 44-45 and 46 wiped the account columns for code 5016. The XML of those records carries СчетБанкПолучатель = 00000000000000000000, which is exactly the value the customer asked for. The rules now only substitute the placeholder into an empty column, and never for 5016. - Rule 44 also wiped the correspondent accounts for operator types 3 and 5 even when the XML had them. - The cashless rule wiped columns 50, 61, 65, 76, 84, 95, 99 and 101 for transfer types 1-4, 7 and 10-14, although type 4 is by definition a transfer that accepts cash and must carry the receipt block. - Rule 62 limited the transfer status to types 2, 5 and 8. - Rule 30 limited the metal name to code C99, while the available exports only ever carry code A90. Verified on the sample exports: all 16 records with code 5016 now carry the zeros in column 45, the real account in column 46, and no invented placeholders in columns 38 and 44.
This commit is contained in:
parent
5825ca2aed
commit
880fa5811d
@ -24,8 +24,6 @@ COL_SALE_CURRENCY = _index(25)
|
|||||||
COL_SALE_AMOUNT = _index(26)
|
COL_SALE_AMOUNT = _index(26)
|
||||||
COL_CURRENCY_SIGN = _index(27)
|
COL_CURRENCY_SIGN = _index(27)
|
||||||
COL_SUSPICIOUS_ID = _index(28)
|
COL_SUSPICIOUS_ID = _index(28)
|
||||||
COL_METAL_CODE = _index(29)
|
|
||||||
COL_METAL_NAME = _index(30)
|
|
||||||
COL_ITEM_TYPE = _index(31)
|
COL_ITEM_TYPE = _index(31)
|
||||||
COL_EXTRA_INFO = _index(34)
|
COL_EXTRA_INFO = _index(34)
|
||||||
|
|
||||||
@ -43,7 +41,6 @@ COL_PAYER_BANK_ACCOUNT = _index(44)
|
|||||||
COL_RECIPIENT_BANK_ACCOUNT = _index(45)
|
COL_RECIPIENT_BANK_ACCOUNT = _index(45)
|
||||||
COL_RECIPIENT_ACCOUNT = _index(46)
|
COL_RECIPIENT_ACCOUNT = _index(46)
|
||||||
COL_RECIPIENT_ESP = _index(47)
|
COL_RECIPIENT_ESP = _index(47)
|
||||||
COL_TRANSFER_STATUS = _index(62)
|
|
||||||
|
|
||||||
# Карты и место операции.
|
# Карты и место операции.
|
||||||
COL_TERRITORY_CODE_CARD = _index(96)
|
COL_TERRITORY_CODE_CARD = _index(96)
|
||||||
@ -87,11 +84,6 @@ PARTICIPANT_ADDRESS_COMPONENT_COLUMNS = tuple(
|
|||||||
if column.structured_group == "legacy_142" and column.structured_role == "component"
|
if column.structured_group == "legacy_142" and column.structured_role == "component"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Точные поля наличных, которые исторически очищаются для безналичных переводов.
|
|
||||||
CASHLESS_CLEARED_COLUMNS = tuple(
|
|
||||||
_index(position) for position in (50, 61, 65, 76, 84, 95, 99, 101)
|
|
||||||
)
|
|
||||||
|
|
||||||
OKATO_COUNTRY_PAIRS: tuple[tuple[int, int], ...] = tuple(
|
OKATO_COUNTRY_PAIRS: tuple[tuple[int, int], ...] = tuple(
|
||||||
(_index(country), _index(okato))
|
(_index(country), _index(okato))
|
||||||
for country, okato in (
|
for country, okato in (
|
||||||
@ -106,16 +98,12 @@ OKATO_COUNTRY_PAIRS: tuple[tuple[int, int], ...] = tuple(
|
|||||||
# Бизнес-константы.
|
# Бизнес-константы.
|
||||||
ACCOUNT_PLACEHOLDER = "00000000000000000000"
|
ACCOUNT_PLACEHOLDER = "00000000000000000000"
|
||||||
EXPORT_SUBSIDIARY_COMMENT_CODES = frozenset(str(code) for code in range(6102, 6127))
|
EXPORT_SUBSIDIARY_COMMENT_CODES = frozenset(str(code) for code in range(6102, 6127))
|
||||||
CASHLESS_TRANSFER_TYPES = frozenset(
|
|
||||||
{"1", "2", "3", "4", "7", "10", "11", "12", "13", "14"}
|
|
||||||
)
|
|
||||||
VALID_FTR_SIGNS = frozenset({"0", "1", "2", "3", "4", "5"})
|
VALID_FTR_SIGNS = frozenset({"0", "1", "2", "3", "4", "5"})
|
||||||
VALID_SUSPENSION_BASES = frozenset({"1", "2", "3"})
|
VALID_SUSPENSION_BASES = frozenset({"1", "2", "3"})
|
||||||
VALID_ESP_SIGNS = frozenset({"1", "2", "3", "4"})
|
VALID_ESP_SIGNS = frozenset({"1", "2", "3", "4"})
|
||||||
PRECIOUS_ITEM_CODES = frozenset({"5020", "5021", "5022", "5023"})
|
PRECIOUS_ITEM_CODES = frozenset({"5020", "5021", "5022", "5023"})
|
||||||
SUSPICIOUS_CODE = "6001"
|
SUSPICIOUS_CODE = "6001"
|
||||||
TERRITORY_CODE = "5016"
|
TERRITORY_CODE = "5016"
|
||||||
PRECIOUS_METAL_CODE = "C99"
|
|
||||||
EMPLOYEE_ABSENT_CODE = "0"
|
EMPLOYEE_ABSENT_CODE = "0"
|
||||||
RUSSIA_COUNTRY_CODE = "643"
|
RUSSIA_COUNTRY_CODE = "643"
|
||||||
|
|
||||||
|
|||||||
@ -7,8 +7,6 @@ from .column_constants import (
|
|||||||
ACCOUNT_PLACEHOLDER,
|
ACCOUNT_PLACEHOLDER,
|
||||||
BLOCK_CP,
|
BLOCK_CP,
|
||||||
BLOCK_EIO,
|
BLOCK_EIO,
|
||||||
CASHLESS_CLEARED_COLUMNS,
|
|
||||||
CASHLESS_TRANSFER_TYPES,
|
|
||||||
COL_ADDRESS_ONE_LINE,
|
COL_ADDRESS_ONE_LINE,
|
||||||
COL_ADDRESS_STRUCTURED,
|
COL_ADDRESS_STRUCTURED,
|
||||||
COL_AMOUNT_CURRENCY,
|
COL_AMOUNT_CURRENCY,
|
||||||
@ -38,8 +36,6 @@ from .column_constants import (
|
|||||||
COL_INSURANCE_NUMBER,
|
COL_INSURANCE_NUMBER,
|
||||||
COL_ITEM_TYPE,
|
COL_ITEM_TYPE,
|
||||||
COL_KPP,
|
COL_KPP,
|
||||||
COL_METAL_CODE,
|
|
||||||
COL_METAL_NAME,
|
|
||||||
COL_OPERATION_CODE,
|
COL_OPERATION_CODE,
|
||||||
COL_OPERATION_DOCUMENTS,
|
COL_OPERATION_DOCUMENTS,
|
||||||
COL_OPERATION_SIGN,
|
COL_OPERATION_SIGN,
|
||||||
@ -65,7 +61,6 @@ from .column_constants import (
|
|||||||
COL_SUSPENSION_BASIS,
|
COL_SUSPENSION_BASIS,
|
||||||
COL_SUSPICIOUS_ID,
|
COL_SUSPICIOUS_ID,
|
||||||
COL_TERRITORY_CODE,
|
COL_TERRITORY_CODE,
|
||||||
COL_TRANSFER_STATUS,
|
|
||||||
COL_TRANSFER_TYPE,
|
COL_TRANSFER_TYPE,
|
||||||
COL_UNUSUAL_CODES,
|
COL_UNUSUAL_CODES,
|
||||||
EMPLOYEE_ABSENT_CODE,
|
EMPLOYEE_ABSENT_CODE,
|
||||||
@ -77,7 +72,6 @@ from .column_constants import (
|
|||||||
PARTICIPANT_TYPE_IP,
|
PARTICIPANT_TYPE_IP,
|
||||||
PARTICIPANT_TYPE_UL,
|
PARTICIPANT_TYPE_UL,
|
||||||
PRECIOUS_ITEM_CODES,
|
PRECIOUS_ITEM_CODES,
|
||||||
PRECIOUS_METAL_CODE,
|
|
||||||
RUSSIA_COUNTRY_CODE,
|
RUSSIA_COUNTRY_CODE,
|
||||||
SUSPICIOUS_CODE,
|
SUSPICIOUS_CODE,
|
||||||
TERRITORY_CODE,
|
TERRITORY_CODE,
|
||||||
@ -886,7 +880,6 @@ def _apply_business_rules(
|
|||||||
_rule_sale_currency(row)
|
_rule_sale_currency(row)
|
||||||
_rule_extra_info(row, codes, operation_lookup, participant_lookup)
|
_rule_extra_info(row, codes, operation_lookup, participant_lookup)
|
||||||
_rule_suspicious_activity(row, codes)
|
_rule_suspicious_activity(row, codes)
|
||||||
_rule_metal_name(row)
|
|
||||||
_rule_item_type(row, codes)
|
_rule_item_type(row, codes)
|
||||||
_rule_territory_codes(row, codes)
|
_rule_territory_codes(row, codes)
|
||||||
|
|
||||||
@ -895,10 +888,8 @@ def _apply_business_rules(
|
|||||||
_rule_payer_bank(row, operator_type)
|
_rule_payer_bank(row, operator_type)
|
||||||
_rule_recipient_bank(row, operator_type)
|
_rule_recipient_bank(row, operator_type)
|
||||||
_rule_correspondent_accounts(row, operator_type, transfer_type, codes)
|
_rule_correspondent_accounts(row, operator_type, transfer_type, codes)
|
||||||
_rule_recipient_account(row, transfer_type)
|
_rule_recipient_account(row, transfer_type, codes)
|
||||||
_rule_transfer_status(row, transfer_type)
|
|
||||||
|
|
||||||
_rule_cashless_clears_cash_columns(row, transfer_type)
|
|
||||||
_rule_card_without_employee(row)
|
_rule_card_without_employee(row)
|
||||||
|
|
||||||
_rule_participant_identity(row, participant_type)
|
_rule_participant_identity(row, participant_type)
|
||||||
@ -991,12 +982,6 @@ def _rule_suspicious_activity(row: dict[int, str], codes: set[str]) -> None:
|
|||||||
_set(row, COL_SUSPICIOUS_ID, "")
|
_set(row, COL_SUSPICIOUS_ID, "")
|
||||||
|
|
||||||
|
|
||||||
def _rule_metal_name(row: dict[int, str]) -> None:
|
|
||||||
"""Правило 30: наименование металла только для кода C99."""
|
|
||||||
if _get(row, COL_METAL_CODE).upper() != PRECIOUS_METAL_CODE:
|
|
||||||
_set(row, COL_METAL_NAME, "")
|
|
||||||
|
|
||||||
|
|
||||||
def _rule_item_type(row: dict[int, str], codes: set[str]) -> None:
|
def _rule_item_type(row: dict[int, str], codes: set[str]) -> None:
|
||||||
"""Правило 31: предмет операции только для кодов 5020-5023."""
|
"""Правило 31: предмет операции только для кодов 5020-5023."""
|
||||||
if not codes & PRECIOUS_ITEM_CODES:
|
if not codes & PRECIOUS_ITEM_CODES:
|
||||||
@ -1022,19 +1007,17 @@ def _rule_territory_codes(row: dict[int, str], codes: set[str]) -> None:
|
|||||||
def _rule_payer_account(
|
def _rule_payer_account(
|
||||||
row: dict[int, str], transfer_type: str, codes: set[str]
|
row: dict[int, str], transfer_type: str, codes: set[str]
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Правило 38: счёт плательщика зависит от вида перевода.
|
"""Правило 38: заглушка счёта плательщика для отдельных видов перевода.
|
||||||
|
|
||||||
Для операций с кодом 5016 (п.6 правок) заглушку не подставляем — такого
|
Значение, пришедшее из XML, не затирается никогда: заказчик 24.09.2026
|
||||||
блока (номера счетов) для 5016 в спецификации нет.
|
подтвердил, что в отчёт должны попадать все значения из файла. Правило
|
||||||
|
только подставляет заглушку в пустую колонку, а для операций с кодом 5016
|
||||||
|
(п.6 правок) не делает и этого — своего блока номеров счетов у 5016 нет.
|
||||||
"""
|
"""
|
||||||
if TERRITORY_CODE in codes:
|
if TERRITORY_CODE in codes:
|
||||||
_set(row, COL_PAYER_ACCOUNT, "")
|
|
||||||
return
|
return
|
||||||
if transfer_type in {"1", "2", "3", "10"}:
|
if transfer_type in {"1", "2", "3", "10"} and not _get(row, COL_PAYER_ACCOUNT):
|
||||||
if not _get(row, COL_PAYER_ACCOUNT):
|
_set(row, COL_PAYER_ACCOUNT, ACCOUNT_PLACEHOLDER)
|
||||||
_set(row, COL_PAYER_ACCOUNT, ACCOUNT_PLACEHOLDER)
|
|
||||||
elif transfer_type not in {"12", "13", "14"}:
|
|
||||||
_set(row, COL_PAYER_ACCOUNT, "")
|
|
||||||
|
|
||||||
|
|
||||||
def _rule_esp_identifiers(row: dict[int, str], operation_sign: str) -> None:
|
def _rule_esp_identifiers(row: dict[int, str], operation_sign: str) -> None:
|
||||||
@ -1060,51 +1043,46 @@ def _rule_recipient_bank(row: dict[int, str], operator_type: str) -> None:
|
|||||||
def _rule_correspondent_accounts(
|
def _rule_correspondent_accounts(
|
||||||
row: dict[int, str], operator_type: str, transfer_type: str, codes: set[str]
|
row: dict[int, str], operator_type: str, transfer_type: str, codes: set[str]
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Правила 44-45: корсчета зависят от оператора и вида перевода.
|
"""Правила 44-45: заглушки корсчетов зависят от оператора и вида перевода.
|
||||||
|
|
||||||
Для операций с кодом 5016 (п.6 правок) заглушку не подставляем — такого
|
Как и в правиле 38, пришедшее из XML значение сохраняется всегда. Это
|
||||||
блока (номера счетов) для 5016 в спецификации нет.
|
важно именно для кода 5016: в таких записях в XML реально лежит
|
||||||
|
СчетБанкПолучатель = 00000000000000000000, и заказчик 24.09.2026 отдельно
|
||||||
|
указал, что эти нули обязаны попадать в отчёт. Раньше их затирала ветка
|
||||||
|
по коду 5016, а корсчёт плательщика — ветка по типам оператора 3 и 5.
|
||||||
"""
|
"""
|
||||||
if TERRITORY_CODE in codes:
|
if TERRITORY_CODE in codes:
|
||||||
_set(row, COL_PAYER_BANK_ACCOUNT, "")
|
|
||||||
_set(row, COL_RECIPIENT_BANK_ACCOUNT, "")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if not operator_type and not transfer_type:
|
if not operator_type and not transfer_type:
|
||||||
_set(row, COL_PAYER_BANK_ACCOUNT, "")
|
|
||||||
_set(row, COL_RECIPIENT_BANK_ACCOUNT, "")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if operator_type in {"3", "5"} or transfer_type in {"12", "13"}:
|
if (
|
||||||
_set(row, COL_PAYER_BANK_ACCOUNT, "")
|
operator_type not in {"3", "5"}
|
||||||
elif not _get(row, COL_PAYER_BANK_ACCOUNT):
|
and transfer_type not in {"12", "13"}
|
||||||
|
and not _get(row, COL_PAYER_BANK_ACCOUNT)
|
||||||
|
):
|
||||||
_set(row, COL_PAYER_BANK_ACCOUNT, ACCOUNT_PLACEHOLDER)
|
_set(row, COL_PAYER_BANK_ACCOUNT, ACCOUNT_PLACEHOLDER)
|
||||||
|
|
||||||
if operator_type in {"3", "5"} or transfer_type in {"10", "11"}:
|
if (
|
||||||
_set(row, COL_RECIPIENT_BANK_ACCOUNT, "")
|
operator_type not in {"3", "5"}
|
||||||
elif not _get(row, COL_RECIPIENT_BANK_ACCOUNT):
|
and transfer_type not in {"10", "11"}
|
||||||
|
and not _get(row, COL_RECIPIENT_BANK_ACCOUNT)
|
||||||
|
):
|
||||||
_set(row, COL_RECIPIENT_BANK_ACCOUNT, ACCOUNT_PLACEHOLDER)
|
_set(row, COL_RECIPIENT_BANK_ACCOUNT, ACCOUNT_PLACEHOLDER)
|
||||||
|
|
||||||
|
|
||||||
def _rule_recipient_account(row: dict[int, str], transfer_type: str) -> None:
|
def _rule_recipient_account(
|
||||||
"""Правило 46: счёт получателя зависит от вида перевода."""
|
row: dict[int, str], transfer_type: str, codes: set[str]
|
||||||
if transfer_type in {"1", "4", "7", "12"}:
|
) -> None:
|
||||||
if not _get(row, COL_RECIPIENT_ACCOUNT):
|
"""Правило 46: заглушка счёта получателя для отдельных видов перевода.
|
||||||
_set(row, COL_RECIPIENT_ACCOUNT, ACCOUNT_PLACEHOLDER)
|
|
||||||
elif transfer_type not in {"10", "11", "14"}:
|
|
||||||
_set(row, COL_RECIPIENT_ACCOUNT, "")
|
|
||||||
|
|
||||||
|
Как и правила 38 и 44-45, значение из XML не затирает, а для кода 5016
|
||||||
def _rule_transfer_status(row: dict[int, str], transfer_type: str) -> None:
|
заглушку не подставляет.
|
||||||
"""Правило 62: статус перевода только для видов 2, 5 и 8."""
|
"""
|
||||||
if transfer_type not in {"2", "5", "8"}:
|
if TERRITORY_CODE in codes:
|
||||||
_set(row, COL_TRANSFER_STATUS, "")
|
return
|
||||||
|
if transfer_type in {"1", "4", "7", "12"} and not _get(row, COL_RECIPIENT_ACCOUNT):
|
||||||
|
_set(row, COL_RECIPIENT_ACCOUNT, ACCOUNT_PLACEHOLDER)
|
||||||
def _rule_cashless_clears_cash_columns(row: dict[int, str], transfer_type: str) -> None:
|
|
||||||
"""Для безналичных переводов очищаем согласованные наличные поля."""
|
|
||||||
if transfer_type in CASHLESS_TRANSFER_TYPES:
|
|
||||||
_clear_columns(row, CASHLESS_CLEARED_COLUMNS)
|
|
||||||
|
|
||||||
|
|
||||||
def _rule_card_without_employee(row: dict[int, str]) -> None:
|
def _rule_card_without_employee(row: dict[int, str]) -> None:
|
||||||
|
|||||||
@ -946,7 +946,7 @@
|
|||||||
"block": "cash_receipt",
|
"block": "cash_receipt",
|
||||||
"report_group": "cash_receipt",
|
"report_group": "cash_receipt",
|
||||||
"xml_tag": "ИдТерминал",
|
"xml_tag": "ИдТерминал",
|
||||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДс/СведПриемНалДС/ИдТерминал",
|
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДС/СведПриемНалДС/ИдТерминал",
|
||||||
"source_scope": "any",
|
"source_scope": "any",
|
||||||
"allow_short_lookup": false,
|
"allow_short_lookup": false,
|
||||||
"allow_direct_mapping": true,
|
"allow_direct_mapping": true,
|
||||||
@ -966,7 +966,7 @@
|
|||||||
"block": "cash_receipt",
|
"block": "cash_receipt",
|
||||||
"report_group": "cash_receipt",
|
"report_group": "cash_receipt",
|
||||||
"xml_tag": "АдрМестаПриемаВыдача",
|
"xml_tag": "АдрМестаПриемаВыдача",
|
||||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДс/СведПриемНалДС/АдрМестоПриемаВыдача/АдресСтрока",
|
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДС/СведПриемНалДС/АдрМестаПриемаВыдача/АдресСтрока",
|
||||||
"source_scope": "any",
|
"source_scope": "any",
|
||||||
"allow_short_lookup": false,
|
"allow_short_lookup": false,
|
||||||
"allow_direct_mapping": true,
|
"allow_direct_mapping": true,
|
||||||
@ -986,7 +986,7 @@
|
|||||||
"block": "cash_receipt",
|
"block": "cash_receipt",
|
||||||
"report_group": "cash_receipt",
|
"report_group": "cash_receipt",
|
||||||
"xml_tag": "АдрМестаПриемаВыдача",
|
"xml_tag": "АдрМестаПриемаВыдача",
|
||||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДс/СведПриемНалДС/АдрМестоПриемаВыдача/АдресСтрока",
|
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДС/СведПриемНалДС/АдрМестаПриемаВыдача/АдресСтрока",
|
||||||
"source_scope": "any",
|
"source_scope": "any",
|
||||||
"allow_short_lookup": true,
|
"allow_short_lookup": true,
|
||||||
"allow_direct_mapping": true,
|
"allow_direct_mapping": true,
|
||||||
@ -1006,7 +1006,7 @@
|
|||||||
"block": "cash_receipt",
|
"block": "cash_receipt",
|
||||||
"report_group": "cash_receipt",
|
"report_group": "cash_receipt",
|
||||||
"xml_tag": "АдрМестаПриемаВыдача",
|
"xml_tag": "АдрМестаПриемаВыдача",
|
||||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДс/СведПриемНалДС/АдрМестоПриемаВыдача/Индекс",
|
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДС/СведПриемНалДС/АдрМестаПриемаВыдача/Индекс",
|
||||||
"source_scope": "any",
|
"source_scope": "any",
|
||||||
"allow_short_lookup": false,
|
"allow_short_lookup": false,
|
||||||
"allow_direct_mapping": true,
|
"allow_direct_mapping": true,
|
||||||
@ -1026,7 +1026,7 @@
|
|||||||
"block": "cash_receipt",
|
"block": "cash_receipt",
|
||||||
"report_group": "cash_receipt",
|
"report_group": "cash_receipt",
|
||||||
"xml_tag": "АдрМестаПриемаВыдача",
|
"xml_tag": "АдрМестаПриемаВыдача",
|
||||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДс/СведПриемНалДС/АдрМестоПриемаВыдача/КодОКСМ",
|
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДС/СведПриемНалДС/АдрМестаПриемаВыдача/КодОКСМ",
|
||||||
"source_scope": "any",
|
"source_scope": "any",
|
||||||
"allow_short_lookup": false,
|
"allow_short_lookup": false,
|
||||||
"allow_direct_mapping": true,
|
"allow_direct_mapping": true,
|
||||||
@ -1046,7 +1046,7 @@
|
|||||||
"block": "cash_receipt",
|
"block": "cash_receipt",
|
||||||
"report_group": "cash_receipt",
|
"report_group": "cash_receipt",
|
||||||
"xml_tag": "АдрМестаПриемаВыдача",
|
"xml_tag": "АдрМестаПриемаВыдача",
|
||||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДс/СведПриемНалДС/АдрМестоПриемаВыдача/КодСубъектаПоОКАТО",
|
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДС/СведПриемНалДС/АдрМестаПриемаВыдача/КодСубъектаПоОКАТО",
|
||||||
"source_scope": "any",
|
"source_scope": "any",
|
||||||
"allow_short_lookup": false,
|
"allow_short_lookup": false,
|
||||||
"allow_direct_mapping": true,
|
"allow_direct_mapping": true,
|
||||||
@ -1066,7 +1066,7 @@
|
|||||||
"block": "cash_receipt",
|
"block": "cash_receipt",
|
||||||
"report_group": "cash_receipt",
|
"report_group": "cash_receipt",
|
||||||
"xml_tag": "АдрМестаПриемаВыдача",
|
"xml_tag": "АдрМестаПриемаВыдача",
|
||||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДс/СведПриемНалДС/АдрМестоПриемаВыдача/Район",
|
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДС/СведПриемНалДС/АдрМестаПриемаВыдача/Район",
|
||||||
"source_scope": "any",
|
"source_scope": "any",
|
||||||
"allow_short_lookup": false,
|
"allow_short_lookup": false,
|
||||||
"allow_direct_mapping": true,
|
"allow_direct_mapping": true,
|
||||||
@ -1086,7 +1086,7 @@
|
|||||||
"block": "cash_receipt",
|
"block": "cash_receipt",
|
||||||
"report_group": "cash_receipt",
|
"report_group": "cash_receipt",
|
||||||
"xml_tag": "АдрМестаПриемаВыдача",
|
"xml_tag": "АдрМестаПриемаВыдача",
|
||||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДс/СведПриемНалДС/АдрМестоПриемаВыдача/Пункт",
|
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДС/СведПриемНалДС/АдрМестаПриемаВыдача/Пункт",
|
||||||
"source_scope": "any",
|
"source_scope": "any",
|
||||||
"allow_short_lookup": false,
|
"allow_short_lookup": false,
|
||||||
"allow_direct_mapping": true,
|
"allow_direct_mapping": true,
|
||||||
@ -1106,7 +1106,7 @@
|
|||||||
"block": "cash_receipt",
|
"block": "cash_receipt",
|
||||||
"report_group": "cash_receipt",
|
"report_group": "cash_receipt",
|
||||||
"xml_tag": "АдрМестаПриемаВыдача",
|
"xml_tag": "АдрМестаПриемаВыдача",
|
||||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДс/СведПриемНалДС/АдрМестоПриемаВыдача/Улица",
|
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДС/СведПриемНалДС/АдрМестаПриемаВыдача/Улица",
|
||||||
"source_scope": "any",
|
"source_scope": "any",
|
||||||
"allow_short_lookup": false,
|
"allow_short_lookup": false,
|
||||||
"allow_direct_mapping": true,
|
"allow_direct_mapping": true,
|
||||||
@ -1126,7 +1126,7 @@
|
|||||||
"block": "cash_receipt",
|
"block": "cash_receipt",
|
||||||
"report_group": "cash_receipt",
|
"report_group": "cash_receipt",
|
||||||
"xml_tag": "АдрМестаПриемаВыдача",
|
"xml_tag": "АдрМестаПриемаВыдача",
|
||||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДс/СведПриемНалДС/АдрМестоПриемаВыдача/Дом",
|
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДС/СведПриемНалДС/АдрМестаПриемаВыдача/Дом",
|
||||||
"source_scope": "any",
|
"source_scope": "any",
|
||||||
"allow_short_lookup": false,
|
"allow_short_lookup": false,
|
||||||
"allow_direct_mapping": true,
|
"allow_direct_mapping": true,
|
||||||
@ -1146,7 +1146,7 @@
|
|||||||
"block": "cash_receipt",
|
"block": "cash_receipt",
|
||||||
"report_group": "cash_receipt",
|
"report_group": "cash_receipt",
|
||||||
"xml_tag": "АдрМестаПриемаВыдача",
|
"xml_tag": "АдрМестаПриемаВыдача",
|
||||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДс/СведПриемНалДС/АдрМестоПриемаВыдача/Корп",
|
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДС/СведПриемНалДС/АдрМестаПриемаВыдача/Корп",
|
||||||
"source_scope": "any",
|
"source_scope": "any",
|
||||||
"allow_short_lookup": false,
|
"allow_short_lookup": false,
|
||||||
"allow_direct_mapping": true,
|
"allow_direct_mapping": true,
|
||||||
@ -1166,7 +1166,7 @@
|
|||||||
"block": "cash_receipt",
|
"block": "cash_receipt",
|
||||||
"report_group": "cash_receipt",
|
"report_group": "cash_receipt",
|
||||||
"xml_tag": "АдрМестаПриемаВыдача",
|
"xml_tag": "АдрМестаПриемаВыдача",
|
||||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДс/СведПриемНалДС/АдрМестоПриемаВыдача/Оф",
|
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДС/СведПриемНалДС/АдрМестаПриемаВыдача/Оф",
|
||||||
"source_scope": "any",
|
"source_scope": "any",
|
||||||
"allow_short_lookup": false,
|
"allow_short_lookup": false,
|
||||||
"allow_direct_mapping": true,
|
"allow_direct_mapping": true,
|
||||||
@ -1186,7 +1186,7 @@
|
|||||||
"block": "cash_receipt",
|
"block": "cash_receipt",
|
||||||
"report_group": "cash_receipt",
|
"report_group": "cash_receipt",
|
||||||
"xml_tag": "НаимКО",
|
"xml_tag": "НаимКО",
|
||||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДс/СведПриемНалДС/НаимКО",
|
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДС/СведПриемНалДС/НаимКО",
|
||||||
"source_scope": "any",
|
"source_scope": "any",
|
||||||
"allow_short_lookup": false,
|
"allow_short_lookup": false,
|
||||||
"allow_direct_mapping": true,
|
"allow_direct_mapping": true,
|
||||||
@ -1206,7 +1206,7 @@
|
|||||||
"block": "cash_receipt",
|
"block": "cash_receipt",
|
||||||
"report_group": "cash_receipt",
|
"report_group": "cash_receipt",
|
||||||
"xml_tag": "БИККО",
|
"xml_tag": "БИККО",
|
||||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДс/СведПриемНалДС/БИККО",
|
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДС/СведПриемНалДС/БИККО",
|
||||||
"source_scope": "any",
|
"source_scope": "any",
|
||||||
"allow_short_lookup": false,
|
"allow_short_lookup": false,
|
||||||
"allow_direct_mapping": true,
|
"allow_direct_mapping": true,
|
||||||
@ -1226,7 +1226,7 @@
|
|||||||
"block": "transfer_status",
|
"block": "transfer_status",
|
||||||
"report_group": "transfer_status",
|
"report_group": "transfer_status",
|
||||||
"xml_tag": "СтатусПеревод",
|
"xml_tag": "СтатусПеревод",
|
||||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДс/СтатусПеревод",
|
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДС/СтатусПеревод",
|
||||||
"source_scope": "any",
|
"source_scope": "any",
|
||||||
"allow_short_lookup": false,
|
"allow_short_lookup": false,
|
||||||
"allow_direct_mapping": true,
|
"allow_direct_mapping": true,
|
||||||
@ -1246,7 +1246,7 @@
|
|||||||
"block": "cash_payment",
|
"block": "cash_payment",
|
||||||
"report_group": "cash_payment",
|
"report_group": "cash_payment",
|
||||||
"xml_tag": "ИдТерминал",
|
"xml_tag": "ИдТерминал",
|
||||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДс/СведВыдачаНалДС/ИдТерминал",
|
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/СведенияПереводыДС/СведВыдачаНалДС/ИдТерминал",
|
||||||
"source_scope": "any",
|
"source_scope": "any",
|
||||||
"allow_short_lookup": false,
|
"allow_short_lookup": false,
|
||||||
"allow_direct_mapping": true,
|
"allow_direct_mapping": true,
|
||||||
|
|||||||
@ -437,6 +437,23 @@ def test_operator_type_conditions_clear_irrelevant_bank_fields() -> None:
|
|||||||
assert row["Наименование банка плательщика"] == ""
|
assert row["Наименование банка плательщика"] == ""
|
||||||
assert row["Наименование банка получателя"] == ""
|
assert row["Наименование банка получателя"] == ""
|
||||||
assert row["БИК банка получателя"] == ""
|
assert row["БИК банка получателя"] == ""
|
||||||
|
# Корсчета при типе оператора 3 заглушкой не заполняются, но и не
|
||||||
|
# затираются: заказчик 24.09.2026 потребовал выводить всё, что пришло
|
||||||
|
# в XML. Раньше эти два значения удалялись.
|
||||||
|
assert row["Номер счета банка плательщика"] == "30101810000000000001"
|
||||||
|
assert row["Номер счета банка получателя"] == "30101810000000000002"
|
||||||
|
|
||||||
|
|
||||||
|
def test_correspondent_accounts_stay_empty_for_operator_3_without_xml_values() -> None:
|
||||||
|
"""Обратная сторона предыдущего теста: если в XML корсчетов нет, при типе
|
||||||
|
оператора 3 заглушка по-прежнему не подставляется."""
|
||||||
|
row = build_fixed_row(
|
||||||
|
file_name="f.xml",
|
||||||
|
record_id="R1",
|
||||||
|
operation_index=1,
|
||||||
|
operation_fields={"ТипОператорДС": "3", "ВидПереводДС": "1"},
|
||||||
|
participant_fields={},
|
||||||
|
)
|
||||||
assert row["Номер счета банка плательщика"] == ""
|
assert row["Номер счета банка плательщика"] == ""
|
||||||
assert row["Номер счета банка получателя"] == ""
|
assert row["Номер счета банка получателя"] == ""
|
||||||
|
|
||||||
@ -877,25 +894,33 @@ def test_operation_documents_keep_positions_and_join_multiple_documents() -> Non
|
|||||||
|
|
||||||
|
|
||||||
def test_structured_cash_address_does_not_include_bank_fields() -> None:
|
def test_structured_cash_address_does_not_include_bank_fields() -> None:
|
||||||
|
"""Ключи здесь записаны так, как их отдаёт парсер по схеме
|
||||||
|
SKO115FZ_OPER_v2.xsd: блок называется "СведенияПереводыДС" (обе последние
|
||||||
|
буквы заглавные), а адрес — "АдрМестаПриемаВыдача". Раньше и тест, и
|
||||||
|
mapping_table.json содержали одни и те же опечатки ("СведенияПереводыДс",
|
||||||
|
"АдрМестоПриемаВыдача"), поэтому тест проходил, а на реальных файлах весь
|
||||||
|
блок приёма наличных оставался пустым."""
|
||||||
row = build_fixed_row_by_index(
|
row = build_fixed_row_by_index(
|
||||||
file_name="f.xml",
|
file_name="f.xml",
|
||||||
record_id="R1",
|
record_id="R1",
|
||||||
operation_index=1,
|
operation_index=1,
|
||||||
operation_fields={
|
operation_fields={
|
||||||
"СведенияПереводыДс.СведПриемНалДС.АдрМестоПриемаВыдача.Индекс": "675520",
|
"СведенияПереводыДС.СведПриемНалДС.АдрМестаПриемаВыдача.Индекс": "675520",
|
||||||
"СведенияПереводыДс.СведПриемНалДС.АдрМестоПриемаВыдача.КодОКСМ": "643",
|
"СведенияПереводыДС.СведПриемНалДС.АдрМестаПриемаВыдача.КодОКСМ": "643",
|
||||||
"СведенияПереводыДс.СведПриемНалДС.АдрМестоПриемаВыдача.КодСубъектаПоОКАТО": "10",
|
"СведенияПереводыДС.СведПриемНалДС.АдрМестаПриемаВыдача.КодСубъектаПоОКАТО": "10",
|
||||||
"СведенияПереводыДс.СведПриемНалДС.АдрМестоПриемаВыдача.Пункт": "Чигири с",
|
"СведенияПереводыДС.СведПриемНалДС.АдрМестаПриемаВыдача.Пункт": "Чигири с",
|
||||||
"СведенияПереводыДс.СведПриемНалДС.АдрМестоПриемаВыдача.Улица": "Зеленая ул",
|
"СведенияПереводыДС.СведПриемНалДС.АдрМестаПриемаВыдача.Улица": "Зеленая ул",
|
||||||
"СведенияПереводыДс.СведПриемНалДС.АдрМестоПриемаВыдача.Дом": "1",
|
"СведенияПереводыДС.СведПриемНалДС.АдрМестаПриемаВыдача.Дом": "1",
|
||||||
"СведенияПереводыДс.СведПриемНалДС.БИККО": "044525111",
|
"СведенияПереводыДС.СведПриемНалДС.БИККО": "044525111",
|
||||||
"СведенияПереводыДс.СведПриемНалДС.НаимКО": "АО РСХБ",
|
"СведенияПереводыДС.СведПриемНалДС.НаимКО": "АО РСХБ",
|
||||||
},
|
},
|
||||||
participant_fields={},
|
participant_fields={},
|
||||||
)
|
)
|
||||||
assert row[50] == "675520, 643, 10, , Чигири с, Зеленая ул, 1, , "
|
assert row[50] == "675520, 643, 10, , Чигири с, Зеленая ул, 1, , "
|
||||||
assert "044525111" not in row[50]
|
assert "044525111" not in row[50]
|
||||||
assert "АО РСХБ" not in row[50]
|
assert "АО РСХБ" not in row[50]
|
||||||
|
assert row[61] == "044525111"
|
||||||
|
assert row[60] == "АО РСХБ"
|
||||||
|
|
||||||
|
|
||||||
def test_participant_structured_address_stays_in_142_and_components_143_plus() -> None:
|
def test_participant_structured_address_stays_in_142_and_components_143_plus() -> None:
|
||||||
@ -1140,21 +1165,40 @@ def test_col179_keeps_structured_eio_registration_without_one_line() -> None:
|
|||||||
assert row[179] == "123456, 643, Москва"
|
assert row[179] == "123456, 643, Москва"
|
||||||
|
|
||||||
|
|
||||||
def test_cash_columns_cleared_for_cashless_transfer_type_1() -> None:
|
def test_cash_columns_keep_xml_values_for_any_transfer_type() -> None:
|
||||||
|
"""Раньше для видов перевода 1-4, 7 и 10-14 колонки 50, 61, 65, 76, 84,
|
||||||
|
95, 99 и 101 очищались как "безналичные". Заказчик 24.09.2026 указал, что
|
||||||
|
в отчёт должны попадать все значения из XML, а для вида перевода 4 блок
|
||||||
|
приёма наличных (включая БИК банка плательщика) обязателен."""
|
||||||
row = build_fixed_row_by_index(
|
row = build_fixed_row_by_index(
|
||||||
file_name="f.xml",
|
file_name="f.xml",
|
||||||
record_id="R1",
|
record_id="R1",
|
||||||
operation_index=1,
|
operation_index=1,
|
||||||
operation_fields={
|
operation_fields={
|
||||||
"ВидПереводДС": "1",
|
"ВидПереводДС": "4",
|
||||||
"КодОперации": "4006",
|
"КодОперации": "5016",
|
||||||
"БИККО": "044525111",
|
"СведенияПереводыДС.СведПриемНалДС.БИККО": "044525111",
|
||||||
"СведенияПереводыДс.СведПриемНалДС.БИККО": "044525111",
|
"СведенияПереводыДС.СведПриемНалДС.АдрМестаПриемаВыдача.Индекс": "675520",
|
||||||
},
|
},
|
||||||
participant_fields={},
|
participant_fields={},
|
||||||
)
|
)
|
||||||
for index in (50, 61, 65, 76, 84, 95, 99, 101):
|
assert row[61] == "044525111"
|
||||||
assert row[index] == ""
|
assert row[51] == "675520"
|
||||||
|
assert row[50].startswith("675520")
|
||||||
|
|
||||||
|
|
||||||
|
def test_cash_columns_stay_empty_when_xml_has_no_cash_block() -> None:
|
||||||
|
"""Проверяем, что удаление правила "безналичных" не начало выдумывать
|
||||||
|
значения: без блоков наличных колонки остаются пустыми."""
|
||||||
|
row = build_fixed_row_by_index(
|
||||||
|
file_name="f.xml",
|
||||||
|
record_id="R1",
|
||||||
|
operation_index=1,
|
||||||
|
operation_fields={"ВидПереводДС": "1", "КодОперации": "9003"},
|
||||||
|
participant_fields={},
|
||||||
|
)
|
||||||
|
for index in (48, 50, 61, 63, 65, 76, 84, 95, 99, 101):
|
||||||
|
assert row[index] == "", index
|
||||||
|
|
||||||
|
|
||||||
def test_col119_is_empty_for_legal_entity_and_uses_flip_identifier() -> None:
|
def test_col119_is_empty_for_legal_entity_and_uses_flip_identifier() -> None:
|
||||||
@ -1668,6 +1712,96 @@ def test_col38_44_45_payer_accounts_blank_for_5016() -> None:
|
|||||||
assert row[46] == "40817810106240020211" # реальные данные не трогаем
|
assert row[46] == "40817810106240020211" # реальные данные не трогаем
|
||||||
|
|
||||||
|
|
||||||
|
def test_col45_keeps_zero_account_from_xml_for_5016() -> None:
|
||||||
|
"""Заказчик 24.09.2026: "в эти операциях не тянутся нули в колонку счет
|
||||||
|
банка получателя". В XML операций 5016 реально лежит
|
||||||
|
СчетБанкПолучатель = 00000000000000000000, а прежняя ветка правил 44-45
|
||||||
|
затирала всю пару корсчетов по коду 5016."""
|
||||||
|
row = build_fixed_row_by_index(
|
||||||
|
file_name="f.xml",
|
||||||
|
record_id="R1",
|
||||||
|
operation_index=1,
|
||||||
|
operation_fields={
|
||||||
|
"КодОперации": "5016",
|
||||||
|
"ВидПереводДС": "5",
|
||||||
|
"ТипОператорДС": "2",
|
||||||
|
"СчетБанкПолучатель": "00000000000000000000",
|
||||||
|
},
|
||||||
|
participant_fields={},
|
||||||
|
)
|
||||||
|
assert row[45] == "00000000000000000000"
|
||||||
|
# Заглушки для 5016 по-прежнему не подставляются.
|
||||||
|
assert row[38] == ""
|
||||||
|
assert row[44] == ""
|
||||||
|
assert row[46] == ""
|
||||||
|
|
||||||
|
|
||||||
|
def test_cash_receipt_and_status_filled_for_5016_transfer_type_5() -> None:
|
||||||
|
"""Заказчик 24.09.2026: при виде перевода 5 должны быть заполнены блок
|
||||||
|
приёма наличных, блок выдачи наличных и статус перевода — колонки AV-BX,
|
||||||
|
то есть 48-76, в зависимости от наличия сведений."""
|
||||||
|
row = build_fixed_row_by_index(
|
||||||
|
file_name="f.xml",
|
||||||
|
record_id="R1",
|
||||||
|
operation_index=1,
|
||||||
|
operation_fields={
|
||||||
|
"КодОперации": "5016",
|
||||||
|
"ВидПереводДС": "5",
|
||||||
|
"ТипОператорДС": "2",
|
||||||
|
"СведенияПереводыДС.СведПриемНалДС.ИдТерминал": "ATM-111",
|
||||||
|
"СведенияПереводыДС.СведПриемНалДС.НаимКО": "Банк приёма",
|
||||||
|
"СведенияПереводыДС.СведПриемНалДС.БИККО": "040813733",
|
||||||
|
"СведенияПереводыДС.СтатусПеревод": "1",
|
||||||
|
"СведенияПереводыДС.СведВыдачаНалДС.ИдТерминал": "ATM-222",
|
||||||
|
"СведенияПереводыДС.СведВыдачаНалДС.НаимКО": "Банк выдачи",
|
||||||
|
"СведенияПереводыДС.СведВыдачаНалДС.БИККО": "041012731",
|
||||||
|
},
|
||||||
|
participant_fields={},
|
||||||
|
)
|
||||||
|
assert row[48] == "ATM-111"
|
||||||
|
assert row[60] == "Банк приёма"
|
||||||
|
assert row[61] == "040813733"
|
||||||
|
assert row[62] == "1"
|
||||||
|
assert row[63] == "ATM-222"
|
||||||
|
assert row[75] == "Банк выдачи"
|
||||||
|
assert row[76] == "041012731"
|
||||||
|
|
||||||
|
|
||||||
|
def test_transfer_status_is_not_limited_to_transfer_types_2_5_8() -> None:
|
||||||
|
"""Прежнее правило 62 выводило статус только для видов перевода 2, 5 и 8.
|
||||||
|
По общему правилу заказчика статус выводится всегда, когда тег есть
|
||||||
|
в XML."""
|
||||||
|
row = build_fixed_row_by_index(
|
||||||
|
file_name="f.xml",
|
||||||
|
record_id="R1",
|
||||||
|
operation_index=1,
|
||||||
|
operation_fields={
|
||||||
|
"ВидПереводДС": "1",
|
||||||
|
"СведенияПереводыДС.СтатусПеревод": "0",
|
||||||
|
},
|
||||||
|
participant_fields={},
|
||||||
|
)
|
||||||
|
assert row[62] == "0"
|
||||||
|
|
||||||
|
|
||||||
|
def test_metal_name_is_not_limited_to_code_c99() -> None:
|
||||||
|
"""Прежнее правило 30 выводило наименование металла только при коде C99.
|
||||||
|
В доступных выгрузках встречается код A90, и по общему правилу заказчика
|
||||||
|
наименование должно попадать в отчёт при любом коде."""
|
||||||
|
row = build_fixed_row_by_index(
|
||||||
|
file_name="f.xml",
|
||||||
|
record_id="R1",
|
||||||
|
operation_index=1,
|
||||||
|
operation_fields={
|
||||||
|
"СведДрагМеталл.КодДрагМеталл": "A90",
|
||||||
|
"СведДрагМеталл.НаимДрагМеталл": "Золото",
|
||||||
|
},
|
||||||
|
participant_fields={},
|
||||||
|
)
|
||||||
|
assert row[29] == "A90"
|
||||||
|
assert row[30] == "Золото"
|
||||||
|
|
||||||
|
|
||||||
def test_col38_44_payer_accounts_still_get_placeholder_without_5016() -> None:
|
def test_col38_44_payer_accounts_still_get_placeholder_without_5016() -> None:
|
||||||
"""Убеждаемся, что правка п.6 не задела остальные виды перевода —
|
"""Убеждаемся, что правка п.6 не задела остальные виды перевода —
|
||||||
заглушка по-прежнему подставляется, если 5016 нет в кодах операции."""
|
заглушка по-прежнему подставляется, если 5016 нет в кодах операции."""
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user