[IMP] mail : message_post_with_template helper

Create `message_post_with_template` helper method to factorize the simulation of a mail.compose.message wizard.

Also, fix the generated attachments of mail.compose.message wizard by returning ORM command (6, 0, ids) instead of the list of attachments ids. In order to standardize the behavior of the wizard, and since the ORM support command assignation in onchange api.v8, all the x2many fields of the wizard return a command.

FYI, that was tde's idea !
This commit is contained in:
Jérome Maes
2015-09-04 15:55:38 +02:00
parent 5f8663cdb6
commit 7674536713
6 changed files with 48 additions and 64 deletions
+1 -14
View File
@@ -290,20 +290,7 @@ class Applicant(models.Model):
# post processing: if stage changed, post a message in the chatter
if vals.get('stage_id'):
if self.stage_id.template_id:
# TDENOTE: probably factorize me in a message_post_with_template generic method FIXME
composer = self.env['mail.compose.message'].with_context(active_ids=self.ids).create(
{
'model': self._name,
'composition_mode': 'mass_mail',
'template_id': self.stage_id.template_id.id,
'notify': True,
})
values = composer.onchange_template_id(
self.stage_id.template_id.id, 'mass_mail', self._name, False)['value']
if values.get('attachment_ids'):
values['attachment_ids'] = [(6, 0, values['attachment_ids'])]
composer.write(values)
composer.send_mail()
self.message_post_with_template(self.stage_id.template_id.id, notify=True, composition_mode='mass_mail')
return res
@api.model
+27
View File
@@ -1663,6 +1663,33 @@ class MailThread(models.AbstractModel):
self.message_subscribe([new_message.author_id.id])
return new_message
@api.multi
def message_post_with_template(self, template_id, **kwargs):
""" Helper method to send a mail with a template
:param template_id : the id of the template to render to create the body of the message
:param **kwargs : parameter to create a mail.compose.message woaerd (which inherit from mail.message)
"""
# Get composition mode, or force it according to the number of record in self
composition_mode = kwargs.get('composition_mode')
if not composition_mode:
composition_mode = 'comment' if len(self.ids) == 1 else 'mass_mail'
res_id = self.ids[0] or 0
# Create the composer
composer = self.env['mail.compose.message'].with_context(
active_ids=self.ids,
active_model=self._name,
default_composition_mode=composition_mode,
default_model=self._name,
default_res_id=self.ids[0] or 0,
default_template_id=template_id,
).create(kwargs)
# Simulate the onchange (like trigger in form the view) only
# when having a template in single-email mode
if template_id:
update_values = composer.onchange_template_id(template_id, composition_mode, self._name, res_id)['value']
composer.write(update_values)
return composer.send_mail()
# ------------------------------------------------------
# Followers API
# ------------------------------------------------------
+4 -9
View File
@@ -50,8 +50,9 @@ class TestMailTemplate(TestMail):
}).create({'subject': 'Forget me subject', 'body': 'Dummy body'})
values = composer.onchange_template_id(self.email_template.id, 'comment', 'mail.channel', self.group_pigs.id)['value']
recipients = self.env['res.partner'].browse(values['partner_ids'])
attachments = self.env['ir.attachment'].browse(values['attachment_ids'])
# this onchange return command [(6, 0, ids)] for x2many fields
recipients = self.env['res.partner'].browse(values['partner_ids'][0][2])
attachments = self.env['ir.attachment'].browse(values['attachment_ids'][0][2])
test_recipients = self.env['res.partner'].search([('email', 'in', ['test1@example.com', 'test2@example.com'])]) | self.partner_1 | self.partner_2 | self.user_employee.partner_id
test_attachments = self.env['ir.attachment'].search([('name', 'in', ['_Test_First', '_Test_Second'])])
self.assertEqual(values['subject'], self.group_pigs.name)
@@ -64,13 +65,7 @@ class TestMailTemplate(TestMail):
@mute_logger('openerp.addons.mail.models.mail_mail')
def test_composer_template_send(self):
composer = self.env['mail.compose.message'].with_context({
'default_composition_mode': 'comment',
'default_model': 'mail.channel',
'default_res_id': self.group_pigs.id,
'default_use_template': False,
'default_template_id': self.email_template.id,
}).create({}).send_mail()
self.group_pigs.with_context(use_template=False).message_post_with_template(self.email_template.id, composition_mode='comment')
message = self.group_pigs.message_ids[0]
test_recipients = self.env['res.partner'].search([('email', 'in', ['test1@example.com', 'test2@example.com'])]) | self.partner_1 | self.partner_2 | self.user_employee.partner_id
+13 -12
View File
@@ -94,18 +94,8 @@ class MailComposer(models.TransientModel):
result['model'] = 'res.partner'
result['res_id'] = self.env.user.partner_id.id
# Override to pre-fill the data when having a template in single-email mode
# and not going through the view: the on_change is not called in that case.
if result.get('composition_mode') != 'mass_mail' and self._context.get('default_template_id') and result.get('model') and result.get('res_id'):
result.update(
self.onchange_template_id(
self._context['default_template_id'], result.get('composition_mode'),
result.get('model'), result.get('res_id')
)['value']
)
if fields is not None:
[result.pop(field, None) for field in result.keys() if field not in fields]
return result
@api.model
@@ -330,7 +320,7 @@ class MailComposer(models.TransientModel):
#------------------------------------------------------
@api.multi
@api.onchange('template_id', 'composition_mode', 'model', 'res_id')
@api.onchange('template_id')
def onchange_template_id_wrapper(self):
self.ensure_one()
values = self.onchange_template_id(self.template_id.id, self.composition_mode, self.model, self.res_id)['value']
@@ -340,7 +330,9 @@ class MailComposer(models.TransientModel):
@api.multi
def onchange_template_id(self, template_id, composition_mode, model, res_id):
""" - mass_mailing: we cannot render, so return the template values
- normal mode: return rendered values """
- normal mode: return rendered values
/!\ for x2many field, this onchange return command instead of ids
"""
if template_id and composition_mode == 'mass_mail':
template = self.env['mail.template'].browse(template_id)
fields = ['subject', 'body_html', 'email_from', 'reply_to', 'mail_server_id']
@@ -373,6 +365,15 @@ class MailComposer(models.TransientModel):
if values.get('body_html'):
values['body'] = values.pop('body_html')
# This onchange should return command instead of ids for x2many field.
# ORM handle the assignation of command list on new onchange (api.v8),
# this force the complete replacement of x2many field with the (6, 0, ids)
# command and is compatible with onchange api.v7
for field_name in values.keys():
if self._fields[field_name].type == 'many2many' or self._fields[field_name].type == 'one2many':
values[field_name] = [(6, 0, values[field_name])]
return {'value': values}
@api.multi
@@ -17,19 +17,7 @@ class account_invoice(osv.Model):
self.message_subscribe(cr, uid, [invoice.id], [invoice.partner_id.id], context=context)
for line in invoice.invoice_line_ids:
if line.product_id.email_template_id:
# CLEANME: should define and use a clean API: message_post with a template
composer_id = Composer.create(cr, uid, {
'model': 'account.invoice',
'res_id': invoice.id,
'template_id': line.product_id.email_template_id.id,
'composition_mode': 'comment',
}, context=context)
template_values = Composer.onchange_template_id(
cr, uid, composer_id, line.product_id.email_template_id.id, 'comment', 'account.invoice', invoice.id
)['value']
template_values['attachment_ids'] = [(4, id) for id in template_values.get('attachment_ids', [])]
Composer.write(cr, uid, [composer_id], template_values, context=context)
Composer.send_mail(cr, uid, [composer_id], context=context)
invoice.message_post_with_template(line.product_id.email_template_id.id, composition_mode='comment')
return True
def invoice_validate(self, cr, uid, ids, context=None):
+2 -16
View File
@@ -325,22 +325,9 @@ class SaleOrder(models.Model):
for order in self:
email_act = order.action_quotation_send()
if email_act and email_act.get('context'):
composer_obj = self.env['mail.compose.message']
email_ctx = email_act['context']
template_values = [
email_ctx.get('default_template_id'),
email_ctx.get('default_composition_mode'),
email_ctx.get('default_model'),
email_ctx.get('default_res_id'),
]
composer_values = composer_obj.onchange_template_id(*template_values).get('value', {})
if not composer_values.get('email_from'):
composer_values['email_from'] = order.company_id.email
for key in ['attachment_ids', 'partner_ids']:
if composer_values.get(key):
composer_values[key] = [(6, 0, composer_values[key])]
composer_id = composer_obj.with_context(email_ctx).create(composer_values)
composer_id.with_context(email_ctx).send_mail()
email_ctx.update(default_email_from=order.company_id.email)
order.with_context(email_ctx).message_post_with_template(email_ctx.get('default_template_id'))
return True
@api.multi
@@ -784,4 +771,3 @@ class ProductTemplate(models.Model):
('delivery', 'Delivered quantities'),
('cost', 'Invoice based on time and material')],
string='Invoicing Policy', default='order')