diff --git a/VERSION b/VERSION index 29631e9..c8308ef 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.0+81 +0.1.0+82 diff --git a/user_store.py b/user_store.py index 5e27399..98498a6 100644 --- a/user_store.py +++ b/user_store.py @@ -238,7 +238,11 @@ def ensure_subscription(user_id: int, db_path: str | None = None) -> None: def activate_subscription_days(user_id: int, days: int, db_path: str | None = None) -> int: - """Добавляет срок к текущей подписке и возвращает оставшиеся дни.""" + """Добавляет срок к подписке и возвращает оставшиеся дни (ceil). + + Сложение ведётся по абсолютному UTC-моменту истечения, без округления дней: + это исключает потерю дроби при каждой продлировке (было 10д + 1д -> 10д). + """ if days <= 0: raise ValueError("Subscription days must be positive") with closing(connect(db_path)) as connection, connection: @@ -246,12 +250,9 @@ def activate_subscription_days(user_id: int, days: int, db_path: str | None = No if not sub: raise RuntimeError("Subscription record not found") now = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None) - current_days = _days_until(sub, now) - if current_days > 0: - current_expires = now + datetime.timedelta(days=current_days, seconds=1) - new_expires = current_expires + datetime.timedelta(days=days) - else: - new_expires = now + datetime.timedelta(days=days) + current_expires = _subscription_expires_at(sub) + base = max(now, current_expires) if current_expires is not None else now + new_expires = base + datetime.timedelta(days=days) connection.execute( """ UPDATE subscriptions @@ -260,7 +261,8 @@ def activate_subscription_days(user_id: int, days: int, db_path: str | None = No """, (new_expires.isoformat(), days, user_id), ) - return max(0, (new_expires - now).days) + remaining_seconds = int((new_expires - now).total_seconds()) + return -(-remaining_seconds // 86400) if remaining_seconds > 0 else 0 def activate_subscription(user_id: int, months: int = 1, db_path: str | None = None) -> int: