Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .docker_files/main/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@
"project_milestone_spent_hours",
"project_milestone_time_kpi",
"project_no_quick_create",
"project_portal_parent_task",
"project_parent_enhanced",
"project_parent_forecasted_end_date",
"project_parent_type_required",
"project_portal_hide_timesheets",
"project_portal_parent_task",
"project_progress_variance",
"project_projected_hours",
"project_remaining_hours_update",
Expand Down
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ COPY project_milestone_spent_hours /mnt/extra-addons/project_milestone_spent_hou
COPY project_milestone_time_kpi /mnt/extra-addons/project_milestone_time_kpi
COPY project_no_quick_create /mnt/extra-addons/project_no_quick_create
COPY project_parent_enhanced mnt/extra-addons/project_parent_enhanced
COPY project_portal_parent_task mnt/extra-addons/project_portal_parent_task
COPY project_parent_forecasted_end_date mnt/extra-addons/project_parent_forecasted_end_date
COPY project_parent_type_required mnt/extra-addons/project_parent_type_required
COPY project_portal_hide_timesheets mnt/extra-addons/project_portal_hide_timesheets
COPY project_portal_parent_task mnt/extra-addons/project_portal_parent_task
COPY project_progress_variance /mnt/extra-addons/project_progress_variance
COPY project_projected_hours mnt/extra-addons/project_projected_hours
COPY project_remaining_hours_update /mnt/extra-addons/project_remaining_hours_update
Expand Down
29 changes: 29 additions & 0 deletions project_parent_forecasted_end_date/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Project Parent Forcasted End Date
=================================

This module allows you to automatically calculate the project end date from the end dates of the different project child that constitute it.

Desccription
------------

After Installing this module, a new field is added to the project form view:

- *Forecasted End Date*: Takes the maximum end dates of the active child, visible only for parent project

.. image:: https://raw.githubusercontent.com/Numigi/odoo-project-addons/16.0/project_parent_forecasted_end_date/static/description/project_forecasted_end_date.png

From `Project / Configuration / Project Type` Form View, I can see a new field added:

- *Exclude From Forecasted End Date*: a Boolean field allowing to exclude the project iteration of this type from `Forcasted End Date` calculation

.. image:: https://raw.githubusercontent.com/Numigi/odoo-project-addons/16.0/project_parent_forecasted_end_date/static/description/project_type_config.png


Contributors
------------
- Numigi (tm) and all its contributors (https://bit.ly/numigiens)

More Information
----------------
- For more details, visit: (https://bit.ly/numigiens)

4 changes: 4 additions & 0 deletions project_parent_forecasted_end_date/__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
21 changes: 21 additions & 0 deletions project_parent_forecasted_end_date/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# 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": "Project Parent Forecasted End Date",
"version": "16.0.1.0.0",
"author": "Numigi",
"maintainer": "Numigi",
"website": "https://bit.ly/numigi-com",
"license": "LGPL-3",
"category": "Project",
"summary": """
Automatically calculate the project Forecasted End Date from its child.
""",
"depends": [
"project_type",
"project_parent_enhanced",
],
"data": ["views/project_project_views.xml", "views/project_type_views.xml"],
"installable": True,
}
36 changes: 36 additions & 0 deletions project_parent_forecasted_end_date/i18n/fr.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * project_parent_forecasted_end_date
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-29 13:35+0000\n"
"PO-Revision-Date: 2025-01-29 13:35+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: project_parent_forecasted_end_date
#: model:ir.model.fields,field_description:project_parent_forecasted_end_date.field_project_project__forecasted_end_date
msgid "Forecasted End Date"
msgstr "Date de fin prévue"

#. module: project_parent_forecasted_end_date
#: model:ir.model.fields,field_description:project_parent_forecasted_end_date.field_project_type__is_exclude_forecasted_end_date
msgid "Is exclude from forecasted end date computation"
msgstr "Exclure du calcul de la date de fin projetée"

#. module: project_parent_forecasted_end_date
#: model:ir.model,name:project_parent_forecasted_end_date.model_project_project
msgid "Project"
msgstr "Projet"

#. module: project_parent_forecasted_end_date
#: model:ir.model,name:project_parent_forecasted_end_date.model_project_type
msgid "Project Type"
msgstr "Type de projet"
5 changes: 5 additions & 0 deletions project_parent_forecasted_end_date/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copyright 2024 - 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_project
from . import project_type
36 changes: 36 additions & 0 deletions project_parent_forecasted_end_date/models/project_project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# 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 api, fields, models


class Project(models.Model):

_inherit = "project.project"

forecasted_end_date = fields.Date(
string="Forecasted End Date",
compute="_compute_forecasted_date",
store=True,
)

@api.depends(
"child_ids",
"child_ids.active",
"child_ids.date",
"child_ids.type_id",
"child_ids.type_id.is_exclude_forecasted_end_date",
)
def _compute_forecasted_date(self):
for project in self:
if project.is_parent:
dates = []
for child in project.child_ids.filtered(
lambda c: c.active
and (c.date and not c.type_id.is_exclude_forecasted_end_date)
):
dates.append(child.date)
project.forecasted_end_date = dates and max(dates) or project.date

else:
project.forecasted_end_date = project.date
13 changes: 13 additions & 0 deletions project_parent_forecasted_end_date/models/project_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# 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 fields, models


class ProjectType(models.Model):

_inherit = "project.type"

is_exclude_forecasted_end_date = fields.Boolean(
"Is exclude from forecasted end date computation"
)
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 project_parent_forecasted_end_date/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright 2023 - 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_effective_end_date
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright 2023 - 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.tests.common import TransactionCase
from datetime import datetime, timedelta


class TestForecastedEndDate(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.today = datetime.now().date()
cls.project_type_a = cls.env["project.type"].create(
{
"name": "My Project Type A",
"is_exclude_forecasted_end_date": False,
}
)
cls.project = cls.env["project.project"].create(
{
"name": "My Project",
"date_start": datetime.now(),
"date": cls.today + timedelta(days=365),
}
)

cls.child_1 = cls.env["project.project"].create(
{
"name": "Interation 1",
"parent_id": cls.project.id,
"date_start": datetime.now().date(),
"date": cls.today + timedelta(days=60),
}
)

cls.child_2 = cls.env["project.project"].create(
{
"name": "Interation 2",
"date_start": datetime.now(),
"parent_id": cls.project.id,
"type_id": cls.project_type_a.id,
}
)

def test_forecasted_end_date(self):
self.child_2.date = self.today + timedelta(days=120)
assert self.project.forecasted_end_date == self.child_2.date

def test_forecasted_end_date_with_excluded_child(self):
self.project_type_a.is_exclude_forecasted_end_date = True
assert self.project.forecasted_end_date == self.child_1.date

def test_forecasted_end_date_without_child(self):
self.child_1.parent_id = False
self.child_2.parent_id = False
assert self.project.forecasted_end_date == self.project.date
18 changes: 18 additions & 0 deletions project_parent_forecasted_end_date/views/project_project_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>

<odoo>

<record id="edit_project" model="ir.ui.view">
<field name="name">Project Forecasted End Date</field>
<field name="model">project.project</field>
<field name="inherit_id" ref="project.edit_project" />
<field name="type">form</field>
<field name="arch" type="xml">
<xpath expr="//div[@name='dates']" position="after">
<field name="is_parent" invisible="1" />
<field name="forecasted_end_date" attrs="{'invisible': [('is_parent', '=', False)]}" />
</xpath>
</field>
</record>

</odoo>
20 changes: 20 additions & 0 deletions project_parent_forecasted_end_date/views/project_type_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>

<odoo>

<record id="project_type_form" model="ir.ui.view">
<field name="name">Project Type Forecasted End Date</field>
<field name="model">project.type</field>
<field name="inherit_id" ref="project_type.project_type_form" />
<field name="type">form</field>
<field name="arch" type="xml">
<xpath expr="//div[field[@name='task_ok']]" position="after">
<div >
<field name="is_exclude_forecasted_end_date" />
<label for="is_exclude_forecasted_end_date" />
</div>
</xpath>
</field>
</record>

</odoo>