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>
This commit is contained in:
@@ -16,6 +16,7 @@ from app.core import crypto
|
||||
from app.db.models.cash_register import CashRegister
|
||||
from app.db.models.order import Order
|
||||
from app.db.models.receipt import Receipt, ReceiptStatus
|
||||
from app.db.models.user import User
|
||||
from app.schemas.checkbox import EttnStatus
|
||||
from app.services import receipts as svc
|
||||
from app.services.checkbox.client import CheckboxRateLimitedError, CheckboxUnavailableError
|
||||
@@ -182,6 +183,52 @@ class TestBuildBody:
|
||||
assert "delivery" not in body["receipt_body"]
|
||||
|
||||
|
||||
class TestRequestReceipts:
|
||||
"""Чек создаётся от кассы, к которой опрос НП привязал заказ."""
|
||||
|
||||
class Session:
|
||||
def __init__(self, registers: list[CashRegister], orders: list[Order]) -> None:
|
||||
self.registers, self.orders, self.added = registers, orders, []
|
||||
|
||||
async def scalars(self, statement: Any) -> list[Any]:
|
||||
entity = statement.column_descriptions[0]["entity"]
|
||||
if entity is CashRegister:
|
||||
return self.registers
|
||||
if entity is Order:
|
||||
return self.orders
|
||||
return [] # активные чеки заказов
|
||||
|
||||
def add(self, obj: Any) -> None:
|
||||
self.added.append(obj)
|
||||
|
||||
@staticmethod
|
||||
def _user() -> User:
|
||||
return User(id=uuid.uuid4(), email="c@x.ua")
|
||||
|
||||
async def test_uses_order_register(self) -> None:
|
||||
default, other = _register(), _register()
|
||||
order = _order(cash_register_id=other.id)
|
||||
session = self.Session([default, other], [order])
|
||||
|
||||
result = await svc.request_receipts(
|
||||
session, [(order.id, None)], user=self._user() # type: ignore[arg-type]
|
||||
)
|
||||
|
||||
assert result.errors == {}
|
||||
assert result.created[0].cash_register_id == other.id
|
||||
|
||||
async def test_unbound_order_is_rejected(self) -> None:
|
||||
order = _order(cash_register_id=None)
|
||||
session = self.Session([_register()], [order])
|
||||
|
||||
result = await svc.request_receipts(
|
||||
session, [(order.id, None)], user=self._user() # type: ignore[arg-type]
|
||||
)
|
||||
|
||||
assert result.created == []
|
||||
assert "Касса не определена" in result.errors[order.id]
|
||||
|
||||
|
||||
class FakeSession:
|
||||
def __init__(self, *objects: Any) -> None:
|
||||
self.objects = {(type(o), o.id): o for o in objects}
|
||||
|
||||
Reference in New Issue
Block a user