Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TA#70963 [12.0][ADD] project_milestone_progress_notification #456

Draft
wants to merge 5 commits into
base: 12.0
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions .docker_files/main/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"project_milestone_dependency",
"project_milestone_enhanced",
"project_milestone_estimated_hours",
"project_milestone_progress_notification",
"project_milestone_remaining_hours",
"project_milestone_responsible",
"project_milestone_role",
Expand Down
40 changes: 40 additions & 0 deletions project_milestone_progress_notification/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
=======================================
Project Milestone Progress Notification
=======================================
This module allows you to send email notifications to the project manager when a project milestone percent is reached.

Usage
-----
To use this module, you need to:
* Go to `Project > Configuration > Settings` and enable the option "Milestone progression notification" (by default enabled) in `Notifications` section.
* By default, a mail template is created with the subject "Milestone Progress Notification" and set by default. You can customize it as needed.
* Set the rate limit of milestone to notify the project manager when the progression is reached.

.. image:: static/description/milestone_notification_configuration.png

When the milestone progress reaches the rate limit, an email is sent to the project manager.

.. image:: static/description/milestone_progression.png

.. image:: static/description/mail_notification.png

Use cases
---------
1. Initial rate for notification configured is 60%.
I have a project with a milestone. The milestone have 2 tasks.
The milestone progress is 50%.
I do some changes on tasks to increase the progress.
Now, milestone progress reaches 67%, a notification email is sent.

Il all task was completed, the milestone progress should be 100%, and no additional email is sent.

I can have the progress to 0%, with a specific reason.
But if the milestone progress is back to 67% or greater by completing tasks, another notification email is sent.


2. If I change the notification rate to 33%. And progress change to 33.33%, triggering another notification email.
But after that I change the notification rate to 90%, and the milestone progress is 100%, this should trigger a final notification email.

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

from . import models

Check notice on line 4 in project_milestone_progress_notification/__init__.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

project_milestone_progress_notification/__init__.py#L4

'.models' imported but unused (F401)
22 changes: 22 additions & 0 deletions project_milestone_progress_notification/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2024 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

{

Check warning on line 4 in project_milestone_progress_notification/__manifest__.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

project_milestone_progress_notification/__manifest__.py#L4

Statement seems to have no effect
"name": "Project Milestone Progress Notification",
"version": "1.0.0",
"author": "Numigi",
"maintainer": "Numigi",
"website": "https://bit.ly/numigi-com",
"license": "AGPL-3",
"category": "project",
"depends": [
"project_milestone",
],
"summary": "Sends email notification when reaching project milestone progression.",
"data": [
"views/res_config_settings_views.xml",
"data/mail_template_data.xml",
"data/res_config_settings_data.xml",
],
"installable": True,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version='1.0' encoding='utf-8'?>
<odoo noupdate="1">
<record id="mail_template_project_milestone_progress_notification" model="mail.template">
<field name="name">Project Milestone Progress Notification</field>
<field name="model_id" ref="project_milestone.model_project_milestone"/>
<field name="auto_delete" eval="False"/>
<field name="email_from">${('&lt;%s&gt;' % (object.env.user.company_id.email or '')) | safe}</field>
<field name="email_to">${object.project_id.user_id.email}</field>
<field name="subject">Milestone Progress Notification</field>
<field name="body_html"><![CDATA[
<p>Dear ${object.project_id.user_id.name},</p>
<p>This is to inform you that the milestone <strong>${object.name}</strong> of the project <strong>${object.project_id.name}</strong> is <strong>${round(object.progress)}%</strong> completed.</p>
<p>Thank you.</p>
]]></field>
</record>
</odoo>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version='1.0' encoding='utf-8'?>
<odoo noupdate="1">
<record id="default_notify_manager" model="ir.config_parameter" forcecreate="0">
<field name="key">project_milestone_progress_notification.default_notify_manager</field>
<field name="value">True</field>
</record>
<record id="default_rate" model="ir.config_parameter" forcecreate="0">
<field name="key">project_milestone_progress_notification.default_rate</field>
<field name="value">100</field>
</record>
<record id="default_mail_template" model="ir.config_parameter" forcecreate="0">
<field name="key">project_milestone_progress_notification.default_mail_template</field>
<field name="value" ref="project_milestone_progress_notification.mail_template_project_milestone_progress_notification"/>
</record>
</odoo>
85 changes: 85 additions & 0 deletions project_milestone_progress_notification/i18n/fr.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * project_milestone_progress_notification
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-27 08:14+0000\n"
"PO-Revision-Date: 2024-11-27 08:14+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_milestone_progress_notification
#: model:mail.template,body_html:project_milestone_progress_notification.mail_template_project_milestone_progress_notification
msgid "\n"
" <p>Dear ${object.project_id.user_id.name},</p>\n"
" <p>This is to inform you that the milestone <strong>${object.name}</strong> of the project <strong>${object.project_id.name}</strong> is <strong>${round(object.progress)}%</strong> completed.</p>\n"
" <p>Thank you.</p>\n"
" "
msgstr "\n"
" <p>Cher ${object.project_id.user_id.name},</p>\n"
" <p>Ceci est pour vous informer que l'étape <strong>${object.name}</strong> du projet <strong>${object.project_id.name}</strong> est <strong>${round(object.progress)}%</strong> complétée.</p>\n"
" <p>Merci.</p>\n"
" "

#. module: project_milestone_progress_notification
#: model:ir.model,name:project_milestone_progress_notification.model_res_config_settings
msgid "Config Settings"
msgstr "Paramètres de configuration"


#. module: project_milestone_progress_notification
#: model:ir.model.fields,field_description:project_milestone_progress_notification.field_project_milestone__last_rate
msgid "Last Rate"
msgstr "Dernier taux"

#. module: project_milestone_progress_notification
#: model:ir.model.fields,field_description:project_milestone_progress_notification.field_res_config_settings__mail_template_id
msgid "Mail Template"
msgstr "Modèle de courriel"

#. module: project_milestone_progress_notification
#: model:mail.template,subject:project_milestone_progress_notification.mail_template_project_milestone_progress_notification
msgid "Milestone Progress Notification"
msgstr "Notification de progression de l'étape de projet"

#. module: project_milestone_progress_notification
#: model_terms:ir.ui.view,arch_db:project_milestone_progress_notification.res_config_settings_view_form_inherit
msgid "Milestone progression notification"
msgstr "Notification de progression de l'étape de projet"

#. module: project_milestone_progress_notification
#: model:ir.model.fields,field_description:project_milestone_progress_notification.field_project_milestone__notification_sent
msgid "Notification Sent"
msgstr "Notification envoyée"

#. module: project_milestone_progress_notification
#: model_terms:ir.ui.view,arch_db:project_milestone_progress_notification.res_config_settings_view_form_inherit
msgid "Notifications"
msgstr "Notifications"

#. module: project_milestone_progress_notification
#: model:ir.model.fields,field_description:project_milestone_progress_notification.field_res_config_settings__notify_manager
msgid "Notify Manager"
msgstr "Notifier le responsable"

#. module: project_milestone_progress_notification
#: model_terms:ir.ui.view,arch_db:project_milestone_progress_notification.res_config_settings_view_form_inherit
msgid "Notify the manager when the milestone is reached"
msgstr "Notifier le responsable lorsque l'étape est atteinte"

#. module: project_milestone_progress_notification
#: model:ir.model,name:project_milestone_progress_notification.model_project_milestone
msgid "Project Milestone"
msgstr "Étape de projet"

#. module: project_milestone_progress_notification
#: model:ir.model.fields,field_description:project_milestone_progress_notification.field_res_config_settings__rate
msgid "Rate"
msgstr "Taux d'atteinte"
5 changes: 5 additions & 0 deletions project_milestone_progress_notification/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 AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import res_config_settings

Check notice on line 4 in project_milestone_progress_notification/models/__init__.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

project_milestone_progress_notification/models/__init__.py#L4

'.res_config_settings' imported but unused (F401)
from . import project_milestone

Check notice on line 5 in project_milestone_progress_notification/models/__init__.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

project_milestone_progress_notification/models/__init__.py#L5

'.project_milestone' imported but unused (F401)
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Copyright 2024 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo import api, fields, models


class ProjectMilestone(models.Model):
_inherit = 'project.milestone'

notification_sent = fields.Boolean(string="Notification Sent")
last_rate = fields.Float(string="Last Rate")
progress_check = fields.Boolean(
string="Last Progress Rate",
store=True,
compute='_compute_progress_check',
)

@api.depends('progress')
def _compute_progress_check(self):
rate = float(
self.env['ir.config_parameter']
.sudo()
.get_param('project_milestone_progress_notification.default_rate')
)
for milestone in self:
should_send_notification = milestone.progress >= rate and (
not milestone.notification_sent or milestone.last_rate < rate
)
if should_send_notification:
template_id = (
self.env['ir.config_parameter']
.sudo()
.get_param(
'project_milestone_progress_notification.default_mail_template'
)
)
milestone.message_post_with_template(int(template_id))
milestone.write({'notification_sent': True, 'last_rate': rate})
elif milestone.progress < rate and milestone.notification_sent:
milestone.write({'notification_sent': False, 'last_rate': rate})
else:
pass

self.env.cr.commit()
milestone.progress_check = True
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright 2024 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
from odoo.exceptions import ValidationError


class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'

notify_manager = fields.Boolean(string="Notify Manager")
rate = fields.Float(string="Rate")
mail_template_id = fields.Many2one('mail.template', string='Mail Template')

def set_values(self):
super(ResConfigSettings, self).set_values()
if not self.check_values():
raise ValidationError(
"Please set Progress Rate greater than 0 and select Mail Template when Notify Manager is checked."
)
self.env['ir.config_parameter'].set_param(
'project_milestone_progress_notification.default_notify_manager',
self.notify_manager,
)
self.env['ir.config_parameter'].set_param(
'project_milestone_progress_notification.default_mail_template',
self.mail_template_id.id,
)
self.env['ir.config_parameter'].set_param(
'project_milestone_progress_notification.default_rate', self.rate
)

def get_values(self):
res = super(ResConfigSettings, self).get_values()
res.update(
notify_manager=self.env['ir.config_parameter'].get_param(
'project_milestone_progress_notification.default_notify_manager'
),
mail_template_id=int(
self.env['ir.config_parameter'].get_param(
'project_milestone_progress_notification.default_mail_template'
)
or 0
),
rate=float(
self.env['ir.config_parameter'].get_param(
'project_milestone_progress_notification.default_rate'
)
or 0.0
),
)
return res

def check_values(self):
if self.notify_manager and (self.rate == 0 or not self.mail_template_id):
return False
return True
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.
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_milestone_progress_notification/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright 2024 Numigi (tm) and all its contributors (https://bit.ly/numigiens)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import test_project_milestone_notification

Check notice on line 4 in project_milestone_progress_notification/tests/__init__.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

project_milestone_progress_notification/tests/__init__.py#L4

'.test_project_milestone_notification' imported but unused (F401)
Loading