Files
lux_fiscal/backend/app/services/nova_poshta/stub_client.py
lauadminandClaude Opus 5.5 8b3c2b6d63 Bind Nova Poshta API key to cash register (#3)
Each cash register stores its own encrypted NP API key. Status polling uses
register keys and binds an order to the register whose key sees the TTN as
its own (PhoneSender present); ETTN receipts are created from that register.
Migration 0008 moves the old NOVA_POSHTA_API_KEY into the default register.

Closes #3

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 13:02:40 +03:00

47 lines
1.7 KiB
Python

"""Фикстурный клиент Nova Poshta для тестов — не ходит в сеть."""
from __future__ import annotations
from app.schemas.tracking import TrackingStatusOut
_FIXTURE_STATUSES: dict[str, dict] = {
"20450123456789": {
"Number": "20450123456789",
"Status": "Відправлення отримано",
"StatusCode": "9",
"PaymentMethod": "Cash",
"ScheduledDeliveryDate": "22-09-2026 18:00:00",
"ActualDeliveryDate": "22-09-2026 15:30:00",
"AmountToPay": "1200.00",
"AfterpaymentOnGoodsCost": 1200,
"PaymentStatus": "Paid",
"PhoneSender": "380501112233",
}
}
class StubNovaPoshtaClient:
"""`statuses` — ответы NP по ТТН; `by_key` — отдельные ответы для конкретных
ключей API (кабинет отправителя видит свои ТТН полностью, чужие — урезанно)."""
def __init__(
self,
statuses: dict[str, dict] | None = None,
*,
by_key: dict[str, dict[str, dict]] | None = None,
) -> None:
self._statuses = statuses if statuses is not None else _FIXTURE_STATUSES
self._by_key = by_key or {}
self.calls: list[tuple[str, list[str]]] = []
async def get_statuses(
self, *, api_key: str, waybill_numbers: list[str]
) -> list[TrackingStatusOut]:
self.calls.append((api_key, list(waybill_numbers)))
statuses = self._by_key.get(api_key, self._statuses)
return [
TrackingStatusOut.model_validate(statuses[number])
for number in waybill_numbers
if number in statuses
]