diff --git a/addons/mail/models/ir_actions.py b/addons/mail/models/ir_actions.py
index bd4b03f3a4c..16abdfeaf8e 100644
--- a/addons/mail/models/ir_actions.py
+++ b/addons/mail/models/ir_actions.py
@@ -1,6 +1,9 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from datetime import date
+from dateutil.relativedelta import relativedelta
+
from odoo import _, api, fields, models
from odoo.exceptions import UserError, ValidationError
@@ -12,7 +15,8 @@ class ServerActions(models.Model):
state = fields.Selection(selection_add=[
('email', 'Send Email'),
- ('followers', 'Add Followers')
+ ('followers', 'Add Followers'),
+ ('next_activity', 'Create Next Activity'),
])
# Followers
partner_ids = fields.Many2many('res.partner', string='Add Followers')
@@ -22,6 +26,29 @@ class ServerActions(models.Model):
'mail.template', 'Email Template', ondelete='set null',
domain="[('model_id', '=', model_id)]",
)
+ # Next Activity
+ activity_type_id = fields.Many2one(
+ 'mail.activity.type', string='Activity',
+ domain="['|', ('res_model_id', '=', False), ('res_model_id', '=', model_id)]")
+ activity_summary = fields.Char('Summary')
+ activity_note = fields.Html('Note')
+ activity_date_deadline_range = fields.Integer(string='Due Date In')
+ activity_date_deadline_range_type = fields.Selection([
+ ('days', 'Days'),
+ ('weeks', 'Weeks'),
+ ('months', 'Months'),
+ ], string='Due type', default='days')
+ activity_user_type = fields.Selection([
+ ('specific', 'Specific User'),
+ ('generic', 'Generic User From Record')], default="specific", required=True,
+ help="Use 'Specific User' to always assign the same user on the next activity. Use 'Generic User From Record' to specify the field name of the user to choose on the record.")
+ activity_user_id = fields.Many2one('res.users', string='Responsible')
+ activity_user_field_name = fields.Char('User field name', help="Technical name of the user on the record", default="user_id")
+
+ @api.onchange('activity_date_deadline_range')
+ def _onchange_activity_date_deadline_range(self):
+ if self.activity_date_deadline_range < 0:
+ raise UserError(_("The 'Due Date In' value can't be negative."))
@api.onchange('template_id')
def on_change_template_id(self):
@@ -35,6 +62,12 @@ class ServerActions(models.Model):
if action.state == 'followers' and not action.model_id.is_mail_thread:
raise ValidationError(_("Add Followers can only be done on a mail thread model"))
+ @api.constrains('state', 'model_id')
+ def _check_activity_mixin(self):
+ for action in self:
+ if action.state == 'next_activity' and not issubclass(self.pool[action.model_id.model], self.pool['mail.thread']):
+ raise ValidationError(_("A next activity can only be planned on models that use the chatter"))
+
@api.model
def run_action_followers_multi(self, action, eval_context=None):
Model = self.env[action.model_id.model]
@@ -51,6 +84,29 @@ class ServerActions(models.Model):
action.template_id.send_mail(self._context.get('active_id'), force_send=False, raise_exception=False)
return False
+ @api.model
+ def run_action_next_activity(self, action, eval_context=None):
+ if not action.activity_type_id or not self._context.get('active_id'):
+ return False
+
+ records = self.env[action.model_id.model].browse(self._context.get('active_ids', self._context.get('active_id')))
+ vals = {
+ 'summary': action.activity_summary or '',
+ 'note': action.activity_note or '',
+ 'activity_type_id': action.activity_type_id.id,
+ }
+ if action.activity_date_deadline_range > 0:
+ vals['date_deadline'] = date.today() + relativedelta(**{action.activity_date_deadline_range_type: action.activity_date_deadline_range})
+ for record in records:
+ if action.activity_user_type == 'specific':
+ user = action.activity_user_id
+ elif action.activity_user_type == 'generic' and action.activity_user_field_name in record:
+ user = record[action.activity_user_field_name]
+ if user:
+ vals['user_id'] = user.id
+ record.activity_schedule(**vals)
+ return False
+
@api.model
def _get_eval_context(self, action=None):
""" Override the method giving the evaluation context but also the
diff --git a/addons/mail/views/ir_actions_views.xml b/addons/mail/views/ir_actions_views.xml
index 381310bf69c..a5a7a0dd6bd 100644
--- a/addons/mail/views/ir_actions_views.xml
+++ b/addons/mail/views/ir_actions_views.xml
@@ -7,6 +7,27 @@
ir.actions.server
+
+
+
+
+
+
+
+
+
+