From f0e4ff4888db4a5a60022bd9a25b6e12fae98c46 Mon Sep 17 00:00:00 2001 From: Carlos Lopez Date: Wed, 18 Dec 2024 16:40:08 -0500 Subject: [PATCH 1/4] [IMP] sale_project_task_recurrency: Add options to force month intervals for Quarter and Semester When the task is created, the interval is automatically adjusted to months (3 months for Quarter and 6 months for Semester) since Odoo does not support these options directly. --- .../models/product_template.py | 23 + .../models/sale_order_line.py | 82 +++- .../tests/test_product_task_recurrency.py | 394 ++++++++++++++++++ .../views/product_template_views.xml | 12 +- 4 files changed, 487 insertions(+), 24 deletions(-) diff --git a/sale_project_task_recurrency/models/product_template.py b/sale_project_task_recurrency/models/product_template.py index 40e3e3c28e..736f0b4ab8 100644 --- a/sale_project_task_recurrency/models/product_template.py +++ b/sale_project_task_recurrency/models/product_template.py @@ -13,6 +13,8 @@ class ProductTemplate(models.Model): ("day", "Days"), ("week", "Weeks"), ("month", "Months"), + ("quarter", "Quarters"), + ("semester", "Semesters"), ("year", "Years"), ], default="week", @@ -73,6 +75,27 @@ class ProductTemplate(models.Model): ], "Force Month", ) + task_force_month_quarter = fields.Selection( + [ + ("1", "First month"), + ("2", "Second month"), + ("3", "Third month"), + ], + "Force Month", + help="Force the month to be used inside the quarter", + ) + task_force_month_semester = fields.Selection( + [ + ("1", "First month"), + ("2", "Second month"), + ("3", "Third month"), + ("4", "Fourth month"), + ("5", "Fifth month"), + ("6", "Sixth month"), + ], + "Force Month", + help="Force the month to be used inside the semester", + ) @api.onchange("service_tracking") def _onchange_service_tracking(self): diff --git a/sale_project_task_recurrency/models/sale_order_line.py b/sale_project_task_recurrency/models/sale_order_line.py index 872ff061bb..79a770efbf 100644 --- a/sale_project_task_recurrency/models/sale_order_line.py +++ b/sale_project_task_recurrency/models/sale_order_line.py @@ -7,6 +7,13 @@ from odoo import fields, models +MONTH_NB_TASK_MAPPING = { + "month": 1, + "quarter": 3, + "semester": 6, + "year": 12, +} + class SaleOrderLine(models.Model): _inherit = "sale.order.line" @@ -19,11 +26,21 @@ def _timesheet_create_task_prepare_values(self, project): if self.product_id.task_repeat_type == "repeat" else self.product_id.task_repeat_type ) + repeat_unit = ( + "month" + if self.product_id.task_repeat_unit in ["quarter", "semester"] + else self.product_id.task_repeat_unit + ) + repeat_interval = self.product_id.task_repeat_interval + if self.product_id.task_repeat_unit == "quarter": + repeat_interval *= 3 + elif self.product_id.task_repeat_unit == "semester": + repeat_interval *= 6 date_deadline = self._get_task_date_deadline() values.update( { - "repeat_interval": self.product_id.task_repeat_interval, - "repeat_unit": self.product_id.task_repeat_unit, + "repeat_interval": repeat_interval, + "repeat_unit": repeat_unit, "repeat_type": repeat_type, "recurring_task": True, "date_deadline": date_deadline, @@ -35,35 +52,54 @@ def _timesheet_create_task_prepare_values(self, project): def _get_task_date_deadline(self): self.ensure_one() product = self.product_id - force_month = int(product.task_force_month) if product.task_force_month else 0 + date_now = fields.Datetime.context_timestamp(self, datetime.now()) task_start_date_method = product.task_start_date_method - date_deadline_tz = fields.Datetime.context_timestamp( - self, datetime.now() - ) + relativedelta(hour=12, minute=0, second=0) + # Initial deadline based on current date and time + date_deadline = date_now.replace(hour=12, minute=0, second=0) + forced_month = int(product.task_force_month or 0) + if product.task_repeat_unit in ["quarter", "semester"]: + forced_month = int( + product["task_force_month_%s" % product.task_repeat_unit] or 0 + ) + month_period = month = date_deadline.month + month_nb = MONTH_NB_TASK_MAPPING.get(product.task_repeat_unit) or 0 + if product.task_repeat_unit in ["quarter", "semester", "year"]: + month_nb = MONTH_NB_TASK_MAPPING[product.task_repeat_unit] + # The period number is started by 0 to be able to calculate the month + period_number = (month - 1) // month_nb + if product.task_repeat_unit == "year": + month_period = 1 + elif product.task_repeat_unit != "month": + # Checking quarterly and semesterly + month_period = period_number * month_nb + 1 + if product.task_repeat_unit != "month" and forced_month: + # When the selected period is year, the period_number field is + # 0, so forced_month will take the value of the forced month set + # on product. + forced_month = month_nb * period_number + forced_month if ( - force_month - and product.task_repeat_unit == "year" + forced_month + and product.task_repeat_unit in ["quarter", "semester", "year"] and task_start_date_method == "current_date" ): - date_deadline_tz += relativedelta(month=force_month) - date_deadline = date_deadline_tz.astimezone(pytz.UTC).replace(tzinfo=None) + date_deadline += relativedelta(month=forced_month) if ( - product.task_repeat_unit in ["month", "year"] + product.task_repeat_unit in ["month", "quarter", "semester", "year"] and task_start_date_method != "current_date" ): - if product.task_repeat_unit == "month": - date_deadline += relativedelta(day=1) - if "_next" in task_start_date_method: - date_deadline += relativedelta(months=product.task_repeat_interval) - if "end_" in task_start_date_method: + is_end = "end_" in task_start_date_method + # If forced_month is set, use it, but if it isn't use the month_period + date_deadline += relativedelta(day=1, month=forced_month or month_period) + if is_end: + increment = month_nb - 1 if not forced_month else 0 + date_deadline += relativedelta(months=increment, day=31) + if "_next" in task_start_date_method: + date_deadline += relativedelta( + months=month_nb * product.task_repeat_interval + ) + if is_end: date_deadline += relativedelta(day=31) - else: - date_deadline += relativedelta(month=force_month or 1, day=1) - if "_next" in task_start_date_method: - date_deadline += relativedelta(years=product.task_repeat_interval) - if "end_" in task_start_date_method: - date_deadline += relativedelta(month=force_month or 12, day=31) - return date_deadline + return date_deadline.astimezone(pytz.UTC).replace(tzinfo=None) def _get_task_repeat_until(self, date_start): self.ensure_one() diff --git a/sale_project_task_recurrency/tests/test_product_task_recurrency.py b/sale_project_task_recurrency/tests/test_product_task_recurrency.py index c039a330fb..0903aca092 100644 --- a/sale_project_task_recurrency/tests/test_product_task_recurrency.py +++ b/sale_project_task_recurrency/tests/test_product_task_recurrency.py @@ -328,6 +328,188 @@ def test_task_recurrency_3_month(self): last_task.date_deadline.date(), fields.Date.from_string("2025-05-28") ) + @users("test-user") + @freeze_time("2024-11-15") + def test_task_recurrency_quarter(self): + """Every 1 quarter forever""" + self.service_task_recurrency.task_repeat_unit = "quarter" + self.service_task_recurrency.task_repeat_interval = 1 + self.sale_order.action_confirm() + self.assertFalse(self.sol_no_task.task_id) + self.assertFalse(self.sol_task.task_id.recurring_task) + task = self.sol_task_recurrency.task_id + self.assertTrue(task.recurring_task) + # quarter is 3 months + self.assertEqual(task.repeat_interval, 3) + self.assertEqual(task.repeat_unit, "month") + self.assertEqual(task.repeat_type, "forever") + self.assertFalse(task.repeat_until) + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-11-15") + ) + self.assertEqual(task.recurring_count, 1) + task.state = "1_done" + task.invalidate_recordset(["recurring_count"]) + self.assertEqual(task.recurring_count, 2) + last_task = self._get_last_task(task) + self.assertEqual( + last_task.date_deadline.date(), fields.Date.from_string("2025-02-15") + ) + # start_date_method = "start_this" + # on November, the quarter start on October + self.service_task_recurrency.task_start_date_method = "start_this" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-10-01") + ) + self.assertEqual(task.recurring_count, 1) + task.state = "1_done" + task.invalidate_recordset(["recurring_count"]) + self.assertEqual(task.recurring_count, 2) + last_task = self._get_last_task(task) + self.assertEqual( + last_task.date_deadline.date(), fields.Date.from_string("2025-01-01") + ) + # start_date_method = "end_this" + # on November, the quarter ends on December + self.service_task_recurrency.task_start_date_method = "end_this" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-12-31") + ) + self.assertEqual(task.recurring_count, 1) + task.state = "1_done" + task.invalidate_recordset(["recurring_count"]) + self.assertEqual(task.recurring_count, 2) + last_task = self._get_last_task(task) + self.assertEqual( + last_task.date_deadline.date(), fields.Date.from_string("2025-03-31") + ) + # start_date_method = "start_next" + # on November, the next quarter starts on January + self.service_task_recurrency.task_start_date_method = "start_next" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2025-01-01") + ) + self.assertEqual(task.recurring_count, 1) + task.state = "1_done" + task.invalidate_recordset(["recurring_count"]) + self.assertEqual(task.recurring_count, 2) + last_task = self._get_last_task(task) + self.assertEqual( + last_task.date_deadline.date(), fields.Date.from_string("2025-04-01") + ) + # start_date_method = "end_next" + self.service_task_recurrency.task_start_date_method = "end_next" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2025-03-31") + ) + self.assertEqual(task.recurring_count, 1) + task.state = "1_done" + task.invalidate_recordset(["recurring_count"]) + self.assertEqual(task.recurring_count, 2) + last_task = self._get_last_task(task) + self.assertEqual( + last_task.date_deadline.date(), fields.Date.from_string("2025-06-30") + ) + + @users("test-user") + @freeze_time("2024-11-15") + def test_task_recurrency_semester(self): + """Every 1 quarter forever""" + self.service_task_recurrency.task_repeat_unit = "semester" + self.service_task_recurrency.task_repeat_interval = 1 + self.sale_order.action_confirm() + self.assertFalse(self.sol_no_task.task_id) + self.assertFalse(self.sol_task.task_id.recurring_task) + task = self.sol_task_recurrency.task_id + self.assertTrue(task.recurring_task) + # semester is 6 months + self.assertEqual(task.repeat_interval, 6) + self.assertEqual(task.repeat_unit, "month") + self.assertEqual(task.repeat_type, "forever") + self.assertFalse(task.repeat_until) + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-11-15") + ) + self.assertEqual(task.recurring_count, 1) + task.state = "1_done" + task.invalidate_recordset(["recurring_count"]) + self.assertEqual(task.recurring_count, 2) + last_task = self._get_last_task(task) + self.assertEqual( + last_task.date_deadline.date(), fields.Date.from_string("2025-05-15") + ) + # start_date_method = "start_this" + # on November, the semester start on July + self.service_task_recurrency.task_start_date_method = "start_this" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-07-01") + ) + self.assertEqual(task.recurring_count, 1) + task.state = "1_done" + task.invalidate_recordset(["recurring_count"]) + self.assertEqual(task.recurring_count, 2) + last_task = self._get_last_task(task) + self.assertEqual( + last_task.date_deadline.date(), fields.Date.from_string("2025-01-01") + ) + # start_date_method = "end_this" + # on November, the semester ends on December + self.service_task_recurrency.task_start_date_method = "end_this" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-12-31") + ) + self.assertEqual(task.recurring_count, 1) + task.state = "1_done" + task.invalidate_recordset(["recurring_count"]) + self.assertEqual(task.recurring_count, 2) + last_task = self._get_last_task(task) + self.assertEqual( + last_task.date_deadline.date(), fields.Date.from_string("2025-06-30") + ) + # start_date_method = "start_next" + # on November, the next semester starts on January + self.service_task_recurrency.task_start_date_method = "start_next" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2025-01-01") + ) + self.assertEqual(task.recurring_count, 1) + task.state = "1_done" + task.invalidate_recordset(["recurring_count"]) + self.assertEqual(task.recurring_count, 2) + last_task = self._get_last_task(task) + self.assertEqual( + last_task.date_deadline.date(), fields.Date.from_string("2025-07-01") + ) + # start_date_method = "end_next" + self.service_task_recurrency.task_start_date_method = "end_next" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2025-06-30") + ) + self.assertEqual(task.recurring_count, 1) + task.state = "1_done" + task.invalidate_recordset(["recurring_count"]) + self.assertEqual(task.recurring_count, 2) + last_task = self._get_last_task(task) + self.assertEqual( + last_task.date_deadline.date(), fields.Date.from_string("2025-12-30") + ) + @users("test-user") @freeze_time("2024-11-15") def test_task_recurrency_year(self): @@ -747,3 +929,215 @@ def test_task_recurrency_year_force_month(self): self.assertEqual( task.date_deadline.date(), fields.Date.from_string("2025-06-30") ) + + @users("test-user") + @freeze_time("2024-11-15") + def test_task_recurrency_quarter_force_month(self): + # Force month to firts month of quarter: January, April, July, October + self.service_task_recurrency.task_repeat_interval = 1 + self.service_task_recurrency.task_repeat_unit = "quarter" + self.service_task_recurrency.task_force_month_quarter = "1" + self.service_task_recurrency.task_repeat_type = "forever" + self.sale_order.action_confirm() + task = self.sol_task_recurrency.task_id + self.assertTrue(task.recurring_task) + self.assertEqual(task.repeat_interval, 3) + self.assertEqual(task.repeat_unit, "month") + self.assertEqual(task.repeat_type, "forever") + self.assertEqual(task.recurring_count, 1) + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-10-15") + ) + # start_this + self.service_task_recurrency.task_start_date_method = "start_this" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-10-01") + ) + # end_this + self.service_task_recurrency.task_start_date_method = "end_this" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-10-31") + ) + # start_next + self.service_task_recurrency.task_start_date_method = "start_next" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2025-01-01") + ) + # end_next + self.service_task_recurrency.task_start_date_method = "end_next" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2025-01-31") + ) + # Force month to second month of quarter: February, May, August, November + self.service_task_recurrency.task_force_month_quarter = "2" + self.service_task_recurrency.task_start_date_method = "current_date" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertTrue(task.recurring_task) + self.assertEqual(task.repeat_interval, 3) + self.assertEqual(task.repeat_unit, "month") + self.assertEqual(task.recurring_count, 1) + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-11-15") + ) + # start_this + self.service_task_recurrency.task_start_date_method = "start_this" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-11-01") + ) + # end_this + self.service_task_recurrency.task_start_date_method = "end_this" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-11-30") + ) + # start_next + self.service_task_recurrency.task_start_date_method = "start_next" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2025-02-01") + ) + # end_next + self.service_task_recurrency.task_start_date_method = "end_next" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2025-02-28") + ) + # Force month to third month of quarter: March, June, September, December + self.service_task_recurrency.task_force_month_quarter = "3" + self.service_task_recurrency.task_start_date_method = "current_date" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertTrue(task.recurring_task) + self.assertEqual(task.repeat_interval, 3) + self.assertEqual(task.repeat_unit, "month") + self.assertEqual(task.recurring_count, 1) + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-12-15") + ) + # start_this + self.service_task_recurrency.task_start_date_method = "start_this" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-12-01") + ) + # end_this + self.service_task_recurrency.task_start_date_method = "end_this" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-12-31") + ) + # start_next + self.service_task_recurrency.task_start_date_method = "start_next" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2025-03-01") + ) + # end_next + self.service_task_recurrency.task_start_date_method = "end_next" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2025-03-31") + ) + + @users("test-user") + @freeze_time("2024-11-15") + def test_task_recurrency_semester_force_month(self): + # Force month to second month of semester + self.service_task_recurrency.task_repeat_interval = 1 + self.service_task_recurrency.task_repeat_unit = "semester" + self.service_task_recurrency.task_force_month_semester = "2" + self.service_task_recurrency.task_repeat_type = "forever" + self.sale_order.action_confirm() + task = self.sol_task_recurrency.task_id + self.assertTrue(task.recurring_task) + self.assertEqual(task.repeat_interval, 6) + self.assertEqual(task.repeat_unit, "month") + self.assertEqual(task.repeat_type, "forever") + self.assertEqual(task.recurring_count, 1) + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-08-15") + ) + # start_this + self.service_task_recurrency.task_start_date_method = "start_this" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-08-01") + ) + # end_this + self.service_task_recurrency.task_start_date_method = "end_this" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-08-31") + ) + # start_next + self.service_task_recurrency.task_start_date_method = "start_next" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2025-02-01") + ) + # end_next + self.service_task_recurrency.task_start_date_method = "end_next" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2025-02-28") + ) + # Force month to four month of semester + self.service_task_recurrency.task_force_month_semester = "4" + self.service_task_recurrency.task_start_date_method = "current_date" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertTrue(task.recurring_task) + self.assertEqual(task.recurring_count, 1) + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-10-15") + ) + # start_this + self.service_task_recurrency.task_start_date_method = "start_this" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-10-01") + ) + # end_this + self.service_task_recurrency.task_start_date_method = "end_this" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2024-10-31") + ) + # start_next + self.service_task_recurrency.task_start_date_method = "start_next" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2025-04-01") + ) + # end_next + self.service_task_recurrency.task_start_date_method = "end_next" + self._reprocess_sale_order() + task = self.sol_task_recurrency.task_id + self.assertEqual( + task.date_deadline.date(), fields.Date.from_string("2025-04-30") + ) diff --git a/sale_project_task_recurrency/views/product_template_views.xml b/sale_project_task_recurrency/views/product_template_views.xml index dc48fcf83b..bf8ba92323 100644 --- a/sale_project_task_recurrency/views/product_template_views.xml +++ b/sale_project_task_recurrency/views/product_template_views.xml @@ -59,7 +59,7 @@ @@ -68,6 +68,16 @@ invisible="task_repeat_unit != 'year'" groups="project.group_project_recurring_tasks" /> + + From 522c280ad58f3a0399109cda4ddefd51cb097929 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Thu, 19 Dec 2024 18:19:00 +0000 Subject: [PATCH 2/4] [UPD] Update sale_project_task_recurrency.pot --- .../i18n/sale_project_task_recurrency.pot | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/sale_project_task_recurrency/i18n/sale_project_task_recurrency.pot b/sale_project_task_recurrency/i18n/sale_project_task_recurrency.pot index efb318bdb9..52456869e8 100644 --- a/sale_project_task_recurrency/i18n/sale_project_task_recurrency.pot +++ b/sale_project_task_recurrency/i18n/sale_project_task_recurrency.pot @@ -65,17 +65,49 @@ msgstr "" msgid "February" msgstr "" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__5 +msgid "Fifth month" +msgstr "" + +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_quarter__1 +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__1 +msgid "First month" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_product__task_force_month +#: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_product__task_force_month_quarter +#: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_product__task_force_month_semester #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_template__task_force_month +#: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_template__task_force_month_quarter +#: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_template__task_force_month_semester msgid "Force Month" msgstr "" +#. module: sale_project_task_recurrency +#: model:ir.model.fields,help:sale_project_task_recurrency.field_product_product__task_force_month_quarter +#: model:ir.model.fields,help:sale_project_task_recurrency.field_product_template__task_force_month_quarter +msgid "Force the month to be used inside the quarter" +msgstr "" + +#. module: sale_project_task_recurrency +#: model:ir.model.fields,help:sale_project_task_recurrency.field_product_product__task_force_month_semester +#: model:ir.model.fields,help:sale_project_task_recurrency.field_product_template__task_force_month_semester +msgid "Force the month to be used inside the semester" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_repeat_type__forever msgid "Forever" msgstr "" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__4 +msgid "Fourth month" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_product__recurring_task #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_template__recurring_task @@ -132,6 +164,11 @@ msgstr "" msgid "Product Variant" msgstr "" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_repeat_unit__quarter +msgid "Quarters" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_repeat_type__repeat msgid "Repeat" @@ -148,11 +185,27 @@ msgstr "" msgid "Sales Order Line" msgstr "" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_quarter__2 +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__2 +msgid "Second month" +msgstr "" + +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_repeat_unit__semester +msgid "Semesters" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month__9 msgid "September" msgstr "" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__6 +msgid "Sixth month" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_product__task_start_date_method #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_template__task_start_date_method @@ -175,6 +228,12 @@ msgstr "" msgid "Task Repeat Unit" msgstr "" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_quarter__3 +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__3 +msgid "Third month" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields,help:sale_project_task_recurrency.field_product_product__task_start_date_method #: model:ir.model.fields,help:sale_project_task_recurrency.field_product_template__task_start_date_method From 4a3a70a355455060ac852948f69cafc7684d0c1b Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 19 Dec 2024 18:22:10 +0000 Subject: [PATCH 3/4] [BOT] post-merge updates --- README.md | 2 +- sale_project_task_recurrency/README.rst | 2 +- sale_project_task_recurrency/__manifest__.py | 2 +- sale_project_task_recurrency/static/description/index.html | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c2f6366198..9d86076ec4 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ addon | version | maintainers | summary [project_timeline](project_timeline/) | 17.0.1.1.1 | | Timeline view for projects [project_timesheet_time_control](project_timesheet_time_control/) | 17.0.1.0.1 | [![ernestotejeda](https://github.com/ernestotejeda.png?size=30px)](https://github.com/ernestotejeda) | Project timesheet time control [project_type](project_type/) | 17.0.1.0.2 | | Project Types -[sale_project_task_recurrency](sale_project_task_recurrency/) | 17.0.1.1.0 | | Configuring Task Recurrence from the Product Form. +[sale_project_task_recurrency](sale_project_task_recurrency/) | 17.0.1.2.0 | | Configuring Task Recurrence from the Product Form. [//]: # (end addons) diff --git a/sale_project_task_recurrency/README.rst b/sale_project_task_recurrency/README.rst index 21133e10c7..88f0d2d95c 100644 --- a/sale_project_task_recurrency/README.rst +++ b/sale_project_task_recurrency/README.rst @@ -7,7 +7,7 @@ Sale project task recurrency !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:333fe55af0b7c235786aba0f66d75dfd763960781b34f0701bf3548783f2793e + !! source digest: sha256:d5da2188db2ac87ba6c4ebb660e25aa1e53a534b122f01791f97e48ae666a311 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/sale_project_task_recurrency/__manifest__.py b/sale_project_task_recurrency/__manifest__.py index 1bd4207941..b616bef5f5 100644 --- a/sale_project_task_recurrency/__manifest__.py +++ b/sale_project_task_recurrency/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Sale project task recurrency", - "version": "17.0.1.1.0", + "version": "17.0.1.2.0", "summary": "Configuring Task Recurrence from the Product Form.", "author": "Tecnativa,Odoo Community Association (OCA)", "website": "https://github.com/OCA/project", diff --git a/sale_project_task_recurrency/static/description/index.html b/sale_project_task_recurrency/static/description/index.html index 8d9f7b642f..c1bdcb042e 100644 --- a/sale_project_task_recurrency/static/description/index.html +++ b/sale_project_task_recurrency/static/description/index.html @@ -367,7 +367,7 @@

Sale project task recurrency

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:333fe55af0b7c235786aba0f66d75dfd763960781b34f0701bf3548783f2793e +!! source digest: sha256:d5da2188db2ac87ba6c4ebb660e25aa1e53a534b122f01791f97e48ae666a311 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/project Translate me on Weblate Try me on Runboat

This module allows configuring the recurrence of tasks created from From f84fd3037b17b560b0e00587326eac41ab8ef9b1 Mon Sep 17 00:00:00 2001 From: Weblate Date: Thu, 19 Dec 2024 18:22:19 +0000 Subject: [PATCH 4/4] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: project-17.0/project-17.0-sale_project_task_recurrency Translate-URL: https://translation.odoo-community.org/projects/project-17-0/project-17-0-sale_project_task_recurrency/ --- sale_project_task_recurrency/i18n/es.po | 59 +++++++++++++++++++++++++ sale_project_task_recurrency/i18n/it.po | 59 +++++++++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/sale_project_task_recurrency/i18n/es.po b/sale_project_task_recurrency/i18n/es.po index 2efda44c60..56281bea53 100644 --- a/sale_project_task_recurrency/i18n/es.po +++ b/sale_project_task_recurrency/i18n/es.po @@ -68,17 +68,49 @@ msgstr "Fin del próximo período" msgid "February" msgstr "Febrero" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__5 +msgid "Fifth month" +msgstr "" + +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_quarter__1 +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__1 +msgid "First month" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_product__task_force_month +#: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_product__task_force_month_quarter +#: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_product__task_force_month_semester #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_template__task_force_month +#: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_template__task_force_month_quarter +#: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_template__task_force_month_semester msgid "Force Month" msgstr "Forzar mes" +#. module: sale_project_task_recurrency +#: model:ir.model.fields,help:sale_project_task_recurrency.field_product_product__task_force_month_quarter +#: model:ir.model.fields,help:sale_project_task_recurrency.field_product_template__task_force_month_quarter +msgid "Force the month to be used inside the quarter" +msgstr "" + +#. module: sale_project_task_recurrency +#: model:ir.model.fields,help:sale_project_task_recurrency.field_product_product__task_force_month_semester +#: model:ir.model.fields,help:sale_project_task_recurrency.field_product_template__task_force_month_semester +msgid "Force the month to be used inside the semester" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_repeat_type__forever msgid "Forever" msgstr "Para siempre" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__4 +msgid "Fourth month" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_product__recurring_task #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_template__recurring_task @@ -135,6 +167,11 @@ msgstr "Producto" msgid "Product Variant" msgstr "Variante" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_repeat_unit__quarter +msgid "Quarters" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_repeat_type__repeat msgid "Repeat" @@ -151,11 +188,27 @@ msgstr "Repetir cada" msgid "Sales Order Line" msgstr "Línea de orden de venta" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_quarter__2 +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__2 +msgid "Second month" +msgstr "" + +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_repeat_unit__semester +msgid "Semesters" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month__9 msgid "September" msgstr "Septiembre" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__6 +msgid "Sixth month" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_product__task_start_date_method #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_template__task_start_date_method @@ -178,6 +231,12 @@ msgstr "Inicio del próximo período" msgid "Task Repeat Unit" msgstr "Repetir tarea hasta" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_quarter__3 +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__3 +msgid "Third month" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields,help:sale_project_task_recurrency.field_product_product__task_start_date_method #: model:ir.model.fields,help:sale_project_task_recurrency.field_product_template__task_start_date_method diff --git a/sale_project_task_recurrency/i18n/it.po b/sale_project_task_recurrency/i18n/it.po index 18a955db13..a725503303 100644 --- a/sale_project_task_recurrency/i18n/it.po +++ b/sale_project_task_recurrency/i18n/it.po @@ -68,17 +68,49 @@ msgstr "Fine del periodo successivo" msgid "February" msgstr "Febbraio" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__5 +msgid "Fifth month" +msgstr "" + +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_quarter__1 +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__1 +msgid "First month" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_product__task_force_month +#: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_product__task_force_month_quarter +#: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_product__task_force_month_semester #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_template__task_force_month +#: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_template__task_force_month_quarter +#: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_template__task_force_month_semester msgid "Force Month" msgstr "Forza mese" +#. module: sale_project_task_recurrency +#: model:ir.model.fields,help:sale_project_task_recurrency.field_product_product__task_force_month_quarter +#: model:ir.model.fields,help:sale_project_task_recurrency.field_product_template__task_force_month_quarter +msgid "Force the month to be used inside the quarter" +msgstr "" + +#. module: sale_project_task_recurrency +#: model:ir.model.fields,help:sale_project_task_recurrency.field_product_product__task_force_month_semester +#: model:ir.model.fields,help:sale_project_task_recurrency.field_product_template__task_force_month_semester +msgid "Force the month to be used inside the semester" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_repeat_type__forever msgid "Forever" msgstr "Per sempre" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__4 +msgid "Fourth month" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_product__recurring_task #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_template__recurring_task @@ -135,6 +167,11 @@ msgstr "Prodotto" msgid "Product Variant" msgstr "Variante prodotto" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_repeat_unit__quarter +msgid "Quarters" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_repeat_type__repeat msgid "Repeat" @@ -151,11 +188,27 @@ msgstr "Ripeti ogni" msgid "Sales Order Line" msgstr "Riga ordine di vendita" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_quarter__2 +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__2 +msgid "Second month" +msgstr "" + +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_repeat_unit__semester +msgid "Semesters" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month__9 msgid "September" msgstr "Settembre" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__6 +msgid "Sixth month" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_product__task_start_date_method #: model:ir.model.fields,field_description:sale_project_task_recurrency.field_product_template__task_start_date_method @@ -178,6 +231,12 @@ msgstr "Inizio del periodo successivo" msgid "Task Repeat Unit" msgstr "Unità ripetizione lavoro" +#. module: sale_project_task_recurrency +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_quarter__3 +#: model:ir.model.fields.selection,name:sale_project_task_recurrency.selection__product_template__task_force_month_semester__3 +msgid "Third month" +msgstr "" + #. module: sale_project_task_recurrency #: model:ir.model.fields,help:sale_project_task_recurrency.field_product_product__task_start_date_method #: model:ir.model.fields,help:sale_project_task_recurrency.field_product_template__task_start_date_method