From c95cb24ca74013d01390f4559687e91301a2e9ef Mon Sep 17 00:00:00 2001 From: Bernard Siebens Date: Sun, 26 Apr 2026 22:01:32 +0200 Subject: [PATCH] Extend `Season` model: add `generate_default` method for creating seasons with configurable defaults, and `_add_months` utility for date calculations. --- teams/models.py | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/teams/models.py b/teams/models.py index 8819133..e6a96ca 100644 --- a/teams/models.py +++ b/teams/models.py @@ -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 "y" or "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)