add newsletter

This commit is contained in:
2026-05-20 10:11:47 +03:00
parent 2cc2f12a21
commit 5c7a9710f3
9 changed files with 957 additions and 11 deletions

View File

@@ -39,15 +39,17 @@ class AppliedDiscount:
plan_code: str | None = None
expires_at: datetime | None = None
def applies_to_plan(self, plan_code: str) -> bool:
def applies_to_plan(self, plan_code: str, *, days: int | None = None) -> bool:
if not self.code:
return False
if self.plan_code is None:
return True
# "all_30" matches any product with 30 days (vpn_white_30, white_30, vpn_30)
# "all_30" matches any product with 30 days, including single-duration product codes.
if self.plan_code.startswith("all_"):
suffix = self.plan_code.removeprefix("all") # "_30"
return plan_code.endswith(suffix)
raw_days = self.plan_code.removeprefix("all_")
return raw_days.isdigit() and (
plan_code.endswith(f"_{raw_days}") or days == int(raw_days)
)
# Exact match or product-prefix match (e.g. promo plan_code="vpn_white" matches plan "vpn_white_30")
return self.plan_code == plan_code or plan_code.startswith(f"{self.plan_code}_")
@@ -535,7 +537,10 @@ class PaymentService:
) -> PaymentPlan:
resolved_discount = (
applied_discount
if applied_discount.applies_to_plan(plan_settings.code)
if applied_discount.applies_to_plan(
plan_settings.code,
days=plan_settings.days,
)
else AppliedDiscount()
)
discount_percent = max(resolved_discount.discount_percent, 0)