diff --git a/addons/event/security/event_security.xml b/addons/event/security/event_security.xml index 645f798641e..573cbe09155 100644 --- a/addons/event/security/event_security.xml +++ b/addons/event/security/event_security.xml @@ -21,7 +21,7 @@ Administrator - + diff --git a/addons/hr_recruitment/security/hr_recruitment_security.xml b/addons/hr_recruitment/security/hr_recruitment_security.xml index 29a16ef8f3e..14f79b789d0 100644 --- a/addons/hr_recruitment/security/hr_recruitment_security.xml +++ b/addons/hr_recruitment/security/hr_recruitment_security.xml @@ -28,7 +28,7 @@ Administrator - + diff --git a/addons/mail/models/mail_template.py b/addons/mail/models/mail_template.py index 840d4efb4ba..3eff2c4bee2 100644 --- a/addons/mail/models/mail_template.py +++ b/addons/mail/models/mail_template.py @@ -18,7 +18,7 @@ class MailTemplate(models.Model): _name = "mail.template" _inherit = ['mail.render.mixin', 'template.reset.mixin'] _description = 'Email Templates' - _order = 'name' + _order = 'user_id,name,id' _unrestricted_rendering = True @@ -46,6 +46,7 @@ class MailTemplate(models.Model): email_from = fields.Char('From', help="Sender address (placeholders may be used here). If not set, the default " "value will be the author's email alias if configured, or email address.") + user_id = fields.Many2one('res.users', string='User', domain="[('share', '=', False)]", help='The template belongs to this user') # recipients use_default_to = fields.Boolean( 'Default recipients', @@ -88,6 +89,7 @@ class MailTemplate(models.Model): # access can_write = fields.Boolean(compute='_compute_can_write', help='The current user can edit the template.') + is_template_editor = fields.Boolean(compute="_compute_is_template_editor") # Overrides of mail.render.mixin @api.depends('model') @@ -101,6 +103,10 @@ class MailTemplate(models.Model): for template in self: template.can_write = template in writable_templates + @api.depends_context('uid') + def _compute_is_template_editor(self): + self.is_template_editor = self.user_has_groups('mail.group_mail_template_editor') + @api.depends('active', 'description') def _compute_template_category(self): """ Base templates (or master templates) are active templates having @@ -166,10 +172,32 @@ class MailTemplate(models.Model): self._fix_attachment_ownership() return True + def open_delete_confirmation_modal(self): + return { + 'type': 'ir.actions.act_window', + 'view_mode': 'form', + 'res_id': self.id, + 'res_model': self._name, + 'target': 'new', + 'view_id': self.env.ref('mail.mail_template_view_form_confirm_delete').id, + 'context': {'dialog_size': 'medium'}, + 'name': _('Confirmation'), + } + def unlink(self): self.unlink_action() return super(MailTemplate, self).unlink() + def cancel_unlink(self): + return { + 'type': 'ir.actions.act_window', + 'view_mode': 'form', + 'res_id': self.id, + 'res_model': self._name, + 'target': 'new', + 'context': {'dialog_size': 'large'}, + } + @api.returns('self', lambda value: value.id) def copy(self, default=None): default = dict(default or {}, diff --git a/addons/mail/static/src/scss/composer.scss b/addons/mail/static/src/scss/composer.scss index 261b7a5ac7e..6fe5b13e7d4 100644 --- a/addons/mail/static/src/scss/composer.scss +++ b/addons/mail/static/src/scss/composer.scss @@ -48,6 +48,7 @@ } .o_mail_composer_form .o_form_renderer { + padding-bottom: 0px; .oe-bordered-editor[name=body] .o_readonly { border: 1px solid $o-gray-300; padding: 4px; diff --git a/addons/mail/views/mail_template_views.xml b/addons/mail/views/mail_template_views.xml index ecae072cc6c..2ebe4ba1219 100644 --- a/addons/mail/views/mail_template_views.xml +++ b/addons/mail/views/mail_template_views.xml @@ -7,42 +7,35 @@
+ + +
-
- - - - -
@@ -80,13 +72,24 @@ - - - - - + + + + + + + + + + + @@ -95,6 +98,20 @@ + + mail.template.view.form.confirm.delete + mail.template + + +

Are you sure you want to delete this Mail Template?

+
+
+ +
+
+ email.template.tree mail.template @@ -103,6 +120,7 @@ + @@ -120,6 +138,7 @@ + diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index 4657479aa09..0bf09d68f59 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -83,7 +83,10 @@ class MailComposer(models.TransientModel): compute='_compute_body', readonly=False, store=True) parent_id = fields.Many2one( 'mail.message', 'Parent Message', ondelete='set null') - template_id = fields.Many2one('mail.template', 'Use template', domain="[('model', '=', model)]") + template_id = fields.Many2one( + 'mail.template', 'Use template', + domain="[('model', '=', model), '|', ('user_id','=', False), ('user_id', '=', uid)]" + ) attachment_ids = fields.Many2many( 'ir.attachment', 'mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id', string='Attachments', @@ -700,32 +703,55 @@ class MailComposer(models.TransientModel): return mails_sudo - def action_save_as_template(self): - """ hit save as template button: current form value will be a new - template attached to the current document. """ - for record in self: - model = self.env['ir.model']._get(record.model or 'mail.message') - model_name = model.name or '' - template_name = "%s: %s" % (model_name, tools.ustr(record.subject)) - values = { - 'name': template_name, - 'subject': record.subject or False, - 'body_html': record.body or False, - 'model_id': model.id or False, - 'use_default_to': True, - } - template = self.env['mail.template'].create(values) + def open_template_creation_wizard(self): + """ hit save as template button: opens a wizard that prompts for the template's subject. + `create_mail_template` is called when saving the new wizard. """ - if record.attachment_ids: - attachments = self.env['ir.attachment'].sudo().browse(record.attachment_ids.ids).filtered( - lambda a: a.res_model == 'mail.compose.message' and a.create_uid.id == self._uid) - if attachments: - attachments.write({'res_model': template._name, 'res_id': template.id}) - template.attachment_ids |= record.attachment_ids + self.ensure_one() + saved_subject = self.subject + self.subject = False + return { + 'type': 'ir.actions.act_window', + 'view_mode': 'form', + 'view_id': self.env.ref('mail.mail_compose_message_view_form_template_save').id, + 'name': _('Create a new Mail Template'), + 'res_model': 'mail.compose.message', + 'context': {'dialog_size': 'medium', 'mail_composer_saved_subject': saved_subject}, + 'target': 'new', + 'res_id': self.id, + } - # generate the saved template - record.write({'template_id': template.id}) - return _reopen(self, record.id, record.model, context=self.env.context) + def create_mail_template(self): + """ creates a mail template with the information form the current mail composer """ + self.ensure_one() + model_id = self.env['ir.model']._get_id(self.model) + values = { + 'name': self.subject, + 'subject': self.subject, + 'body_html': self.body, + 'model_id': model_id, + 'use_default_to': True, + 'user_id': self.env.uid, + } + template = self.env['mail.template'].create(values) + + if self.attachment_ids: + attachments = self.env['ir.attachment'].sudo().browse(self.attachment_ids.ids).filtered( + lambda a: a.res_model == 'mail.compose.message' and a.create_uid.id == self._uid) + if attachments: + attachments.write({'res_model': template._name, 'res_id': template.id}) + template.attachment_ids = self.attachment_ids + + # generate the saved template + self.write({'template_id': template.id}) + return _reopen(self, self.id, self.model, context={**self.env.context, 'dialog_size': 'large'}) + + def cancel_save_template(self): + """ Restore old subject when canceling the 'save as template' action + as it was erased to let user give a more custom input. """ + self.ensure_one() + self.subject = self.env.context.get('mail_composer_saved_subject') + return _reopen(self, self.id, self.model, context={**self.env.context, 'dialog_size': 'large'}) # ------------------------------------------------------------ # RENDERING / VALUES GENERATION diff --git a/addons/mail/wizard/mail_compose_message_views.xml b/addons/mail/wizard/mail_compose_message_views.xml index 7d6cd5b1cb6..7d59093065f 100644 --- a/addons/mail/wizard/mail_compose_message_views.xml +++ b/addons/mail/wizard/mail_compose_message_views.xml @@ -46,7 +46,9 @@ - + + @@ -56,7 +58,9 @@ - + + @@ -80,10 +84,26 @@ type="object" class="btn-primary" data-hotkey="q" invisible="not subtype_is_log"/>