Add Nova Poshta tracking: TTN status, COD amount, payment status

Adds NpTrackingClient (Protocol + real/stub impls) and an ARQ worker that
polls Nova Poshta every minute for orders without a receipt, writing
status, net COD amount (Контроль оплати), and payment status onto the
order. Surfaced in the orders table and detail modal. Marks plan stages
3-4 done in README.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-23 22:33:58 +03:00
co-authored by Claude Sonnet 5
parent f4072be451
commit d13e7ce2b3
20 changed files with 496 additions and 14 deletions
+37
View File
@@ -0,0 +1,37 @@
"""ARQ worker: раз в минуту опрашивает Nova Poshta по заказам без чека.
Запускается отдельным процессом: `arq app.worker.WorkerSettings`.
"""
from __future__ import annotations
from typing import Any
from arq import cron
from arq.connections import RedisSettings
from app.core.config import settings
from app.core.logging import configure_logging, get_logger
from app.db.session import SessionFactory
from app.services.nova_poshta.np_client import NpTrackingClient
from app.services.orders import sync_np_statuses
log = get_logger(__name__)
async def startup(ctx: dict[str, Any]) -> None:
configure_logging()
ctx["np_client"] = NpTrackingClient(settings)
log.info("worker_starting", environment=settings.environment)
async def poll_np_statuses(ctx: dict[str, Any]) -> None:
async with SessionFactory() as session:
await sync_np_statuses(session, ctx["np_client"])
log.info("np_statuses_polled")
class WorkerSettings:
redis_settings = RedisSettings.from_dsn(settings.redis_url)
on_startup = startup
cron_jobs = [cron(poll_np_statuses, minute=set(range(60)), run_at_startup=True)]