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:
@@ -63,7 +63,7 @@ def get_checkbox_client() -> CheckboxClient:
|
||||
"""Один экземпляр на процесс: внутри — кэш токенов кассиров."""
|
||||
if settings.checkbox_use_stub:
|
||||
if settings.is_production:
|
||||
raise RuntimeError("CHECKBOX_USE_STUB=true запрещён в production")
|
||||
raise RuntimeError("CHECKBOX_USE_STUB=true заборонено в production")
|
||||
from app.services.checkbox.stub_client import StubCheckboxClient
|
||||
|
||||
return StubCheckboxClient(auto_complete_after=2)
|
||||
|
||||
@@ -57,7 +57,7 @@ def _error_message(response: httpx.Response) -> str:
|
||||
# {"code": "third_party.*", "message": "Internal Server Error"} —
|
||||
# без кода кассир видит только бесполезное «Internal Server Error».
|
||||
if code := data.get("code"):
|
||||
message = f"{message or 'Ошибка'} ({code})"
|
||||
message = f"{message or 'Помилка'} ({code})"
|
||||
if isinstance(detail, list) and detail:
|
||||
parts = [
|
||||
f"{'.'.join(str(p) for p in item.get('loc', []))}: {item.get('msg')}"
|
||||
@@ -130,7 +130,7 @@ class HttpCheckboxClient:
|
||||
method, path, headers=headers, json=json, params=params
|
||||
)
|
||||
except httpx.HTTPError as exc:
|
||||
raise CheckboxUnavailableError(f"Checkbox недоступен: {exc!r}") from exc
|
||||
raise CheckboxUnavailableError(f"Checkbox недоступний: {exc!r}") from exc
|
||||
if error := _transient_error(response):
|
||||
raise error
|
||||
return response
|
||||
@@ -155,7 +155,7 @@ class HttpCheckboxClient:
|
||||
json={"pin_code": creds.pin_code},
|
||||
)
|
||||
if response.status_code != 200:
|
||||
raise CheckboxError(f"Вход кассира не удался: {_error_message(response)}")
|
||||
raise CheckboxError(f"Вхід касира не вдався: {_error_message(response)}")
|
||||
token = response.json()["access_token"]
|
||||
self._tokens[creds.cash_register_id] = token
|
||||
return token
|
||||
|
||||
@@ -32,12 +32,12 @@ class StubCheckboxClient:
|
||||
|
||||
async def sign_in(self, creds: CheckboxCredentials) -> None:
|
||||
if not creds.license_key or not creds.pin_code:
|
||||
raise CheckboxError("Вход кассира не удался: пустой ключ или PIN")
|
||||
raise CheckboxError("Вхід касира не вдався: порожній ключ або PIN")
|
||||
|
||||
async def create_ettn(self, creds: CheckboxCredentials, body: dict[str, Any]) -> EttnOut:
|
||||
waybill = body["receipt_body"]["payments"][0]["ettn"]
|
||||
if await self.find_ettn(creds, waybill) is not None:
|
||||
raise CheckboxError(f"ЕТТН {waybill} уже привязана к чеку")
|
||||
raise CheckboxError(f"ЕТТН {waybill} вже прив'язана до чека")
|
||||
ettn = EttnOut(
|
||||
id=str(uuid.uuid4()),
|
||||
status=EttnStatus.CREATED,
|
||||
@@ -50,7 +50,7 @@ class StubCheckboxClient:
|
||||
|
||||
async def get_ettn(self, creds: CheckboxCredentials, ettn_id: str) -> EttnOut:
|
||||
if ettn_id not in self.orders:
|
||||
raise CheckboxError(f"ЕТТН-чек {ettn_id} не найден")
|
||||
raise CheckboxError(f"ЕТТН-чек {ettn_id} не знайдено")
|
||||
self._polls[ettn_id] = self._polls.get(ettn_id, 0) + 1
|
||||
if (
|
||||
self.auto_complete_after is not None
|
||||
|
||||
Reference in New Issue
Block a user