Skip to content

Commit 1036e37

Browse files
kanda999AungKoKoLin1997
authored andcommitted
[4969][ADD] mail_reply_stage
1 parent e6e5bf1 commit 1036e37

File tree

14 files changed

+747
-0
lines changed

14 files changed

+747
-0
lines changed

mail_reply_stage/README.rst

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
================
2+
Mail Reply Stage
3+
================
4+
5+
..
6+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7+
!! This file is generated by oca-gen-addon-readme !!
8+
!! changes will be overwritten. !!
9+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10+
!! source digest: sha256:3e0a708a7c69ddc0f3b1222b5c268d8d6acc6f32c6de186e7c9a5df995a98bb3
11+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12+
13+
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
14+
:target: https://odoo-community.org/page/development-status
15+
:alt: Beta
16+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
17+
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
18+
:alt: License: AGPL-3
19+
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github
20+
:target: https://github.com/OCA/social/tree/15.0/mail_reply_stage
21+
:alt: OCA/social
22+
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
23+
:target: https://translation.odoo-community.org/projects/social-15-0/social-15-0-mail_reply_stage
24+
:alt: Translate me on Weblate
25+
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
26+
:target: https://runboat.odoo-community.org/builds?repo=OCA/social&target_branch=15.0
27+
:alt: Try me on Runboat
28+
29+
|badge1| |badge2| |badge3| |badge4| |badge5|
30+
31+
This module has the feature to automatically update the stage of the record when a non-internal user sends an update to the record.
32+
33+
**Table of contents**
34+
35+
.. contents::
36+
:local:
37+
38+
Configuration
39+
=============
40+
41+
Go to **Settings > Mail Reply Configurations** and create records according to your needs.
42+
43+
For each record:
44+
45+
- **Model**: Choose a model (required).
46+
- **Parent Field**: Select the field for the parent field ID (e.g., if you select the model as project.task, choose project_id as the parent field). If a parent field is selected, the system will update the reply stage based on the parent (e.g., tasks under the project will use the reply stage of the matched configuration). If this field is left empty, all records without a matching configuration for their project will use the configuration record that does not specify a parent field.
47+
- **Parent Model**: The system will assign this automatically.
48+
- **Parent Field Value**: Set up the name of the parent record (e.g., project name).
49+
- **Parent Stage Field**: Choose the stages field from the parent model to verify that the reply stage is within the parent stages.
50+
- **Reply Stage Field**: Choose the field for the stage that will be automatically updated when a non-internal user sends an update.(required)
51+
- **Reply Stage**: Set the stage value that will be updated.(required)
52+
- **No Reply Stage**: Set the stage value. If the record is in this state, updates from the user will not change the stage of the record.(required)
53+
54+
Bug Tracker
55+
===========
56+
57+
Bugs are tracked on `GitHub Issues <https://github.com/OCA/social/issues>`_.
58+
In case of trouble, please check there if your issue has already been reported.
59+
If you spotted it first, help us to smash it by providing a detailed and welcomed
60+
`feedback <https://github.com/OCA/social/issues/new?body=module:%20mail_reply_stage%0Aversion:%2015.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
61+
62+
Do not contact contributors directly about support or help with technical issues.
63+
64+
Credits
65+
=======
66+
67+
Authors
68+
~~~~~~~
69+
70+
* Quartile
71+
72+
Contributors
73+
~~~~~~~~~~~~
74+
75+
* `Quartile <https://www.quartile.co>`_
76+
77+
* Aung Ko Ko Lin
78+
79+
Maintainers
80+
~~~~~~~~~~~
81+
82+
This module is maintained by the OCA.
83+
84+
.. image:: https://odoo-community.org/logo.png
85+
:alt: Odoo Community Association
86+
:target: https://odoo-community.org
87+
88+
OCA, or the Odoo Community Association, is a nonprofit organization whose
89+
mission is to support the collaborative development of Odoo features and
90+
promote its widespread use.
91+
92+
This module is part of the `OCA/social <https://github.com/OCA/social/tree/15.0/mail_reply_stage>`_ project on GitHub.
93+
94+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

mail_reply_stage/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import models

mail_reply_stage/__manifest__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Copyright 2025 Quartile (https://www.quartile.co)
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
{
4+
"name": "Mail Reply Stage",
5+
"category": "Mail",
6+
"version": "15.0.1.0.0",
7+
"author": "Quartile, Odoo Community Association (OCA)",
8+
"website": "https://github.com/OCA/social",
9+
"license": "AGPL-3",
10+
"depends": ["mail"],
11+
"data": [
12+
"security/ir.model.access.csv",
13+
"views/mail_reply_config_views.xml",
14+
],
15+
"installable": True,
16+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from . import mail_message
2+
from . import mail_reply_config
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Copyright 2025 Quartile (https://www.quartile.co)
2+
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
3+
4+
from odoo import api, models
5+
6+
7+
class MailMessage(models.Model):
8+
_inherit = "mail.message"
9+
10+
@api.model_create_multi
11+
def create(self, values_list):
12+
messages = super().create(values_list)
13+
for message in messages:
14+
user = message.author_id.user_ids[:1]
15+
if user and user.has_group("base.group_user"):
16+
continue
17+
if message.subtype_id and message.subtype_id.internal:
18+
continue
19+
res_model = (
20+
self.env["ir.model"]
21+
.sudo()
22+
.search([("model", "=", message.model)], limit=1)
23+
)
24+
if not res_model:
25+
continue
26+
resource = self.env[message.model].browse(message.res_id)
27+
config_records = self.env["mail.reply.config"].search(
28+
[("model_id", "=", res_model.id)]
29+
)
30+
matched_config = None
31+
parent_field_rec = None
32+
for config in config_records:
33+
if config.parent_field_id:
34+
parent_field_rec = getattr(
35+
resource, config.parent_field_id.name, None
36+
)
37+
if (
38+
parent_field_rec
39+
and getattr(parent_field_rec, "name", None)
40+
== config.parent_field_value
41+
):
42+
matched_config = config
43+
break
44+
else:
45+
matched_config = config
46+
if not matched_config:
47+
continue
48+
current_stage = getattr(
49+
resource, matched_config.reply_stage_field_id.name, None
50+
)
51+
if current_stage == matched_config.remain_stage:
52+
continue
53+
reply_stage_rec = self.env[
54+
matched_config.reply_stage_field_id.relation
55+
].search([("name", "=", matched_config.reply_stage)])
56+
if matched_config.parent_stage_field_id:
57+
allowed_stages = getattr(
58+
parent_field_rec,
59+
matched_config.parent_stage_field_id.name,
60+
self.env[matched_config.parent_stage_field_id.relation],
61+
)
62+
reply_stage_rec = reply_stage_rec.filtered(
63+
lambda stage: stage in allowed_stages
64+
)
65+
if reply_stage_rec:
66+
resource.sudo().write(
67+
{matched_config.reply_stage_field_id.name: reply_stage_rec.id}
68+
)
69+
return messages
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Copyright 2025 Quartile (https://www.quartile.co)
2+
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
3+
4+
from odoo import api, fields, models
5+
6+
7+
class MailReplyStage(models.Model):
8+
_name = "mail.reply.config"
9+
10+
model_id = fields.Many2one(
11+
"ir.model", string="Model", required=True, ondelete="cascade"
12+
)
13+
parent_field_id = fields.Many2one(
14+
"ir.model.fields",
15+
string="Parent Field",
16+
domain="[('model_id', '=', model_id), ('ttype', '=', 'many2one')]",
17+
ondelete="cascade",
18+
)
19+
parent_model_name = fields.Char(
20+
related="parent_field_id.relation",
21+
string="Parent Model",
22+
store=True,
23+
help="Automatically stores the model name of the related parent entity.",
24+
)
25+
parent_stage_field_id = fields.Many2one(
26+
"ir.model.fields",
27+
string="Parent Stage Field",
28+
domain="[('model_id.model', '=', parent_model_name), ('ttype', '=', 'many2many')]",
29+
ondelete="cascade",
30+
help="A Many2Many field within the parent model that defines "
31+
"valid stages for this configuration.",
32+
)
33+
parent_field_value = fields.Char(
34+
help="The specific value of the parent field that this configuration applies to. "
35+
"For example, a project name."
36+
)
37+
reply_stage_field_id = fields.Many2one(
38+
"ir.model.fields",
39+
domain="[('model_id', '=', model_id), ('ttype', '=', 'many2one')]",
40+
required=True,
41+
ondelete="cascade",
42+
)
43+
reply_stage = fields.Char(
44+
required=True,
45+
help="This stage of record will be changed when a non-internal user "
46+
"replies to the record.",
47+
)
48+
remain_stage = fields.Char(
49+
string="No Reply Stage",
50+
required=True,
51+
help="Record in this stage will not update to the mail reply stage "
52+
"when a non-internal user replies to the record.",
53+
)
54+
55+
@api.onchange("model_id")
56+
def _onchange_model_id(self):
57+
self.reply_stage_field_id = False
58+
59+
@api.onchange("reply_stage_field_id")
60+
def _onchange_reply_stage_field_id(self):
61+
self.reply_stage = False
62+
self.remain_stage = False
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Go to **Settings > Mail Reply Configurations** and create records according to your needs.
2+
3+
For each record:
4+
5+
- **Model**: Choose a model (required).
6+
- **Parent Field**: Select the field for the parent field ID (e.g., if you select the model as project.task, choose project_id as the parent field). If a parent field is selected, the system will update the reply stage based on the parent (e.g., tasks under the project will use the reply stage of the matched configuration). If this field is left empty, all records without a matching configuration for their project will use the configuration record that does not specify a parent field.
7+
- **Parent Model**: The system will assign this automatically.
8+
- **Parent Field Value**: Set up the name of the parent record (e.g., project name).
9+
- **Parent Stage Field**: Choose the stages field from the parent model to verify that the reply stage is within the parent stages.
10+
- **Reply Stage Field**: Choose the field for the stage that will be automatically updated when a non-internal user sends an update.(required)
11+
- **Reply Stage**: Set the stage value that will be updated.(required)
12+
- **No Reply Stage**: Set the stage value. If the record is in this state, updates from the user will not change the stage of the record.(required)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
* `Quartile <https://www.quartile.co>`_
2+
3+
* Aung Ko Ko Lin
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This module has the feature to automatically update the stage of the record when a non-internal user sends an update to the record.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
2+
access_mail_reply_config_all,mail.reply.config.all,model_mail_reply_config,,1,0,0,0
3+
access_mail_reply_config_admin,mail.reply.config.admin,model_mail_reply_config,base.group_system,1,1,1,1

0 commit comments

Comments
 (0)