fix
This commit is contained in:
parent
bef38dedd8
commit
510d668ab8
@ -27,6 +27,7 @@ COL_SUSPICIOUS_ID = _index(28)
|
||||
COL_METAL_CODE = _index(29)
|
||||
COL_METAL_NAME = _index(30)
|
||||
COL_ITEM_TYPE = _index(31)
|
||||
COL_EXTRA_INFO = _index(34)
|
||||
|
||||
# Перевод.
|
||||
COL_TRANSFER_TYPE = _index(35)
|
||||
@ -101,7 +102,7 @@ PARTICIPANT_ADDRESS_OUTPUT_SOURCES: dict[int, int] = {
|
||||
|
||||
# Бизнес-константы.
|
||||
ACCOUNT_PLACEHOLDER = "00000000000000000000"
|
||||
CURRENCY_OPERATION_CODES = frozenset(str(code) for code in range(6101, 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"}
|
||||
)
|
||||
|
||||
@ -19,13 +19,13 @@ from .column_constants import (
|
||||
COL_COUNTRY_CODE,
|
||||
COL_CP_ISSUER_INN,
|
||||
COL_CURRENCY,
|
||||
COL_CURRENCY_SIGN,
|
||||
COL_EIO_ADDRESS_ONE_LINE,
|
||||
COL_EIO_INN,
|
||||
COL_EIO_REG_PLACE_ONE_LINE,
|
||||
COL_EMPLOYEE_SIGN,
|
||||
COL_ESP_SIGN,
|
||||
COL_EXTRA_CODES,
|
||||
COL_EXTRA_INFO,
|
||||
COL_FILE_NAME,
|
||||
COL_FOREIGN_BANK_NAME,
|
||||
COL_FTR_SIGN,
|
||||
@ -63,8 +63,8 @@ from .column_constants import (
|
||||
COL_TRANSFER_STATUS,
|
||||
COL_TRANSFER_TYPE,
|
||||
COL_UNUSUAL_CODES,
|
||||
CURRENCY_OPERATION_CODES,
|
||||
EMPLOYEE_ABSENT_CODE,
|
||||
EXPORT_SUBSIDIARY_COMMENT_CODES,
|
||||
OKATO_COUNTRY_PAIRS,
|
||||
PARTICIPANT_TYPE_FL,
|
||||
PARTICIPANT_TYPE_FLCHP,
|
||||
@ -389,6 +389,8 @@ def build_fixed_row_by_index(
|
||||
row,
|
||||
has_eio_block=has_eio_block,
|
||||
has_cp_block=has_cp_block,
|
||||
operation_fields=operation_fields,
|
||||
participant_fields=participant_fields,
|
||||
)
|
||||
else:
|
||||
_apply_continuation_validation_rules(row)
|
||||
@ -472,6 +474,14 @@ def _pick_scoped_payload_value(payload: dict[str, str], scoped_path: str) -> str
|
||||
return ""
|
||||
|
||||
|
||||
def _pick_direct_payload_value(payload: dict[str, str], field_name: str) -> str:
|
||||
"""Возвращает только прямое поле текущего XML-блока без suffix-поиска."""
|
||||
for key, value in payload.items():
|
||||
if value and _normalize_indexed_path(key) == field_name:
|
||||
return str(value).strip()
|
||||
return ""
|
||||
|
||||
|
||||
def _apply_participant_identity_rules(
|
||||
row: dict[int, str], participant_fields: dict[str, str]
|
||||
) -> None:
|
||||
@ -633,6 +643,8 @@ def _apply_business_rules(
|
||||
*,
|
||||
has_eio_block: bool,
|
||||
has_cp_block: bool,
|
||||
operation_fields: dict[str, str],
|
||||
participant_fields: dict[str, str],
|
||||
) -> None:
|
||||
codes = _operation_codes(row)
|
||||
operation_sign = _get(row, COL_OPERATION_SIGN)
|
||||
@ -646,7 +658,7 @@ def _apply_business_rules(
|
||||
_rule_unusual_codes(row, codes)
|
||||
_rule_digital_rights_currency(row, operation_sign)
|
||||
_rule_sale_currency(row)
|
||||
_rule_currency_sign(row, codes)
|
||||
_rule_extra_info(row, codes, operation_fields, participant_fields)
|
||||
_rule_suspicious_activity(row, codes)
|
||||
_rule_metal_name(row)
|
||||
_rule_item_type(row, codes)
|
||||
@ -725,10 +737,26 @@ def _rule_sale_currency(row: dict[int, str]) -> None:
|
||||
_set(row, COL_SALE_AMOUNT, "")
|
||||
|
||||
|
||||
def _rule_currency_sign(row: dict[int, str], codes: set[str]) -> None:
|
||||
"""Правило 27: признак VO только для валютных операций 6101-6126."""
|
||||
if not codes & CURRENCY_OPERATION_CODES:
|
||||
_set(row, COL_CURRENCY_SIGN, "")
|
||||
def _rule_extra_info(
|
||||
row: dict[int, str],
|
||||
codes: set[str],
|
||||
operation_fields: dict[str, str],
|
||||
participant_fields: dict[str, str],
|
||||
) -> None:
|
||||
"""Правило 34: объединяет допустимые комментарии операции и участника."""
|
||||
operation_comment = _pick_direct_payload_value(operation_fields, "Коммент")
|
||||
participant_comment = ""
|
||||
if codes & EXPORT_SUBSIDIARY_COMMENT_CODES:
|
||||
participant_comment = _pick_direct_payload_value(
|
||||
participant_fields, "КомментУчастник"
|
||||
)
|
||||
|
||||
values = list(
|
||||
dict.fromkeys(
|
||||
value for value in (operation_comment, participant_comment) if value
|
||||
)
|
||||
)
|
||||
_set(row, COL_EXTRA_INFO, "; ".join(values))
|
||||
|
||||
|
||||
def _rule_suspicious_activity(row: dict[int, str], codes: set[str]) -> None:
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
"xml_path": "/ММ/ГГГГ",
|
||||
"source_scope": "any",
|
||||
"allow_short_lookup": true,
|
||||
"allow_direct_mapping": true,
|
||||
"allow_direct_mapping": false,
|
||||
"structured_value": false,
|
||||
"structured_group": "",
|
||||
"structured_role": "",
|
||||
@ -665,11 +665,11 @@
|
||||
"column_name": "Доп. сведения",
|
||||
"block": "operation_base",
|
||||
"report_group": "operation_parameters",
|
||||
"xml_tag": "КомментУчастник",
|
||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/УчастникОп/КомментУчастник",
|
||||
"xml_tag": "Коммент | КомментУчастник",
|
||||
"xml_path": "/СообщОперКО/ИнформЧасть/СведКО/Операция/Коммент | /СообщОперКО/ИнформЧасть/СведКО/Операция/УчастникОп/КомментУчастник",
|
||||
"source_scope": "any",
|
||||
"allow_short_lookup": true,
|
||||
"allow_direct_mapping": true,
|
||||
"allow_direct_mapping": false,
|
||||
"structured_value": false,
|
||||
"structured_group": "",
|
||||
"structured_role": "",
|
||||
|
||||
@ -937,7 +937,7 @@ def test_cp_block_is_empty_without_sved_cp_and_uses_emitent_inn_when_present() -
|
||||
assert row_with_cp[202] == "7707083893"
|
||||
|
||||
|
||||
def test_currency_columns_apply_only_to_conversion_and_currency_operations() -> None:
|
||||
def test_currency_sign_is_preserved_independently_of_operation_code() -> None:
|
||||
non_conversion = build_fixed_row_by_index(
|
||||
file_name="f.xml",
|
||||
record_id="R1",
|
||||
@ -950,7 +950,7 @@ def test_currency_columns_apply_only_to_conversion_and_currency_operations() ->
|
||||
participant_fields={},
|
||||
)
|
||||
assert non_conversion[26] == ""
|
||||
assert non_conversion[27] == ""
|
||||
assert non_conversion[27] == "VO"
|
||||
|
||||
conversion = build_fixed_row_by_index(
|
||||
file_name="f.xml",
|
||||
@ -993,7 +993,95 @@ def test_currency_columns_apply_only_to_conversion_and_currency_operations() ->
|
||||
},
|
||||
participant_fields={},
|
||||
)
|
||||
assert boundary_row[27] == ""
|
||||
assert boundary_row[27] == "VO"
|
||||
|
||||
|
||||
def test_extra_info_uses_operation_comment() -> None:
|
||||
row = build_fixed_row_by_index(
|
||||
file_name="f.xml",
|
||||
record_id="R1",
|
||||
operation_index=1,
|
||||
operation_fields={"КодОперации": "9003", "Коммент": "Комментарий операции"},
|
||||
participant_fields={},
|
||||
)
|
||||
|
||||
assert row[34] == "Комментарий операции"
|
||||
|
||||
|
||||
def test_extra_info_ignores_nested_operation_comment() -> None:
|
||||
row = build_fixed_row_by_index(
|
||||
file_name="f.xml",
|
||||
record_id="R1",
|
||||
operation_index=1,
|
||||
operation_fields={
|
||||
"КодОперации": "9003",
|
||||
"СведенияПереводыДС.Коммент": "Комментарий вложенного блока",
|
||||
},
|
||||
participant_fields={},
|
||||
)
|
||||
|
||||
assert row[34] == ""
|
||||
|
||||
|
||||
def test_extra_info_rejects_participant_comment_outside_allowed_codes() -> None:
|
||||
row = build_fixed_row_by_index(
|
||||
file_name="f.xml",
|
||||
record_id="R1",
|
||||
operation_index=1,
|
||||
operation_fields={"КодОперации": "9003"},
|
||||
participant_fields={"КомментУчастник": "Посторонний комментарий"},
|
||||
)
|
||||
|
||||
assert row[34] == ""
|
||||
|
||||
|
||||
def test_extra_info_is_not_directly_mapped_on_continuation_row() -> None:
|
||||
row = build_fixed_row_by_index(
|
||||
file_name="f.xml",
|
||||
record_id="R1",
|
||||
operation_index=1,
|
||||
operation_fields={"КодОперации": "9003"},
|
||||
participant_fields={"КомментУчастник": "Посторонний комментарий"},
|
||||
is_continuation=True,
|
||||
)
|
||||
|
||||
assert row[34] == ""
|
||||
|
||||
|
||||
def test_extra_info_accepts_participant_comment_for_main_or_extra_code() -> None:
|
||||
for operation_fields in (
|
||||
{"КодОперации": "6102"},
|
||||
{"КодОперации": "9003", "ДопКодОперации": "6126"},
|
||||
):
|
||||
row = build_fixed_row_by_index(
|
||||
file_name="f.xml",
|
||||
record_id="R1",
|
||||
operation_index=1,
|
||||
operation_fields=operation_fields,
|
||||
participant_fields={"КомментУчастник": "Комментарий участника"},
|
||||
)
|
||||
|
||||
assert row[34] == "Комментарий участника"
|
||||
|
||||
|
||||
def test_extra_info_joins_distinct_allowed_comments_without_duplicates() -> None:
|
||||
combined = build_fixed_row_by_index(
|
||||
file_name="f.xml",
|
||||
record_id="R1",
|
||||
operation_index=1,
|
||||
operation_fields={"КодОперации": "6102", "Коммент": "Общий комментарий"},
|
||||
participant_fields={"КомментУчастник": "Комментарий участника"},
|
||||
)
|
||||
duplicate = build_fixed_row_by_index(
|
||||
file_name="f.xml",
|
||||
record_id="R2",
|
||||
operation_index=2,
|
||||
operation_fields={"КодОперации": "6102", "Коммент": "Одинаковый текст"},
|
||||
participant_fields={"КомментУчастник": "Одинаковый текст"},
|
||||
)
|
||||
|
||||
assert combined[34] == "Общий комментарий; Комментарий участника"
|
||||
assert duplicate[34] == "Одинаковый текст"
|
||||
|
||||
|
||||
def test_bank_bik_columns_accept_canonical_transfer_block_spelling() -> None:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user