[IMP] mail: now defines a catchall email alias, used to format the

reply_to of notification emails when having a document without alias, or for
private discussions using external mail readers.

bzr revid: tde@openerp.com-20130516150900-khb1d1ygyuos1wrl
This commit is contained in:
Thibault Delavallée
2013-05-16 17:09:00 +02:00
parent f4ad388635
commit bc4964de13
5 changed files with 144 additions and 15 deletions
+23 -13
View File
@@ -93,31 +93,41 @@ class mail_mail(osv.Model):
""" Return a specific reply_to: alias of the document through message_get_reply_to
or take the email_from
"""
# if value specified: directly return it
if values.get('reply_to'):
return values.get('reply_to')
email_reply_to = False
# model, res_id: comes from values OR related message
model = values.get('model')
res_id = values.get('res_id')
if values.get('mail_message_id') and (not model or not res_id):
mailgateway = True # tells whether the answer will go through the mailgateway, leading to the formatting of reply_to <Followers of ...>
ir_config_parameter = self.pool.get("ir.config_parameter")
catchall_domain = ir_config_parameter.get_param(cr, uid, "mail.catchall.domain", context=context)
# model, res_id, email_from, reply_to: comes from values OR related message
message = None
if values.get('mail_message_id'):
message = self.pool.get('mail.message').browse(cr, uid, values.get('mail_message_id'), context=context)
if not model:
model = message.model
if not res_id:
res_id = message.res_id
model = values.get('model', message and message.model or False)
res_id = values.get('res_id', message and message.res_id or False)
email_from = values.get('email_from', message and message.email_from or False)
email_reply_to = message and message.reply_to or False
# if model and res_id: try to use ``message_get_reply_to`` that returns the document alias
if model and res_id and hasattr(self.pool[model], 'message_get_reply_to'):
if not email_reply_to and model and res_id and hasattr(self.pool[model], 'message_get_reply_to'):
email_reply_to = self.pool[model].message_get_reply_to(cr, uid, [res_id], context=context)[0]
# no alias reply_to -> catchall alias
if not email_reply_to:
catchall_alias = ir_config_parameter.get_param(cr, uid, "mail.catchall.alias", context=context)
if catchall_domain and catchall_alias:
email_reply_to = '%s@%s' % (catchall_alias, catchall_domain)
# no alias reply_to -> reply_to will be the email_from, only the email part
if not email_reply_to and values.get('email_from'):
emails = tools.email_split(values.get('email_from'))
if not email_reply_to and email_from:
emails = tools.email_split(email_from)
if emails:
email_reply_to = emails[0]
if emails[0].split('@')[1] != catchall_domain:
mailgateway = False
# format 'Document name <email_address>'
if email_reply_to and model and res_id:
if email_reply_to and model and res_id and mailgateway:
document_name = self.pool[model].name_get(cr, SUPERUSER_ID, [res_id], context=context)[0]
if document_name:
# sanitize document name
+1 -1
View File
@@ -743,7 +743,7 @@ class mail_message(osv.Model):
default_starred = context.pop('default_starred', False)
# generate message_id, to redirect answers to the right discussion thread
if not values.get('message_id') and values.get('reply_to'):
values['message_id'] = tools.generate_tracking_message_id('reply_to-%(model)s' % values)
values['message_id'] = tools.generate_tracking_message_id('reply_to')
elif not values.get('message_id') and values.get('res_id') and values.get('model'):
values['message_id'] = tools.generate_tracking_message_id('%(res_id)s-%(model)s' % values)
elif not values.get('message_id'):
+17 -1
View File
@@ -23,13 +23,18 @@ import urlparse
from openerp.osv import osv, fields
class project_configuration(osv.TransientModel):
_inherit = 'base.config.settings'
_columns = {
'alias_domain' : fields.char('Alias Domain',
'alias_domain': fields.char('Alias Domain',
help="If you have setup a catch-all email domain redirected to "
"the OpenERP server, enter the domain name here."),
'alias_catchall': fields.char('Catchall Email Alias',
help="Define the default email that will handle replies to document "
"not having their specific email alias defined. Only the left "
"part is required.")
}
def get_default_alias_domain(self, cr, uid, ids, context=None):
@@ -46,3 +51,14 @@ class project_configuration(osv.TransientModel):
config_parameters = self.pool.get("ir.config_parameter")
for record in self.browse(cr, uid, ids, context=context):
config_parameters.set_param(cr, uid, "mail.catchall.domain", record.alias_domain or '', context=context)
def get_default_alias_catchall(self, cr, uid, ids, context=None):
alias_catchall = self.pool.get("ir.config_parameter").get_param(cr, uid, "mail.catchall.alias", context=context)
if not alias_catchall:
return {}
return {'alias_catchall': alias_catchall}
def set_alias_catchall(self, cr, uid, ids, context=None):
config_parameters = self.pool.get("ir.config_parameter")
for record in self.browse(cr, uid, ids, context=context):
config_parameters.set_param(cr, uid, "mail.catchall.alias", record.alias_catchall or '', context=context)
+4
View File
@@ -11,6 +11,10 @@
<label for="alias_domain" class="oe_inline"/>
<field name="alias_domain" placeholder="mycompany.my.openerp.com" class="oe_inline"/>
</div>
<div>
<label for="alias_catchall" class="oe_inline"/>
<field name="alias_catchall" placeholder="gateway" class="oe_inline"/>
</div>
</xpath>
</field>
</record>
+99
View File
@@ -123,6 +123,105 @@ class TestMailgateway(TestMailBase):
self.assertEqual(partner_info['partner_id'], p_b_id,
'mail_thread: message_find_partner_from_emails wrong partner found')
def test_05_mail_message_mail_mail(self):
""" Tests designed for testing email values based on mail.message, aliases, ... """
cr, uid = self.cr, self.uid
# Data: clean catchall domain
param_ids = self.registry('ir.config_parameter').search(cr, uid, [('key', '=', 'mail.catchall.domain')])
self.registry('ir.config_parameter').unlink(cr, uid, param_ids)
# Do: create a mail_message with a reply_to, without message-id
msg_id = self.mail_message.create(cr, uid, {'subject': 'Subject', 'body': 'Body', 'reply_to': 'custom@example.com'})
msg = self.mail_message.browse(cr, uid, msg_id)
# Test: message content
self.assertIn('reply_to', msg.message_id,
'mail_message: message_id should be specific to a mail_message with a given reply_to')
self.assertEqual('custom@example.com', msg.reply_to,
'mail_message: incorrect reply_to')
# Do: create a mail_mail with the previous mail_message and specified reply_to
mail_id = self.mail_mail.create(cr, uid, {'mail_message_id': msg_id, 'reply_to': 'other@example.com', 'state': 'cancel'})
mail = self.mail_mail.browse(cr, uid, mail_id)
# Test: mail_mail content
self.assertEqual(mail.reply_to, 'other@example.com',
'mail_mail: reply_to should be equal to the one coming from creation values')
# Do: create a mail_mail with the previous mail_message
mail_id = self.mail_mail.create(cr, uid, {'mail_message_id': msg_id, 'state': 'cancel'})
mail = self.mail_mail.browse(cr, uid, mail_id)
# Test: mail_mail content
self.assertEqual(mail.reply_to, msg.reply_to,
'mail_mail: reply_to should be equal to the one coming from the mail_message')
# Do: create a mail_message without a reply_to
msg_id = self.mail_message.create(cr, uid, {'subject': 'Subject', 'body': 'Body', 'model': 'mail.group', 'res_id': self.group_pigs_id, 'email_from': False})
msg = self.mail_message.browse(cr, uid, msg_id)
# Test: message content
self.assertIn('mail.group', msg.message_id,
'mail_message: message_id should contain model')
self.assertIn('%s' % self.group_pigs_id, msg.message_id,
'mail_message: message_id should contain res_id')
self.assertFalse(msg.reply_to,
'mail_message: should not generate a reply_to address when not specified')
# Do: create a mail_mail based on the previous mail_message
mail_id = self.mail_mail.create(cr, uid, {'mail_message_id': msg_id, 'state': 'cancel'})
mail = self.mail_mail.browse(cr, uid, mail_id)
# Test: mail_mail content
self.assertFalse(mail.reply_to,
'mail_mail: reply_to should not have been guessed')
# Update message
self.mail_message.write(cr, uid, [msg_id], {'email_from': 'someone@example.com'})
msg.refresh()
# Do: create a mail_mail based on the previous mail_message
mail_id = self.mail_mail.create(cr, uid, {'mail_message_id': msg_id, 'state': 'cancel'})
mail = self.mail_mail.browse(cr, uid, mail_id)
# Test: mail_mail content
self.assertEqual(mail.reply_to, msg.email_from,
'mail_mail: reply_to should equal to mail_message.email_from when having no document or default alias')
# Data: set catchall domain
self.registry('ir.config_parameter').set_param(self.cr, self.uid, 'mail.catchall.domain', 'schlouby.fr')
# Do: create a mail_mail based on the previous mail_message
mail_id = self.mail_mail.create(cr, uid, {'mail_message_id': msg_id, 'state': 'cancel'})
mail = self.mail_mail.browse(cr, uid, mail_id)
# Test: mail_mail content
self.assertEqual(mail.reply_to, '"Followers of Pigs" <group+pigs@schlouby.fr>',
'mail_mail: reply_to should equal the mail.group alias')
# Update message
self.mail_message.write(cr, uid, [msg_id], {'res_id': False, 'email_from': 'someone@schlouby.fr'})
msg.refresh()
# Do: create a mail_mail based on the previous mail_message
mail_id = self.mail_mail.create(cr, uid, {'mail_message_id': msg_id, 'state': 'cancel'})
mail = self.mail_mail.browse(cr, uid, mail_id)
# Test: mail_mail content
self.assertEqual(mail.reply_to, msg.email_from,
'mail_mail: reply_to should equal the mail_message email_from')
# Data: set catchall alias
self.registry('ir.config_parameter').set_param(self.cr, self.uid, 'mail.catchall.alias', 'gateway')
# Do: create a mail_mail based on the previous mail_message
mail_id = self.mail_mail.create(cr, uid, {'mail_message_id': msg_id, 'state': 'cancel'})
mail = self.mail_mail.browse(cr, uid, mail_id)
# Test: mail_mail content
self.assertEqual(mail.reply_to, 'gateway@schlouby.fr',
'mail_mail: reply_to should equal the catchall email alias')
# Do: create a mail_mail
mail_id = self.mail_mail.create(cr, uid, {'state': 'cancel'})
mail = self.mail_mail.browse(cr, uid, mail_id)
# Test: mail_mail content
self.assertEqual(mail.reply_to, 'gateway@schlouby.fr',
'mail_mail: reply_to should equal the catchall email alias')
# Do: create a mail_mail
mail_id = self.mail_mail.create(cr, uid, {'state': 'cancel', 'reply_to': 'someone@example.com'})
mail = self.mail_mail.browse(cr, uid, mail_id)
# Test: mail_mail content
self.assertEqual(mail.reply_to, 'someone@example.com',
'mail_mail: reply_to should equal the rpely_to given to create')
def test_10_message_process(self):
""" Testing incoming emails processing. """
cr, uid, user_raoul = self.cr, self.uid, self.user_raoul