Skip to content

Commit

Permalink
TA#72216 [MIG][16.0] timesheet_task_project_no_change (#55)
Browse files Browse the repository at this point in the history
* [16.0][ADD]  timesheet_task_project_no_change

---------

Co-authored-by: Majda EL MARIOULI <[email protected]>
  • Loading branch information
rivo2302 and majouda authored Jan 30, 2025
1 parent 86b2b0d commit 306f087
Show file tree
Hide file tree
Showing 13 changed files with 200 additions and 0 deletions.
1 change: 1 addition & 0 deletions .docker_files/main/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"depends": [
"hr_timesheet_project_parent_enhanced",
"project_timesheet_time_control_sheet",
"timesheet_task_project_no_change",
],
"installable": True,
}
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ USER odoo

COPY hr_timesheet_project_parent_enhanced /mnt/extra-addons/hr_timesheet_project_parent_enhanced
COPY project_timesheet_time_control_sheet /mnt/extra-addons/project_timesheet_time_control_sheet
COPY timesheet_task_project_no_change /mnt/extra-addons/timesheet_task_project_no_change

COPY .docker_files/main /mnt/extra-addons/main
COPY .docker_files/odoo.conf /etc/odoo
23 changes: 23 additions & 0 deletions timesheet_task_project_no_change/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Timesheet Task Project No Change
================================

Usage
-----

As a user of the **Project** module, when attempting to change the project of a task:

1. If timesheets have already been recorded on the task, a blocking message will appear:

.. image:: static/description/task_timesheet_error.png
:alt: Blocking error when task has timesheets

2. If timesheets have been recorded on a subtask, a similar blocking message will appear:

.. image:: static/description/subtask_timesheet_error.png
:alt: Blocking error when subtask has timesheets

3. In both cases, the task's project cannot be changed unless no timesheets exist for the task or its subtasks.

Contributors
------------
* Numigi (tm) and all its contributors (https://bit.ly/numigiens)
4 changes: 4 additions & 0 deletions timesheet_task_project_no_change/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright 2024 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from . import models
15 changes: 15 additions & 0 deletions timesheet_task_project_no_change/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2024 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

{
"name": "Timesheet Task Project No Change",
"version": "16.0.1.0.0",
"author": "Numigi",
"maintainer": "Numigi",
"website": "https://bit.ly/numigi-com",
"license": "LGPL-3",
"category": "Project",
"summary": "Prevent changing the project on a task with timesheets.",
"depends": ["hr_timesheet"],
"installable": True,
}
47 changes: 47 additions & 0 deletions timesheet_task_project_no_change/i18n/fr.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * timesheet_task_project_no_change
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-12-03 11:49+0000\n"
"PO-Revision-Date: 2024-12-03 11:49+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

#. module: timesheet_task_project_no_change
#: model:ir.model,name:timesheet_task_project_no_change.model_project_task
msgid "Task"
msgstr "Tâche"

#. module: timesheet_task_project_no_change
#. odoo-python
#: code:addons/timesheet_task_project_no_change/models/project_task.py:0
#, python-format
msgid ""
"Timesheets have already been entered on a sub-task ({subtask}). In order to "
"modify the project of the parent task ({task}), there must be no time on the"
" parent task, nor on its child tasks."
msgstr ""
"Du temps a été saisi une des tâches enfant ({subtask}). Pour modifier le "
"projet de la tâche parente ({task}), il ne doit pas y avoir de temps saisi "
"sur celle-ci ou sur ses tâches enfants."

#. module: timesheet_task_project_no_change
#. odoo-python
#: code:addons/timesheet_task_project_no_change/models/project_task.py:0
#, python-format
msgid ""
"Timesheets have already been entered on this task ({task}). In order to "
"modify the project of this task, you may close the task and create another "
"in the target project."
msgstr ""
"Du temps a déjà été saisi sur la tâche ({task}). Pour modifier le projet de "
"la tâche, veuillez fermer celle-ci et en créer une nouvelle sur le projet "
"cible."
4 changes: 4 additions & 0 deletions timesheet_task_project_no_change/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright 2024 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from . import project_task
50 changes: 50 additions & 0 deletions timesheet_task_project_no_change/models/project_task.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright 2024 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from odoo import models, _
from odoo.exceptions import ValidationError


class ProjectTask(models.Model):
_inherit = "project.task"

def write(self, vals):
if "project_id" in vals:
project = self.env["project.project"].browse(vals["project_id"])
tasks_with_different_project = self.filtered(
lambda t: t.project_id != project
)

for task in tasks_with_different_project:
task._validate_no_timesheets()
task._validate_no_subtask_timesheets()

return super().write(vals)

def _validate_no_timesheets(self):
if self.sudo().timesheet_ids:
raise ValidationError(
_(
"Timesheets have already been entered on this task ({task}). "
"In order to modify the project of this task, you may "
"close the task and create another in the target project."
).format(task=self.display_name)
)

def _validate_no_subtask_timesheets(self):
timesheets = (
self.env["account.analytic.line"]
.sudo()
.search([("task_id.parent_id", "=", self.id)])
)

if timesheets:
raise ValidationError(
_(
"Timesheets have already been entered on a sub-task ({subtask}). "
"In order to modify the project of the parent task ({task}), there must "
"be no time on the parent task, nor on its child tasks."
).format(
task=self.display_name, subtask=timesheets[0].task_id.display_name
)
)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions timesheet_task_project_no_change/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright 2024 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from . import test_project_task
51 changes: 51 additions & 0 deletions timesheet_task_project_no_change/tests/test_project_task.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright 2024 - today Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

import pytest
from odoo.exceptions import ValidationError
from odoo.tests.common import TransactionCase


class TestProjectTask(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.project_a = cls.env["project.project"].create({"name": "projectA"})
cls.project_b = cls.env["project.project"].create({"name": "projectB"})
cls.task = cls.env["project.task"].create(
{"name": "Parent Task", "project_id": cls.project_a.id}
)
cls.subtask = cls.env["project.task"].create(
{
"name": "Child Task",
"project_id": cls.project_a.id,
"parent_id": cls.task.id,
}
)

def test_if_no_timesheet__project_can_be_changed(self):
self.task.project_id = self.project_b

def test_if_project_is_the_same__constraint_not_raised(self):
self._make_timesheet_line(self.task)
self.task.project_id = self.project_a

def test_if_task_has_timesheet__project_can_not_be_changed(self):
self._make_timesheet_line(self.task)
with pytest.raises(ValidationError):
self.task.project_id = self.project_b

def test_if_subtask_has_timesheet__project_can_not_be_changed(self):
self._make_timesheet_line(self.subtask)
with pytest.raises(ValidationError):
self.task.project_id = self.project_b

def _make_timesheet_line(self, task):
return self.env["account.analytic.line"].create(
{
"task_id": task.id,
"project_id": task.project_id.id,
"name": "/",
"employee_id": self.ref("hr.employee_admin"),
}
)

0 comments on commit 306f087

Please sign in to comment.