[MERGE]merge with parent branch
bzr revid: sgo@tinyerp.com-20120914053347-u28fihi7mcetup4j
This commit is contained in:
@@ -27,13 +27,15 @@ import time
|
||||
import tools
|
||||
from tools.translate import _
|
||||
|
||||
from base.res.res_partner import format_address
|
||||
|
||||
CRM_LEAD_PENDING_STATES = (
|
||||
crm.AVAILABLE_STATES[2][0], # Cancelled
|
||||
crm.AVAILABLE_STATES[3][0], # Done
|
||||
crm.AVAILABLE_STATES[4][0], # Pending
|
||||
)
|
||||
|
||||
class crm_lead(base_stage, osv.osv):
|
||||
class crm_lead(base_stage, format_address, osv.osv):
|
||||
""" CRM Lead Case """
|
||||
_name = "crm.lead"
|
||||
_description = "Lead/Opportunity"
|
||||
@@ -105,6 +107,12 @@ class crm_lead(base_stage, osv.osv):
|
||||
|
||||
return result, fold
|
||||
|
||||
def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
|
||||
res = super(crm_lead,self).fields_view_get(cr, user, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
|
||||
if view_type == 'form':
|
||||
res['arch'] = self.fields_view_get_address(cr, user, res['arch'], context=context)
|
||||
return res
|
||||
|
||||
_group_by_full = {
|
||||
'stage_id': _read_group_stage_ids
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ The main features of the module are:
|
||||
'website': 'http://www.openerp.com',
|
||||
'depends': ['base', 'base_tools', 'base_setup'],
|
||||
'data': [
|
||||
'wizard/invite_view.xml',
|
||||
'wizard/mail_compose_message_view.xml',
|
||||
'mail_message_subtype.xml',
|
||||
'res_config_view.xml',
|
||||
|
||||
@@ -20,11 +20,13 @@
|
||||
##############################################################################
|
||||
|
||||
import logging
|
||||
import openerp
|
||||
import tools
|
||||
|
||||
from email.header import decode_header
|
||||
from operator import itemgetter
|
||||
from osv import osv, fields
|
||||
from tools.translate import _
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -35,6 +37,7 @@ def decode(text):
|
||||
text = decode_header(text.replace('\r', ''))
|
||||
return ''.join([tools.ustr(x[0], x[1]) for x in text])
|
||||
|
||||
|
||||
class mail_message(osv.Model):
|
||||
""" Messages model: system notification (replacing res.log notifications),
|
||||
comments (OpenChatter discussion) and incoming emails. """
|
||||
@@ -57,7 +60,10 @@ class mail_message(osv.Model):
|
||||
for message in self.browse(cr, uid, ids, context=context):
|
||||
if not message.model or not message.res_id:
|
||||
continue
|
||||
result[message.id] = self._shorten_name(self.pool.get(message.model).name_get(cr, uid, [message.res_id], context=context)[0][1])
|
||||
try:
|
||||
result[message.id] = self._shorten_name(self.pool.get(message.model).name_get(cr, uid, [message.res_id], context=context)[0][1])
|
||||
except openerp.exceptions.AccessDenied, e:
|
||||
pass
|
||||
return result
|
||||
|
||||
def _get_unread(self, cr, uid, ids, name, arg, context=None):
|
||||
@@ -351,3 +357,25 @@ class mail_message(osv.Model):
|
||||
default = {}
|
||||
default.update(message_id=False, headers=False)
|
||||
return super(mail_message, self).copy(cr, uid, id, default=default, context=context)
|
||||
|
||||
#------------------------------------------------------
|
||||
# Tools
|
||||
#------------------------------------------------------
|
||||
|
||||
def check_partners_email(self, cr, uid, partner_ids, context=None):
|
||||
""" Verify that selected partner_ids have an email_address defined.
|
||||
Otherwise throw a warning. """
|
||||
partner_wo_email_lst = []
|
||||
for partner in self.pool.get('res.partner').browse(cr, uid, partner_ids, context=context):
|
||||
if not partner.email:
|
||||
partner_wo_email_lst.append(partner)
|
||||
if not partner_wo_email_lst:
|
||||
return {}
|
||||
warning_msg = _('The following partners chosen as recipients for the email have no email address linked :')
|
||||
for partner in partner_wo_email_lst:
|
||||
warning_msg += '\n- %s' % (partner.name)
|
||||
return {'warning': {
|
||||
'title': _('Partners email addresses not found'),
|
||||
'message': warning_msg,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -629,20 +629,14 @@ class mail_thread(osv.AbstractModel):
|
||||
partner_ids = [user.partner_id.id for user in self.pool.get('res.users').browse(cr, uid, user_ids, context=context)]
|
||||
return self.message_subscribe(cr, uid, ids, partner_ids, context=context)
|
||||
|
||||
def message_subscribe(self, cr, uid, ids, partner_ids,subtype_ids = None, context=None):
|
||||
""" Add partners to the records followers.
|
||||
:param partner_ids: a list of partner_ids to subscribe
|
||||
:param return: new value of followers if read_back key in context
|
||||
"""
|
||||
self.write(cr, uid, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context)
|
||||
def message_subscribe(self, cr, uid, ids, partner_ids, context=None):
|
||||
""" Add partners to the records followers. """
|
||||
if not subtype_ids:
|
||||
subtype_obj = self.pool.get('mail.message.subtype')
|
||||
subtype_ids = subtype_obj.search(cr, uid, [('default', '=', 'true'),('res_model', '=', self._name)],context=context)
|
||||
if subtype_ids:
|
||||
self.message_subscribe_udpate_subtypes(cr, uid, ids, partner_ids, subtype_ids, context=context)
|
||||
if context and context.get('read_back'):
|
||||
return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids]
|
||||
return []
|
||||
return self.write(cr, uid, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context)
|
||||
|
||||
def message_unsubscribe_users(self, cr, uid, ids, user_ids=None, context=None):
|
||||
""" Wrapper on message_subscribe, using users. If user_ids is not
|
||||
@@ -652,14 +646,8 @@ class mail_thread(osv.AbstractModel):
|
||||
return self.message_unsubscribe(cr, uid, ids, partner_ids, context=context)
|
||||
|
||||
def message_unsubscribe(self, cr, uid, ids, partner_ids, context=None):
|
||||
""" Remove partners from the records followers.
|
||||
:param partner_ids: a list of partner_ids to unsubscribe
|
||||
:param return: new value of followers if read_back key in context
|
||||
"""
|
||||
self.write(cr, uid, ids, {'message_follower_ids': [(3, pid) for pid in partner_ids]}, context=context)
|
||||
if context and context.get('read_back'):
|
||||
return [follower.id for thread in self.browse(cr, uid, ids, context=context) for follower in thread.message_follower_ids]
|
||||
return []
|
||||
""" Remove partners from the records followers. """
|
||||
return self.write(cr, uid, ids, {'message_follower_ids': [(3, pid) for pid in partner_ids]}, context=context)
|
||||
|
||||
#------------------------------------------------------
|
||||
# Thread state
|
||||
|
||||
@@ -96,10 +96,6 @@
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.openerp button.oe_mail_button_followers {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.openerp button.oe_mail_button_mouseout {
|
||||
color: white;
|
||||
background-color: #8a89ba;
|
||||
|
||||
@@ -33,20 +33,12 @@ openerp_mail_followers = function(session, mail) {
|
||||
},
|
||||
|
||||
start: function() {
|
||||
var self = this;
|
||||
// NB: all the widget should be modified to check the actual_mode property on view, not use
|
||||
// any other method to know if the view is in create mode anymore
|
||||
// use actual_mode property on view to know if the view is in create mode anymore
|
||||
this.view.on("change:actual_mode", this, this._check_visibility);
|
||||
this._check_visibility();
|
||||
this.fetch_subtype();
|
||||
this.$el.find('ul.oe_mail_recthread_subtype').click(function () {self.update_subtype();})
|
||||
this.$el.find('button.oe_mail_button_follow').click(function () { self.do_follow(); self.fetch_subtype();})
|
||||
.mouseover(function () { $(this).html('Follow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); })
|
||||
.mouseleave(function () { $(this).html('Not following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); });
|
||||
this.$el.find('button.oe_mail_button_unfollow').click(function () { self.do_unfollow(); })
|
||||
.mouseover(function () { $(this).html('Unfollow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); })
|
||||
.mouseleave(function () { $(this).html('Following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); });
|
||||
this.reinit();
|
||||
this.bind_events();
|
||||
},
|
||||
|
||||
_check_visibility: function() {
|
||||
@@ -54,14 +46,40 @@ openerp_mail_followers = function(session, mail) {
|
||||
if (this.view.get("actual_mode") !== "create"){this.fetch_subtype();}
|
||||
},
|
||||
|
||||
destroy: function () {
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
reinit: function() {
|
||||
this.$el.find('button.oe_mail_button_follow').hide();
|
||||
this.$el.find('button.oe_mail_button_unfollow').hide();
|
||||
// this.$el.find('ul.oe_mail_recthread_subtype').hide()
|
||||
},
|
||||
|
||||
bind_events: function() {
|
||||
var self = this;
|
||||
this.$('button.oe_mail_button_unfollow').on('click', function () { self.do_unfollow(); })
|
||||
.mouseover(function () { $(this).html('Unfollow').removeClass('oe_mail_button_mouseout').addClass('oe_mail_button_mouseover'); })
|
||||
.mouseleave(function () { $(this).html('Following').removeClass('oe_mail_button_mouseover').addClass('oe_mail_button_mouseout'); });
|
||||
this.$el.on('click', 'button.oe_mail_button_follow', function () { self.do_follow(); self.fetch_subtype(); });
|
||||
this.$el.on('click','ul.oe_mail_recthread_subtype', function () {self.update_subtype();})
|
||||
this.$el.on('click', 'button.oe_mail_button_invite', function(event) {
|
||||
action = {
|
||||
type: 'ir.actions.act_window',
|
||||
res_model: 'mail.wizard.invite',
|
||||
view_mode: 'form',
|
||||
view_type: 'form',
|
||||
views: [[false, 'form']],
|
||||
target: 'new',
|
||||
context: {
|
||||
'default_res_model': self.view.dataset.model,
|
||||
'default_res_id': self.view.datarecord.id
|
||||
},
|
||||
}
|
||||
self.do_action(action, function() { self.read_value(); });
|
||||
});
|
||||
},
|
||||
|
||||
read_value: function() {
|
||||
var self = this;
|
||||
return this.ds_model.read_ids([this.view.datarecord.id], ['message_follower_ids']).pipe(function (results) {
|
||||
return results[0].message_follower_ids;
|
||||
}).pipe(this.proxy('set_value'));
|
||||
},
|
||||
|
||||
set_value: function(value_) {
|
||||
@@ -71,11 +89,11 @@ openerp_mail_followers = function(session, mail) {
|
||||
this.$el.find('div.oe_mail_recthread_aside').hide();
|
||||
return;
|
||||
}
|
||||
return this.fetch_followers(value_);
|
||||
return this.fetch_followers(value_ || this.get_value());
|
||||
},
|
||||
|
||||
fetch_followers: function (value_) {
|
||||
return this.ds_follow.call('read', [value_ || this.get_value(), ['name', 'user_ids']]).then(this.proxy('display_followers'));
|
||||
return this.ds_follow.call('read', [value_, ['name', 'user_ids']]).pipe(this.proxy('display_followers'));
|
||||
},
|
||||
|
||||
/** Display the followers, evaluate is_follower directly */
|
||||
@@ -131,8 +149,8 @@ openerp_mail_followers = function(session, mail) {
|
||||
},
|
||||
|
||||
do_follow: function () {
|
||||
var context = new session.web.CompoundContext(this.build_context(), {'read_back': true});
|
||||
return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('set_value'));
|
||||
var context = new session.web.CompoundContext(this.build_context(), {});
|
||||
return this.ds_model.call('message_subscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('read_value'));
|
||||
},
|
||||
|
||||
//fetch subtype from subtype model
|
||||
@@ -145,8 +163,8 @@ openerp_mail_followers = function(session, mail) {
|
||||
},
|
||||
|
||||
do_unfollow: function () {
|
||||
var context = new session.web.CompoundContext(this.build_context(), {'read_back': true});
|
||||
return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('set_value'));
|
||||
var context = new session.web.CompoundContext(this.build_context(), {});
|
||||
return this.ds_model.call('message_unsubscribe_users', [[this.view.datarecord.id], undefined, context]).pipe(this.proxy('read_value'));
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
<!-- dropdown menu with message options and actions -->
|
||||
<span class="oe_dropdown_toggle oe_dropdown_arrow">
|
||||
<ul class="oe_dropdown_menu">
|
||||
<li t-if="record.is_author & options.show_dd_delete"><a class="oe_mail_msg_delete" t-attf-data-id='{record.id}'>Delete</a></li>
|
||||
<li t-if="record.is_author and options.show_dd_delete"><a class="oe_mail_msg_delete" t-attf-data-id='{record.id}'>Delete</a></li>
|
||||
<li t-if="options.show_dd_hide"><a class="oe_mail_msg_hide" t-attf-data-id='{record.id}'>Remove notification</a></li>
|
||||
<!-- Uncomment when adding subtype hiding
|
||||
<li t-if="display['show_hide']">
|
||||
@@ -130,14 +130,14 @@
|
||||
<t t-raw="record.subject"/>
|
||||
</h1>
|
||||
<div class="oe_mail_msg_body">
|
||||
<t t-if="options.show_record_name & (!record.subject) & (options.thread_level > 0)">
|
||||
<t t-if="options.show_record_name and record.record_name and (!record.subject) and (options.thread_level > 0)">
|
||||
<a t-attf-href="#model=#{record.model}&id=#{record.res_id}"><t t-raw="record.record_name"/></a>
|
||||
</t>
|
||||
<t t-raw="record.body"/>
|
||||
</div>
|
||||
<div class="oe_clear"/>
|
||||
<ul class="oe_mail_msg_footer">
|
||||
<li t-if="options.show_record_name & record.subject & options.thread_level > 0">
|
||||
<li t-if="options.show_record_name and record.record_name and record.subject and options.thread_level > 0">
|
||||
<a t-attf-href="#model=#{record.model}&id=#{record.res_id}"><t t-raw="record.record_name"/></a>
|
||||
</li>
|
||||
<li><a t-attf-href="#model=res.partner&id=#{record.author_id[0]}"><t t-raw="record.author_id[1]"/></a></li>
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import tools
|
||||
|
||||
from openerp.tests import common
|
||||
from openerp.tools.html_sanitize import html_sanitize
|
||||
|
||||
@@ -82,15 +84,42 @@ Sylvie
|
||||
"""
|
||||
|
||||
|
||||
class test_mail(common.TransactionCase):
|
||||
class TestMailMockups(common.TransactionCase):
|
||||
|
||||
def _mock_smtp_gateway(self, *args, **kwargs):
|
||||
return True
|
||||
|
||||
def _init_mock_build_email(self):
|
||||
self._build_email_args_list = []
|
||||
self._build_email_kwargs_list = []
|
||||
|
||||
def _mock_build_email(self, *args, **kwargs):
|
||||
self._build_email_args = args
|
||||
self._build_email_kwargs = kwargs
|
||||
return self.build_email_real(*args, **kwargs)
|
||||
self._build_email_args_list.append(args)
|
||||
self._build_email_kwargs_list.append(kwargs)
|
||||
return self._build_email(*args, **kwargs)
|
||||
|
||||
def setUp(self):
|
||||
super(TestMailMockups, self).setUp()
|
||||
# Install mock SMTP gateway
|
||||
self._init_mock_build_email()
|
||||
self._build_email = self.registry('ir.mail_server').build_email
|
||||
self.registry('ir.mail_server').build_email = self._mock_build_email
|
||||
self._send_email = self.registry('ir.mail_server').send_email
|
||||
self.registry('ir.mail_server').send_email = self._mock_smtp_gateway
|
||||
|
||||
def tearDown(self):
|
||||
# Remove mocks
|
||||
self.registry('ir.mail_server').build_email = self._build_email
|
||||
self.registry('ir.mail_server').send_email = self._send_email
|
||||
super(TestMailMockups, self).tearDown()
|
||||
|
||||
|
||||
class test_mail(TestMailMockups):
|
||||
|
||||
def _mock_send_get_mail_body(self, *args, **kwargs):
|
||||
# def _send_get_mail_body(self, cr, uid, mail, partner=None, context=None)
|
||||
body = tools.append_content_to_html(args[2].body_html, kwargs.get('partner').name if kwargs.get('partner') else 'No specific partner')
|
||||
return body
|
||||
|
||||
def setUp(self):
|
||||
super(test_mail, self).setUp()
|
||||
@@ -106,10 +135,9 @@ class test_mail(common.TransactionCase):
|
||||
self.res_users = self.registry('res.users')
|
||||
self.res_partner = self.registry('res.partner')
|
||||
|
||||
# Install mock SMTP gateway
|
||||
self.build_email_real = self.registry('ir.mail_server').build_email
|
||||
self.registry('ir.mail_server').build_email = self._mock_build_email
|
||||
self.registry('ir.mail_server').send_email = self._mock_smtp_gateway
|
||||
# Mock send_get_mail_body to test its functionality without other addons override
|
||||
self._send_get_mail_body = self.registry('mail.mail').send_get_mail_body
|
||||
self.registry('mail.mail').send_get_mail_body = self._mock_send_get_mail_body
|
||||
|
||||
# groups@.. will cause the creation of new mail groups
|
||||
self.mail_group_model_id = self.ir_model.search(self.cr, self.uid, [('model', '=', 'mail.group')])[0]
|
||||
@@ -119,6 +147,11 @@ class test_mail(common.TransactionCase):
|
||||
self.group_pigs_id = self.mail_group.create(self.cr, self.uid,
|
||||
{'name': 'Pigs', 'description': 'Fans of Pigs, unite !'})
|
||||
|
||||
def tearDown(self):
|
||||
# Remove mocks
|
||||
self.registry('mail.mail').send_get_mail_body = self._send_get_mail_body
|
||||
super(test_mail, self).tearDown()
|
||||
|
||||
def test_00_message_process(self):
|
||||
cr, uid = self.cr, self.uid
|
||||
# Incoming mail creates a new mail_group "frogs"
|
||||
@@ -275,18 +308,20 @@ class test_mail(common.TransactionCase):
|
||||
_attachments = [('First', 'My first attachment'), ('Second', 'My second attachment')]
|
||||
|
||||
# CASE1: post comment, body and subject specified
|
||||
self._init_mock_build_email()
|
||||
msg_id = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body1, subject=_subject, type='comment')
|
||||
message = self.mail_message.browse(cr, uid, msg_id)
|
||||
sent_email = self._build_email_kwargs
|
||||
sent_emails = self._build_email_kwargs_list
|
||||
# Test: notifications have been deleted
|
||||
self.assertFalse(self.mail_mail.search(cr, uid, [('mail_message_id', '=', msg_id)]), 'mail.mail notifications should have been auto-deleted!')
|
||||
# Test: mail_message: subject is _subject, body is _body1 (no formatting done)
|
||||
self.assertEqual(message.subject, _subject, 'mail.message subject incorrect')
|
||||
self.assertEqual(message.body, _body1, 'mail.message body incorrect')
|
||||
# Test: sent_email: email send by server: correct subject, body; body_alternative
|
||||
self.assertEqual(sent_email['subject'], _subject, 'sent_email subject incorrect')
|
||||
self.assertEqual(sent_email['body'], _mail_body1, 'sent_email body incorrect')
|
||||
self.assertEqual(sent_email['body_alternative'], _mail_bodyalt1, 'sent_email body_alternative is incorrect')
|
||||
# Test: sent_email: email send by server: correct subject, body, body_alternative
|
||||
for sent_email in sent_emails:
|
||||
self.assertEqual(sent_email['subject'], _subject, 'sent_email subject incorrect')
|
||||
self.assertEqual(sent_email['body'], _mail_body1 + '\n<pre>Bert Tartopoils</pre>\n', 'sent_email body incorrect')
|
||||
self.assertEqual(sent_email['body_alternative'], _mail_bodyalt1 + '\nBert Tartopoils', 'sent_email body_alternative is incorrect')
|
||||
# Test: mail_message: partner_ids = group followers
|
||||
message_pids = set([partner.id for partner in message.partner_ids])
|
||||
test_pids = set([p_a_id, p_b_id, p_c_id])
|
||||
@@ -296,14 +331,16 @@ class test_mail(common.TransactionCase):
|
||||
notif_pids = set([notif.partner_id.id for notif in self.mail_notification.browse(cr, uid, notif_ids)])
|
||||
self.assertEqual(notif_pids, test_pids, 'mail.message notification partners incorrect')
|
||||
# Test: sent_email: email_to should contain b@b, not c@c (pref email), not a@a (writer)
|
||||
self.assertEqual(sent_email['email_to'], ['b@b'], 'sent_email email_to is incorrect')
|
||||
for sent_email in sent_emails:
|
||||
self.assertEqual(sent_email['email_to'], ['b@b'], 'sent_email email_to is incorrect')
|
||||
|
||||
# CASE2: post an email with attachments, parent_id, partner_ids
|
||||
# TESTS: automatic subject, signature in body_html, attachments propagation
|
||||
self._init_mock_build_email()
|
||||
msg_id2 = self.mail_group.message_post(cr, uid, self.group_pigs_id, body=_body2, type='email',
|
||||
partner_ids=[(6, 0, [p_d_id])], parent_id=msg_id, attachments=_attachments)
|
||||
message = self.mail_message.browse(cr, uid, msg_id2)
|
||||
sent_email = self._build_email_kwargs
|
||||
sent_emails = self._build_email_kwargs_list
|
||||
self.assertFalse(self.mail_mail.search(cr, uid, [('mail_message_id', '=', msg_id2)]), 'mail.mail notifications should have been auto-deleted!')
|
||||
|
||||
# Test: mail_message: subject is False, body is _body2 (no formatting done), parent_id is msg_id
|
||||
@@ -311,9 +348,11 @@ class test_mail(common.TransactionCase):
|
||||
self.assertEqual(message.body, html_sanitize(_body2), 'mail.message body incorrect')
|
||||
self.assertEqual(message.parent_id.id, msg_id, 'mail.message parent_id incorrect')
|
||||
# Test: sent_email: email send by server: correct subject, body, body_alternative
|
||||
self.assertEqual(sent_email['subject'], _mail_subject, 'sent_email subject incorrect')
|
||||
self.assertEqual(sent_email['body'], _mail_body2, 'sent_email body incorrect')
|
||||
self.assertEqual(sent_email['body_alternative'], _mail_bodyalt2, 'sent_email body_alternative incorrect')
|
||||
self.assertEqual(len(sent_emails), 2, 'sent_email number of sent emails incorrect')
|
||||
for sent_email in sent_emails:
|
||||
self.assertEqual(sent_email['subject'], _mail_subject, 'sent_email subject incorrect')
|
||||
self.assertIn(_mail_body2, sent_email['body'], 'sent_email body incorrect')
|
||||
self.assertIn(_mail_bodyalt2, sent_email['body_alternative'], 'sent_email body_alternative incorrect')
|
||||
# Test: mail_message: partner_ids = group followers
|
||||
message_pids = set([partner.id for partner in message.partner_ids])
|
||||
test_pids = set([p_a_id, p_b_id, p_c_id, p_d_id])
|
||||
@@ -323,7 +362,8 @@ class test_mail(common.TransactionCase):
|
||||
notif_pids = set([notif.partner_id.id for notif in self.mail_notification.browse(cr, uid, notif_ids)])
|
||||
self.assertEqual(notif_pids, test_pids, 'mail.message notification partners incorrect')
|
||||
# Test: sent_email: email_to should contain b@b, c@c, not a@a (writer)
|
||||
self.assertEqual(set(sent_email['email_to']), set(['b@b', 'c@c']), 'sent_email email_to incorrect')
|
||||
for sent_email in sent_emails:
|
||||
self.assertTrue(set(sent_email['email_to']).issubset(set(['b@b', 'c@c'])), 'sent_email email_to incorrect')
|
||||
# Test: attachments
|
||||
for attach in message.attachment_ids:
|
||||
self.assertEqual(attach.res_model, 'mail.group', 'mail.message attachment res_model incorrect')
|
||||
|
||||
@@ -193,24 +193,6 @@ class mail_compose_message(osv.TransientModel):
|
||||
"""
|
||||
return {'value': {'content_subtype': value}}
|
||||
|
||||
def _verify_partner_email(self, cr, uid, partner_ids, context=None):
|
||||
""" Verify that selected partner_ids have an email_address defined.
|
||||
Otherwise throw a warning. """
|
||||
partner_wo_email_lst = []
|
||||
for partner in self.pool.get('res.partner').browse(cr, uid, partner_ids, context=context):
|
||||
if not partner.email:
|
||||
partner_wo_email_lst.append(partner)
|
||||
if not partner_wo_email_lst:
|
||||
return {}
|
||||
warning_msg = _('The following partners chosen as recipients for the email have no email address linked :')
|
||||
for partner in partner_wo_email_lst:
|
||||
warning_msg += '\n- %s' % (partner.name)
|
||||
return {'warning': {
|
||||
'title': _('Partners email addresses not found'),
|
||||
'message': warning_msg,
|
||||
}
|
||||
}
|
||||
|
||||
def onchange_partner_ids(self, cr, uid, ids, value, context=None):
|
||||
""" The basic purpose of this method is to check that destination partners
|
||||
effectively have email addresses. Otherwise a warning is thrown.
|
||||
@@ -219,7 +201,7 @@ class mail_compose_message(osv.TransientModel):
|
||||
res = {'value': {}}
|
||||
if not value or not value[0] or not value[0][0] == 6:
|
||||
return
|
||||
res.update(self._verify_partner_email(cr, uid, value[0][2], context=context))
|
||||
res.update(self.check_partners_email(cr, uid, value[0][2], context=context))
|
||||
return res
|
||||
|
||||
def dummy(self, cr, uid, ids, context=None):
|
||||
|
||||
@@ -30,7 +30,7 @@ class sale_advance_payment_inv(osv.osv_memory):
|
||||
'advance_payment_method':fields.selection(
|
||||
[('all', 'Invoice the whole sale order'), ('percentage','Percentage'), ('fixed','Fixed price (deposit)'),
|
||||
('lines', 'Some order lines')],
|
||||
'Invoice Method', required=True,
|
||||
'What do you want to invoice?', required=True,
|
||||
help="""Use All to create the final invoice.
|
||||
Use Percentage to invoice a percentage of the total amount.
|
||||
Use Fixed Price to invoice a specific amound in advance.
|
||||
|
||||
Reference in New Issue
Block a user