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>
45 lines
2.1 KiB
Python
45 lines
2.1 KiB
Python
"""Кассы (ПРРО) Checkbox.
|
|
|
|
Ключ лицензии, PIN кассира и ключ API Новой Почты хранятся только в
|
|
зашифрованном виде (`app/core/crypto.py`): утечка дампа БД не должна давать
|
|
доступ к кассе и кабинету отправителя.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from sqlalchemy import Boolean, Index, String, text
|
|
from sqlalchemy.dialects.postgresql import JSONB
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.db.base import Base, TimestampMixin, UUIDPrimaryKeyMixin
|
|
|
|
|
|
class CashRegister(UUIDPrimaryKeyMixin, TimestampMixin, Base):
|
|
__tablename__ = "cash_registers"
|
|
|
|
name: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
fiscal_number: Mapped[str | None] = mapped_column(String(64))
|
|
license_key_enc: Mapped[str] = mapped_column(String(512), nullable=False)
|
|
cashier_pin_enc: Mapped[str] = mapped_column(String(512), nullable=False)
|
|
# Ключ API кабинета отправителя НП. Посылки, которые этот ключ видит как
|
|
# свои, привязываются к кассе (`orders.cash_register_id`), и ЕТТН-чеки по
|
|
# ним создаются от неё. Без ключа касса статусы ТТН не опрашивает.
|
|
np_api_key_enc: Mapped[str | None] = mapped_column(String(512))
|
|
# Коды налоговых ставок Checkbox для всех товаров чека; пусто — поле `tax`
|
|
# не передаётся (неплательщик ПДВ).
|
|
tax_codes: Mapped[list[Any]] = mapped_column(JSONB, nullable=False, default=list)
|
|
is_active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
|
is_default: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
|
|
|
__table_args__ = (
|
|
# Касса по умолчанию может быть только одна.
|
|
Index(
|
|
"uq_cash_registers_default",
|
|
"is_default",
|
|
unique=True,
|
|
postgresql_where=text("is_default"),
|
|
),
|
|
)
|