Refactor subscription duration calculation in PanelWebhookService and SubscriptionService
- Introduced a utility function `add_months` to handle subscription duration calculations based on calendar months instead of a fixed 30-day period. - Updated the auto-renewal logic in `PanelWebhookService` to use the new function for extending subscription end dates. - Adjusted the duration calculation in `SubscriptionService` to derive the end date after a specified number of months, improving accuracy in subscription management.
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
|
||||
def add_months(base_dt: datetime, months_to_add: int) -> datetime:
|
||||
"""Add calendar months to a datetime, clamping the day to the month's length.
|
||||
|
||||
Preserves tzinfo from base_dt.
|
||||
"""
|
||||
year = base_dt.year
|
||||
month = base_dt.month + months_to_add
|
||||
day = base_dt.day
|
||||
|
||||
# Normalize year and month
|
||||
year += (month - 1) // 12
|
||||
month = ((month - 1) % 12) + 1
|
||||
|
||||
# Determine last day of target month by rolling to next month's first day and subtracting 1 day
|
||||
if month == 12:
|
||||
next_month_first = datetime(year + 1, 1, 1, tzinfo=base_dt.tzinfo)
|
||||
else:
|
||||
next_month_first = datetime(year, month + 1, 1, tzinfo=base_dt.tzinfo)
|
||||
last_day = (next_month_first - timedelta(days=1)).day
|
||||
|
||||
clamped_day = min(day, last_day)
|
||||
return base_dt.replace(year=year, month=month, day=clamped_day)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user