Extend Season model: add generate_default method for creating seasons with configurable defaults, and _add_months utility for date calculations.
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
import calendar
|
||||
import datetime
|
||||
import re
|
||||
|
||||
from constance import config
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
@@ -42,3 +45,40 @@ class Season(RulesModel):
|
||||
if values_only:
|
||||
return season.date_range
|
||||
return season
|
||||
|
||||
@classmethod
|
||||
def generate_default(cls, day: int | None = None, month: int | None = None, duration: str | None = None) -> "Season":
|
||||
if day is None:
|
||||
day = config.TF_DEFAULT_SEASON_DAY
|
||||
if month is None:
|
||||
month = config.TF_DEFAULT_SEASON_MONTH
|
||||
if duration is None:
|
||||
duration = config.TF_DEFAULT_SEASON_DURATION
|
||||
|
||||
current_year = timezone.now().date().year
|
||||
start_date = datetime.date(current_year, month, day)
|
||||
|
||||
match = re.fullmatch(r"(\d+)([ym])", duration.strip().lower())
|
||||
if match is None:
|
||||
raise ValueError('Duration must be specified as "<number>y" or "<number>m", for example "1y", "1m", or "3m".')
|
||||
|
||||
duration_value = int(match.group(1))
|
||||
duration_unit = match.group(2)
|
||||
|
||||
if duration_unit == "y":
|
||||
end_date = cls._add_months(start_date, duration_value * 12) - datetime.timedelta(days=1)
|
||||
elif duration_unit == "m":
|
||||
end_date = cls._add_months(start_date, duration_value) - datetime.timedelta(days=1)
|
||||
else:
|
||||
raise ValueError('Duration unit must be "y" or "m".')
|
||||
|
||||
return cls.objects.create(start_date=start_date, end_date=end_date)
|
||||
|
||||
@staticmethod
|
||||
def _add_months(date_value: datetime.date, months: int) -> datetime.date:
|
||||
month_index = date_value.month - 1 + months
|
||||
year = date_value.year + month_index // 12
|
||||
month = month_index % 12 + 1
|
||||
day = min(date_value.day, calendar.monthrange(year, month)[1])
|
||||
|
||||
return date_value.replace(year=year, month=month, day=day)
|
||||
|
||||
Reference in New Issue
Block a user