From b755975372dd18967d7da7920a5d488bc91dea79 Mon Sep 17 00:00:00 2001 From: "Thomas Lefebvre (thle)" Date: Thu, 1 Dec 2022 12:14:26 +0000 Subject: [PATCH] [FIX] project: calculate recurring tasks with interval Steps to reproduce: - activate "Recurring Tasks" option inside Project settings; - go to "Field Service" app; - create a task; - check recurrence box; - make the following configuration in the recurrence tab: * Repeat Every 6 Months * Repeat On Date of the Month 1 * Until End Date [your choice] Issue: The dates calculated for the recurrence are not correct. Cause: When we select an interval other than 1 for a frequency in months, we do not divide the number of months between the start and end date. And therefore the loop that calculates the recurrence dates goes too far into the dates. Solution: Divide the number of months between the start date and the end date by the interval. opw-3078084 closes odoo/odoo#107320 X-original-commit: 5d44d7d595dab866695945e5a6d2091ddd9df342 Signed-off-by: Xavier Bol (xbo) Signed-off-by: Lefebvre Thomas (thle) --- .../project/models/project_task_recurrence.py | 4 +++- .../project/tests/test_project_recurrence.py | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/addons/project/models/project_task_recurrence.py b/addons/project/models/project_task_recurrence.py index 1b05d2c49bd..fe5b3737a12 100644 --- a/addons/project/models/project_task_recurrence.py +++ b/addons/project/models/project_task_recurrence.py @@ -8,6 +8,8 @@ from calendar import monthrange from dateutil.relativedelta import relativedelta from dateutil.rrule import rrule, rruleset, DAILY, WEEKLY, MONTHLY, YEARLY, MO, TU, WE, TH, FR, SA, SU +import math + MONTHS = { 'january': 31, 'february': 28, @@ -179,7 +181,7 @@ class ProjectTaskRecurrence(models.Model): start = date_start - relativedelta(days=1) if repeat_type == 'until' and repeat_until > date_start: delta = relativedelta(repeat_until, date_start) - count = delta.years * 12 + delta.months + count = math.floor((delta.years * 12 + delta.months) / repeat_interval) for i in range(count): start = start.replace(day=min(repeat_day, monthrange(start.year, start.month)[1])) if i == 0 and start < date_start: diff --git a/addons/project/tests/test_project_recurrence.py b/addons/project/tests/test_project_recurrence.py index 4508545ec3f..216673e7360 100644 --- a/addons/project/tests/test_project_recurrence.py +++ b/addons/project/tests/test_project_recurrence.py @@ -437,6 +437,24 @@ class TestProjectrecurrence(TransactionCase): self.assertEqual(dates[3], datetime(2020, 4, 25)) self.assertEqual(dates[4], datetime(2020, 5, 23)) + dates = self.env['project.task.recurrence']._get_next_recurring_dates( + date_start=datetime(2020, 1, 10), + repeat_interval=6, # twice a year + repeat_unit='month', + repeat_type='until', + repeat_until=datetime(2021, 1, 11), + repeat_on_month='date', + repeat_on_year=False, + weekdays=[TH(+1)], + repeat_day='3', # the 3rd of the month + repeat_week=False, + repeat_month=False, + count=1) + + self.assertEqual(len(dates), 2) + self.assertEqual(dates[0], datetime(2020, 7, 3)) + self.assertEqual(dates[1], datetime(2021, 1, 3)) + def test_recurrence_next_dates_year(self): dates = self.env['project.task.recurrence']._get_next_recurring_dates( date_start=date(2020, 12, 1),