optimization
This commit is contained in:
parent
b9d4ba6573
commit
4482179e82
@ -153,11 +153,20 @@ def build_fixed_row(
|
|||||||
"Уникальный номер операции": str(operation_index),
|
"Уникальный номер операции": str(operation_index),
|
||||||
}
|
}
|
||||||
merged = _merge_fields(operation_fields, participant_fields)
|
merged = _merge_fields(operation_fields, participant_fields)
|
||||||
|
merged_suffix_index = _build_suffix_index(merged)
|
||||||
|
participant_suffix_index = _build_suffix_index(participant_fields)
|
||||||
for rule in REPORT_MAPPING_RULES:
|
for rule in REPORT_MAPPING_RULES:
|
||||||
if row.get(rule.column_name):
|
if row.get(rule.column_name):
|
||||||
continue
|
continue
|
||||||
source_payload = participant_fields if rule.source == "participant" else merged
|
if rule.source == "participant":
|
||||||
row[rule.column_name] = _pick_value(source_payload, rule.candidate_keys)
|
source_payload = participant_fields
|
||||||
|
suffix_index = participant_suffix_index
|
||||||
|
else:
|
||||||
|
source_payload = merged
|
||||||
|
suffix_index = merged_suffix_index
|
||||||
|
row[rule.column_name] = _pick_value(
|
||||||
|
source_payload, suffix_index, rule.candidate_keys
|
||||||
|
)
|
||||||
for column in FIXED_REPORT_COLUMNS:
|
for column in FIXED_REPORT_COLUMNS:
|
||||||
row.setdefault(column, "")
|
row.setdefault(column, "")
|
||||||
return row
|
return row
|
||||||
@ -173,17 +182,27 @@ def _merge_fields(
|
|||||||
return merged
|
return merged
|
||||||
|
|
||||||
|
|
||||||
def _pick_value(payload: dict[str, str], candidates: tuple[str, ...]) -> str:
|
def _build_suffix_index(payload: dict[str, str]) -> dict[str, str]:
|
||||||
|
index: dict[str, str] = {}
|
||||||
|
for key, value in payload.items():
|
||||||
|
if not value:
|
||||||
|
continue
|
||||||
|
short = key.rsplit(".", maxsplit=1)[-1]
|
||||||
|
index.setdefault(short, value)
|
||||||
|
return index
|
||||||
|
|
||||||
|
|
||||||
|
def _pick_value(
|
||||||
|
payload: dict[str, str],
|
||||||
|
suffix_index: dict[str, str],
|
||||||
|
candidates: tuple[str, ...],
|
||||||
|
) -> str:
|
||||||
for key in candidates:
|
for key in candidates:
|
||||||
if key in payload and payload[key]:
|
if key in payload and payload[key]:
|
||||||
return payload[key]
|
return payload[key]
|
||||||
short = key.split(".")[-1]
|
short = key.rsplit(".", maxsplit=1)[-1]
|
||||||
if short in payload and payload[short]:
|
if short in payload and payload[short]:
|
||||||
return payload[short]
|
return payload[short]
|
||||||
dotted_suffix = f".{short}"
|
if short in suffix_index:
|
||||||
for payload_key, payload_value in payload.items():
|
return suffix_index[short]
|
||||||
if not payload_value:
|
|
||||||
continue
|
|
||||||
if payload_key.endswith(dotted_suffix):
|
|
||||||
return payload_value
|
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import time
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@ -39,6 +40,7 @@ class BatchResult:
|
|||||||
protocol_path: str
|
protocol_path: str
|
||||||
log_path: str
|
log_path: str
|
||||||
messages: list[str] = field(default_factory=list)
|
messages: list[str] = field(default_factory=list)
|
||||||
|
duration_seconds: float = 0.0
|
||||||
|
|
||||||
|
|
||||||
def run_batch(
|
def run_batch(
|
||||||
@ -48,6 +50,7 @@ def run_batch(
|
|||||||
samba_password: str,
|
samba_password: str,
|
||||||
launcher: str,
|
launcher: str,
|
||||||
) -> BatchResult:
|
) -> BatchResult:
|
||||||
|
started_at = time.perf_counter()
|
||||||
messages: list[str] = []
|
messages: list[str] = []
|
||||||
if not samba_user:
|
if not samba_user:
|
||||||
return BatchResult(
|
return BatchResult(
|
||||||
@ -195,6 +198,8 @@ def run_batch(
|
|||||||
status=status, processed=processed, partial=partial, errors=errors
|
status=status, processed=processed, partial=partial, errors=errors
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
duration_seconds = round(time.perf_counter() - started_at, 2)
|
||||||
|
messages.append(f"Время выполнения: {_format_duration(duration_seconds)}.")
|
||||||
messages.extend(log_lines[-5:])
|
messages.extend(log_lines[-5:])
|
||||||
return BatchResult(
|
return BatchResult(
|
||||||
status=status,
|
status=status,
|
||||||
@ -205,6 +210,7 @@ def run_batch(
|
|||||||
protocol_path=protocol_path,
|
protocol_path=protocol_path,
|
||||||
log_path=log_path,
|
log_path=log_path,
|
||||||
messages=messages,
|
messages=messages,
|
||||||
|
duration_seconds=duration_seconds,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -362,3 +368,11 @@ def _build_result_message(
|
|||||||
f"успешно={processed}, частично={partial}, с ошибками={errors}."
|
f"успешно={processed}, частично={partial}, с ошибками={errors}."
|
||||||
)
|
)
|
||||||
return f"Ошибка обработки: успешно={processed}, частично={partial}, с ошибками={errors}."
|
return f"Ошибка обработки: успешно={processed}, частично={partial}, с ошибками={errors}."
|
||||||
|
|
||||||
|
|
||||||
|
def _format_duration(duration_seconds: float) -> str:
|
||||||
|
total_seconds = max(0, int(round(duration_seconds)))
|
||||||
|
minutes, seconds = divmod(total_seconds, 60)
|
||||||
|
if minutes:
|
||||||
|
return f"{minutes} мин {seconds} сек"
|
||||||
|
return f"{seconds} сек"
|
||||||
|
|||||||
@ -121,3 +121,31 @@ def test_extract_tag_candidate_keys_supports_comma_separator() -> None:
|
|||||||
"КППЮЛ, ИдентификацияФЛ, ПризнакОргФормаИНБОЮЛ"
|
"КППЮЛ, ИдентификацияФЛ, ПризнакОргФормаИНБОЮЛ"
|
||||||
)
|
)
|
||||||
assert candidates == ("КППЮЛ", "ИдентификацияФЛ", "ПризнакОргФормаИНБОЮЛ")
|
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"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user