diff --git a/project_workload_milestone/__init__.py b/project_workload_milestone/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/project_workload_milestone/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/project_workload_milestone/__manifest__.py b/project_workload_milestone/__manifest__.py new file mode 100644 index 00000000..f662e3cd --- /dev/null +++ b/project_workload_milestone/__manifest__.py @@ -0,0 +1,22 @@ +# Copyright 2024 Akretion (https://www.akretion.com). +# @author Florian Mounier +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Project Workload Milestone", + "summary": "Add Milestone Support to Project Workload", + "version": "14.0.1.0.0", + "development_status": "Alpha", + "category": "Uncategorized", + "website": "https://github.com/akretion/ak-odoo-incubator", + "author": " Akretion", + "license": "AGPL-3", + "depends": [ + "project_workload", + "project_milestone", + ], + "data": [ + "views/project_milestone.xml", + ], + "auto_install": True, +} diff --git a/project_workload_milestone/models/__init__.py b/project_workload_milestone/models/__init__.py new file mode 100644 index 00000000..fed98971 --- /dev/null +++ b/project_workload_milestone/models/__init__.py @@ -0,0 +1,2 @@ +from . import project_milestone +from . import project_task diff --git a/project_workload_milestone/models/project_milestone.py b/project_workload_milestone/models/project_milestone.py new file mode 100644 index 00000000..c1e3617a --- /dev/null +++ b/project_workload_milestone/models/project_milestone.py @@ -0,0 +1,49 @@ +# Copyright 2024 Akretion (http://www.akretion.com). +# @author Florian Mounier +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from datetime import timedelta + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + + +class ProjectMilestone(models.Model): + _inherit = "project.milestone" + + start_date = fields.Date( + string="Start Date", + help="The date when the Milestone should start.", + compute="_compute_milestone_start_date", + store=True, + readonly=False, + ) + + @api.constrains("start_date", "target_date") + def _check_start_date(self): + for milestone in self: + if milestone.target_date < milestone.start_date: + raise ValidationError( + _("The end date cannot be earlier than the start date.") + ) + + @api.depends("target_date", "project_id") + def _compute_milestone_start_date(self): + for record in self: + if record.start_date: + continue + if not record.target_date: + record.start_date = False + continue + + # Use a simple algorithm to find the start date + # Find previous milestone + previous_milestones = self.search( + [ + ("project_id", "=", record.project_id.id), + ("target_date", "<", record.target_date), + ], + order="target_date desc", + limit=1, + ) + # The start date will be the end date of the previous milestone + record.start_date = previous_milestones.target_date + timedelta(days=1) diff --git a/project_workload_milestone/models/project_task.py b/project_workload_milestone/models/project_task.py new file mode 100644 index 00000000..b88475cd --- /dev/null +++ b/project_workload_milestone/models/project_task.py @@ -0,0 +1,27 @@ +# Copyright 2024 Akretion (http://www.akretion.com). +# @author Florian Mounier +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, models + + +class ProjectTask(models.Model): + _inherit = "project.task" + + def _prepare_task_dates_vals_from_milestone(self, vals): + # If we create a task with a milestone or affect it after, + # we set the task dates to the milestone dates + + if "milestone_id" in vals: + milestone = self.env["project.milestone"].browse(vals["milestone_id"]) + if milestone: + vals["date_end"] = milestone.target_date + vals["date_start"] = milestone.start_date + return vals + + @api.model + def create(self, vals): + return super().create(self._prepare_task_dates_vals_from_milestone(vals)) + + def write(self, vals): + return super().write(self._prepare_task_dates_vals_from_milestone(vals)) diff --git a/project_workload_milestone/views/project_milestone.xml b/project_workload_milestone/views/project_milestone.xml new file mode 100644 index 00000000..a0fb1614 --- /dev/null +++ b/project_workload_milestone/views/project_milestone.xml @@ -0,0 +1,21 @@ + + + + + + project.milestone + + + + + + + + + + + + + diff --git a/setup/project_workload_milestone/odoo/addons/project_workload_milestone b/setup/project_workload_milestone/odoo/addons/project_workload_milestone new file mode 120000 index 00000000..e908b1d0 --- /dev/null +++ b/setup/project_workload_milestone/odoo/addons/project_workload_milestone @@ -0,0 +1 @@ +../../../../project_workload_milestone \ No newline at end of file diff --git a/setup/project_workload_milestone/setup.py b/setup/project_workload_milestone/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/project_workload_milestone/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)