Translate UI and user-facing messages to Ukrainian (#5)
- All frontend pages, labels, notices and errors; html lang=uk, uk-UA money format - Brand "Assistant System" in the top bar and page title - Backend error details returned to the UI (auth, orders, receipts, cash registers, Checkbox/CRM/NP errors) and CLI output - Tests updated for the new messages Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -110,7 +110,7 @@ class TestNpTrackingClientGetStatuses:
|
||||
async def test_rejects_too_many_documents(self) -> None:
|
||||
client = NpTrackingClient()
|
||||
|
||||
with pytest.raises(NovaPoshtaError, match="Слишком много"):
|
||||
with pytest.raises(NovaPoshtaError, match="Забагато"):
|
||||
await client.get_statuses(
|
||||
api_key=API_KEY, waybill_numbers=[str(i) for i in range(101)]
|
||||
)
|
||||
|
||||
@@ -88,7 +88,7 @@ def _patch_orders_service(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
session: object, order_id: str, data: object
|
||||
) -> tuple[Order, list[str]] | None:
|
||||
if order_id == "locked":
|
||||
raise orders_router.orders_service.OrderEditError("По заказу уже создан чек")
|
||||
raise orders_router.orders_service.OrderEditError("За замовленням уже створено чек")
|
||||
if order_id != "1":
|
||||
return None
|
||||
order = _order(order_id)
|
||||
|
||||
@@ -140,16 +140,16 @@ class TestUpdateOrder:
|
||||
assert order.goods == [stored]
|
||||
|
||||
def test_total_above_goods_sum_is_rejected(self) -> None:
|
||||
with pytest.raises(OrderEditError, match="больше суммы товаров"):
|
||||
with pytest.raises(OrderEditError, match="більша за суму товарів"):
|
||||
_update(_order(), _payload(total_amount="1200.00"))
|
||||
|
||||
def test_discount_above_line_sum_is_rejected(self) -> None:
|
||||
good = {"name": "Товар", "price": "10.00", "quantity": "1", "discount_amount": "11"}
|
||||
with pytest.raises(OrderEditError, match="скидка больше"):
|
||||
with pytest.raises(OrderEditError, match="знижка більша"):
|
||||
_update(_order(), _payload(goods=[good], total_amount="0"))
|
||||
|
||||
def test_order_with_receipt_is_locked(self) -> None:
|
||||
with pytest.raises(OrderEditError, match="уже создан чек"):
|
||||
with pytest.raises(OrderEditError, match="уже створено чек"):
|
||||
_update(_order(receipt_created_at=datetime.now(UTC)), _payload())
|
||||
|
||||
def test_missing_or_deleted_order_returns_none(self) -> None:
|
||||
|
||||
@@ -45,7 +45,9 @@ def queue(monkeypatch: pytest.MonkeyPatch) -> FakeQueue:
|
||||
)
|
||||
|
||||
async def fake_request(session: Any, items: Any, *, user: Any, request: Any) -> Any:
|
||||
return receipts_service.RequestResult(created=[receipt], errors={"2": "У заказа нет ТТН"})
|
||||
return receipts_service.RequestResult(
|
||||
created=[receipt], errors={"2": "У замовлення немає ТТН"}
|
||||
)
|
||||
|
||||
async def fake_commit(self: AsyncSession) -> None:
|
||||
return None
|
||||
@@ -74,5 +76,5 @@ def test_cashier_creates_and_enqueues(queue: FakeQueue) -> None:
|
||||
assert response.status_code == 202
|
||||
body = response.json()
|
||||
assert [r["order_id"] for r in body["created"]] == ["1"]
|
||||
assert body["errors"] == {"2": "У заказа нет ТТН"}
|
||||
assert body["errors"] == {"2": "У замовлення немає ТТН"}
|
||||
assert queue.jobs == [("create_ettn_receipt", (body["created"][0]["id"],))]
|
||||
|
||||
@@ -77,17 +77,17 @@ class TestResolveAmounts:
|
||||
assert amounts.cod_kopecks == 100000
|
||||
|
||||
def test_explicit_prepayment_must_match_cod(self) -> None:
|
||||
with pytest.raises(svc.ReceiptValidationError, match="≠ наложка"):
|
||||
with pytest.raises(svc.ReceiptValidationError, match="≠ післяплата"):
|
||||
svc.resolve_amounts(_order(np_cod_amount_kopecks=100000), 10000)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("overrides", "message"),
|
||||
[
|
||||
({"waybill_number": None}, "нет ТТН"),
|
||||
({"np_cod_amount_kopecks": None}, "контроля оплаты"),
|
||||
({"np_status_code": "9"}, "не в пути"),
|
||||
({"np_cod_amount_kopecks": 130000}, "больше суммы заказа"),
|
||||
({"is_deleted": True}, "удалён"),
|
||||
({"waybill_number": None}, "немає ТТН"),
|
||||
({"np_cod_amount_kopecks": None}, "контролю оплати"),
|
||||
({"np_status_code": "9"}, "не в дорозі"),
|
||||
({"np_cod_amount_kopecks": 130000}, "більша за суму замовлення"),
|
||||
({"is_deleted": True}, "видалено"),
|
||||
],
|
||||
)
|
||||
def test_rejects(self, overrides: dict[str, Any], message: str) -> None:
|
||||
@@ -226,7 +226,7 @@ class TestRequestReceipts:
|
||||
)
|
||||
|
||||
assert result.created == []
|
||||
assert "Касса не определена" in result.errors[order.id]
|
||||
assert "Касу не визначено" in result.errors[order.id]
|
||||
|
||||
|
||||
class FakeSession:
|
||||
@@ -289,7 +289,7 @@ class TestCreateEttn:
|
||||
await svc.create_ettn_for_receipt(FakeSession(order, register, receipt), client, receipt.id)
|
||||
|
||||
assert receipt.status == ReceiptStatus.FAILED
|
||||
assert "уже привязана" in (receipt.error or "")
|
||||
assert "вже прив'язана" in (receipt.error or "")
|
||||
assert order.receipt_created_at is None
|
||||
|
||||
async def test_unavailable_keeps_pending_then_reconciles(self) -> None:
|
||||
|
||||
Reference in New Issue
Block a user