"""Лимит устройств (HWID): база 10, каждое сверх — 50 ₽.""" from __future__ import annotations from dataclasses import dataclass BASE_DEVICES = 10 EXTRA_DEVICE_PRICE_RUB = 50.0 # Сколько устройств панель может зарегистрировать максимум (мягкий потолок). # Реальная квота: BASE_DEVICES + оплаченные слоты; при превышении — DISABLE. PANEL_SOFT_CAP = 100 @dataclass(frozen=True, slots=True) class DevicePack: slots: int price: float @property def id(self) -> str: return f"dev_{self.slots}" @property def title(self) -> str: return f"+{self.slots} устр." def format_price(self) -> str: if self.price == int(self.price): return f"{int(self.price)} ₽/мес" return f"{self.price:.2f} ₽/мес" DEVICE_PACKS: tuple[DevicePack, ...] = tuple( DevicePack(slots=n, price=EXTRA_DEVICE_PRICE_RUB * n) for n in (1, 2, 3, 5) ) def get_device_pack(pack_id: str) -> DevicePack | None: for p in DEVICE_PACKS: if p.id == pack_id or str(p.slots) == pack_id: return p return None @dataclass(frozen=True, slots=True) class DeviceUsage: used: int allowed: int extra_paid: int over_limit: bool @property def excess(self) -> int: return max(0, self.used - self.allowed) @property def excess_price(self) -> float: return self.excess * EXTRA_DEVICE_PRICE_RUB def format_line(self) -> str: line = ( f"📱 Устройства: {self.used} / {self.allowed} " f"(база {BASE_DEVICES}" + (f" + {self.extra_paid} доп." if self.extra_paid else "") + ")" ) if self.over_limit: line += ( f"\n⚠️ Превышение: +{self.excess} · " f"к оплате {int(self.excess_price)} ₽\n" "Подписка отключена, пока не оплатишь лишние устройства " f"({int(EXTRA_DEVICE_PRICE_RUB)} ₽ за каждое)." ) return line def as_dict(self) -> dict: return { "used": self.used, "allowed": self.allowed, "base": BASE_DEVICES, "extra_paid": self.extra_paid, "over_limit": self.over_limit, "excess": self.excess, "excess_price": self.excess_price, "slot_price": EXTRA_DEVICE_PRICE_RUB, } def allowed_devices(extra_paid: int) -> int: return BASE_DEVICES + max(0, int(extra_paid or 0))