feat: hwid limits and topups

This commit is contained in:
3252a8
2026-05-03 22:36:33 +03:00
parent 00f8e5fb20
commit aa5a9496ed
21 changed files with 738 additions and 15 deletions
+11
View File
@@ -18,6 +18,16 @@
"squad_uuids": ["uuid-1", "uuid-2"],
"billing_model": "period",
"monthly_gb": 500,
"hwid_device_limit": 5,
"hwid_device_packages": {
"rub": [
{ "count": 1, "price": 99 },
{ "count": 3, "price": 249 }
],
"stars": [
{ "count": 1, "price": 2500 }
]
},
"prices_rub": { "1": 150, "3": 400, "6": 750, "12": 1400 },
"prices_stars": { "1": 0, "3": 0, "6": 0, "12": 0 },
"enabled_periods": [1, 3, 6, 12],
@@ -32,6 +42,7 @@
},
"squad_uuids": ["uuid-1", "uuid-2"],
"billing_model": "traffic",
"hwid_device_limit": 3,
"conversion_rate_rub_per_gb": 20,
"traffic_packages": {
"rub": [
+31
View File
@@ -23,6 +23,19 @@ class TrafficPackage(BaseModel):
return self
class HwidDevicePackage(BaseModel):
count: int
price: float
@model_validator(mode="after")
def validate_values(self) -> "HwidDevicePackage":
if self.count <= 0:
raise ValueError("device package count must be greater than zero")
if self.price < 0:
raise ValueError("device package price must be non-negative")
return self
class PackageSet(BaseModel):
rub: List[TrafficPackage] = Field(default_factory=list)
stars: List[TrafficPackage] = Field(default_factory=list)
@@ -34,6 +47,17 @@ class PackageSet(BaseModel):
return bool(self.rub or self.stars)
class HwidDevicePackageSet(BaseModel):
rub: List[HwidDevicePackage] = Field(default_factory=list)
stars: List[HwidDevicePackage] = Field(default_factory=list)
def for_currency(self, currency: Currency) -> List[HwidDevicePackage]:
return list(getattr(self, currency) or [])
def has_any(self) -> bool:
return bool(self.rub or self.stars)
class Tariff(BaseModel):
key: str
names: Dict[str, str] = Field(default_factory=dict)
@@ -50,6 +74,8 @@ class Tariff(BaseModel):
traffic_packages: Optional[PackageSet] = None
conversion_rate_rub_per_gb: Optional[float] = None
hwid_device_limit: Optional[int] = None
hwid_device_packages: Optional[HwidDevicePackageSet] = None
@model_validator(mode="after")
def validate_tariff(self) -> "Tariff":
@@ -57,6 +83,8 @@ class Tariff(BaseModel):
raise ValueError("tariff key must not be empty")
self.key = self.key.strip()
self.squad_uuids = [uuid.strip() for uuid in self.squad_uuids if uuid.strip()]
if self.hwid_device_limit is not None and self.hwid_device_limit < 0:
raise ValueError(f"tariff {self.key}: hwid_device_limit must be >= 0")
if self.billing_model == "period":
if self.monthly_gb is None or self.monthly_gb < 0:
@@ -119,6 +147,9 @@ class Tariff(BaseModel):
packages = self.traffic_packages.rub if self.traffic_packages else []
return min(float(pkg.price) / float(pkg.gb) for pkg in packages)
def has_hwid_device_packages(self) -> bool:
return bool(self.hwid_device_packages and self.hwid_device_packages.has_any())
class TariffsConfig(BaseModel):
default_tariff: str