diff --git a/addons/account/data/account_data.xml b/addons/account/data/account_data.xml
index 949d03324f3..9d2e65a3a4c 100644
--- a/addons/account/data/account_data.xml
+++ b/addons/account/data/account_data.xml
@@ -30,7 +30,6 @@
- 15 Days
balance
@@ -48,7 +47,6 @@
- 30 Net Days
balance
diff --git a/addons/account/demo/account_demo.xml b/addons/account/demo/account_demo.xml
index 6918ad44702..8a450c0b6aa 100644
--- a/addons/account/demo/account_demo.xml
+++ b/addons/account/demo/account_demo.xml
@@ -135,7 +135,6 @@
30 Days End of Month
- 30 Days End of Month
balance
@@ -147,16 +146,13 @@
30% Advance End 30 Days
- 30% Advance
procent
-
- Remaining Balance
balance
diff --git a/addons/account_analytic_analysis/account_analytic_analysis_view.xml b/addons/account_analytic_analysis/account_analytic_analysis_view.xml
index 3c477b5556f..6f670b2c6b9 100644
--- a/addons/account_analytic_analysis/account_analytic_analysis_view.xml
+++ b/addons/account_analytic_analysis/account_analytic_analysis_view.xml
@@ -276,7 +276,7 @@
form
tree,form
[('invoice_id','=',False)]
- {'search_default_to_invoice': 1, 'search_default_sales': 1}
+ {'search_default_to_invoice': 1}
diff --git a/addons/account_payment/__openerp__.py b/addons/account_payment/__openerp__.py
index 66d0201b2fe..4c3c8f045e3 100644
--- a/addons/account_payment/__openerp__.py
+++ b/addons/account_payment/__openerp__.py
@@ -53,7 +53,6 @@ have a new option to import payment orders as bank statement lines.
'account_payment_view.xml',
'account_payment_workflow.xml',
'account_payment_sequence.xml',
- 'account_invoice_view.xml',
'account_payment_report.xml',
],
'demo': ['account_payment_demo.xml'],
diff --git a/addons/account_payment/account_invoice.py b/addons/account_payment/account_invoice.py
index 7c8560fc9e8..bcce77a54ce 100644
--- a/addons/account_payment/account_invoice.py
+++ b/addons/account_payment/account_invoice.py
@@ -19,9 +19,8 @@
#
##############################################################################
-from datetime import datetime
from openerp.tools.translate import _
-from openerp.osv import fields, osv
+from openerp.osv import osv
class Invoice(osv.osv):
_inherit = 'account.invoice'
@@ -43,28 +42,6 @@ class Invoice(osv.osv):
raise osv.except_osv(_('Error!'), _("You cannot cancel an invoice which has already been imported in a payment order. Remove it from the following payment order : %s."%(payment_order_name)))
return super(Invoice, self).action_cancel(cr, uid, ids, context=context)
- def _amount_to_pay(self, cursor, user, ids, name, args, context=None):
- '''Return the amount still to pay regarding all the payment orders'''
- if not ids:
- return {}
- res = {}
- for invoice in self.browse(cursor, user, ids, context=context):
- res[invoice.id] = 0.0
- if invoice.move_id:
- for line in invoice.move_id.line_id:
- if not line.date_maturity or \
- datetime.strptime(line.date_maturity, '%Y-%m-%d') \
- < datetime.today():
- res[invoice.id] += line.amount_to_pay
- return res
-
- _columns = {
- 'amount_to_pay': fields.function(_amount_to_pay,
- type='float', string='Amount to be paid',
- help='The amount which should be paid at the current date\n' \
- 'minus the amount which is already in payment order'),
- }
-
Invoice()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_payment/account_invoice_view.xml b/addons/account_payment/account_invoice_view.xml
deleted file mode 100644
index ebb6bcbf965..00000000000
--- a/addons/account_payment/account_invoice_view.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
- account.invoice.supplier.form.inherit
- account.invoice
-
-
-
-
-
-
-
-
-
diff --git a/addons/account_payment/account_move_line.py b/addons/account_payment/account_move_line.py
index 35c30c686e8..c601d9e8da3 100644
--- a/addons/account_payment/account_move_line.py
+++ b/addons/account_payment/account_move_line.py
@@ -19,65 +19,12 @@
#
##############################################################################
-from operator import itemgetter
-from openerp.osv import fields, osv
+from openerp.osv import osv
from openerp.tools.translate import _
class account_move_line(osv.osv):
_inherit = "account.move.line"
- def amount_to_pay(self, cr, uid, ids, name, arg=None, context=None):
- """ Return the amount still to pay regarding all the payemnt orders
- (excepting cancelled orders)"""
- if not ids:
- return {}
- cr.execute("""SELECT ml.id,
- CASE WHEN ml.amount_currency < 0
- THEN - ml.amount_currency
- ELSE ml.credit
- END -
- (SELECT coalesce(sum(amount_currency),0)
- FROM payment_line pl
- INNER JOIN payment_order po
- ON (pl.order_id = po.id)
- WHERE move_line_id = ml.id
- AND po.state != 'cancel') AS amount
- FROM account_move_line ml
- WHERE id IN %s""", (tuple(ids),))
- r = dict(cr.fetchall())
- return r
-
- def _to_pay_search(self, cr, uid, obj, name, args, context=None):
- if not args:
- return []
- line_obj = self.pool.get('account.move.line')
- query = line_obj._query_get(cr, uid, context={})
- where = ' and '.join(map(lambda x: '''(SELECT
- CASE WHEN l.amount_currency < 0
- THEN - l.amount_currency
- ELSE l.credit
- END - coalesce(sum(pl.amount_currency), 0)
- FROM payment_line pl
- INNER JOIN payment_order po ON (pl.order_id = po.id)
- WHERE move_line_id = l.id
- AND po.state != 'cancel'
- ) %(operator)s %%s ''' % {'operator': x[1]}, args))
- sql_args = tuple(map(itemgetter(2), args))
-
- cr.execute(('''SELECT id
- FROM account_move_line l
- WHERE account_id IN (select id
- FROM account_account
- WHERE type=%s AND active)
- AND reconcile_id IS null
- AND credit > 0
- AND ''' + where + ' and ' + query), ('payable',)+sql_args )
-
- res = cr.fetchall()
- if not res:
- return [('id', '=', '0')]
- return [('id', 'in', map(lambda x:x[0], res))]
-
def line2bank(self, cr, uid, ids, payment_type=None, context=None):
"""
Try to return for each Ledger Posting line a corresponding bank
@@ -110,11 +57,6 @@ class account_move_line(osv.osv):
raise osv.except_osv(_('Error!'), _('There is no partner defined on the entry line.'))
return line2bank
- _columns = {
- 'amount_to_pay': fields.function(amount_to_pay,
- type='float', string='Amount to pay', fnct_search=_to_pay_search),
- }
-
account_move_line()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account_payment/account_payment.py b/addons/account_payment/account_payment.py
index bf0377111a8..2b0fe1271d2 100644
--- a/addons/account_payment/account_payment.py
+++ b/addons/account_payment/account_payment.py
@@ -352,7 +352,7 @@ class payment_line(osv.osv):
if move_line_id:
line = move_line_obj.browse(cr, uid, move_line_id, context=context)
- data['amount_currency'] = line.amount_to_pay
+ data['amount_currency'] = line.amount_residual_currency
res = self.onchange_amount(cr, uid, ids, data['amount_currency'], currency,
company_currency, context)
diff --git a/addons/account_payment/account_payment_view.xml b/addons/account_payment/account_payment_view.xml
index c2f27a576a2..aa52d1d443e 100644
--- a/addons/account_payment/account_payment_view.xml
+++ b/addons/account_payment/account_payment_view.xml
@@ -2,29 +2,6 @@
-
-
- account.move.line.form.inherit
- account.move.line
-
-
-
-
-
-
-
-
-
-
@@ -116,7 +93,7 @@
-
+
@@ -242,7 +219,7 @@
-
+
diff --git a/addons/account_payment/wizard/account_payment_order.py b/addons/account_payment/wizard/account_payment_order.py
index f4d695a05d1..4bd969726fe 100644
--- a/addons/account_payment/wizard/account_payment_order.py
+++ b/addons/account_payment/wizard/account_payment_order.py
@@ -82,7 +82,7 @@ class payment_order_create(osv.osv_memory):
date_to_pay = payment.date_scheduled
payment_obj.create(cr, uid,{
'move_line_id': line.id,
- 'amount_currency': line.amount_to_pay,
+ 'amount_currency': line.amount_residual_currency,
'bank_id': line2bank.get(line.id),
'order_id': payment.id,
'partner_id': line.partner_id and line.partner_id.id or False,
@@ -102,7 +102,7 @@ class payment_order_create(osv.osv_memory):
# payment = self.pool.get('payment.order').browse(cr, uid, context['active_id'], context=context)
# Search for move line to pay:
- domain = [('reconcile_id', '=', False), ('account_id.type', '=', 'payable'), ('amount_to_pay', '>', 0)]
+ domain = [('reconcile_id', '=', False), ('account_id.type', '=', 'payable'), ('amount_residual', '>', 0)]
domain = domain + ['|', ('date_maturity', '<=', search_due_date), ('date_maturity', '=', False)]
line_ids = line_obj.search(cr, uid, domain, context=context)
context.update({'line_ids': line_ids})
diff --git a/addons/auth_openid/static/src/css/openid.css b/addons/auth_openid/static/src/css/openid.css
index ab01ffd2f60..57c745f0aca 100644
--- a/addons/auth_openid/static/src/css/openid.css
+++ b/addons/auth_openid/static/src/css/openid.css
@@ -1,25 +1,15 @@
-.login .pane {
- width: 260px;
- height: 175px;
-}
-
-.login .pane input[name='openid_url'] {
+.oe_login .oe_login_pane input[name='openid_url'] {
background: #fff url(../img/login-bg.gif) no-repeat 1px;
padding-left: 20px;
}
-.auth_choice {
- position: static;
- display: none;
+.openerp .oe_login .openid_providers {
+ text-align: center;
}
-
-.openid_providers {
- padding: 0;
- list-style: none;
- float: right;
+.openerp .oe_login .openid_providers ul {
+ display: inline-block;
}
-
-.openid_providers li {
+.openerp .oe_login .openid_providers ul li {
display: block;
float: left;
margin: 0 1px 3px 2px;
@@ -29,7 +19,6 @@
display: block;
width: 24px;
height: 24px;
- border: 1px solid #ddd;
background: #fff url(../img/openid_16.png) no-repeat 50%;
text-indent: -9999px;
overflow: hidden;
@@ -37,20 +26,16 @@
}
.openid_providers a.selected {
- border-color: #9A0404;
+ background-color: #DC5F59;
}
-.openid_providers a[title="Password"] { background-image: url(../img/textfield_key.png); }
-.openid_providers a[title="AOL"] { background-image: url(../img/aol.png); }
-.openid_providers a[title="ClaimID"] { background-image: url(../img/claimid.png); }
-.openid_providers a[title="Google"] { background-image: url(../img/googlefav.png); }
-.openid_providers a[title="Google Apps"] { background-image: url(../img/marketplace.gif); }
-.openid_providers a[title="MyOpenID"] { background-image: url(../img/myopenid.png); }
-.openid_providers a[title="VeriSign"] { background-image: url(../img/verisign.png); }
-.openid_providers a[title="Yahoo!"] { background-image: url(../img/yahoo.png); }
-.openid_providers a[title="Launchpad"] { background-image: url(../img/launchpad.png); }
+.openid_providers a[data-provider="Password"] { background-image: url(../img/textfield_key.png); }
+.openid_providers a[data-provider="AOL"] { background-image: url(../img/aol.png); }
+.openid_providers a[data-provider="ClaimID"] { background-image: url(../img/claimid.png); }
+.openid_providers a[data-provider="Google"] { background-image: url(../img/googlefav.png); }
+.openid_providers a[data-provider="Google Apps"] { background-image: url(../img/marketplace.gif); }
+.openid_providers a[data-provider="MyOpenID"] { background-image: url(../img/myopenid.png); }
+.openid_providers a[data-provider="VeriSign"] { background-image: url(../img/verisign.png); }
+.openid_providers a[data-provider="Yahoo!"] { background-image: url(../img/yahoo.png); }
+.openid_providers a[data-provider="Launchpad"] { background-image: url(../img/launchpad.png); }
-
-li.auth_choice.selected {
- display: table-row;
-}
diff --git a/addons/auth_openid/static/src/js/auth_openid.js b/addons/auth_openid/static/src/js/auth_openid.js
index f8615481a40..ac2804cb130 100644
--- a/addons/auth_openid/static/src/js/auth_openid.js
+++ b/addons/auth_openid/static/src/js/auth_openid.js
@@ -14,6 +14,16 @@ instance.web.Login = instance.web.Login.extend({
self.$openid_selected_input = $();
self.$openid_selected_provider = null;
+
+ // Hook auth_signup events. noop if module is not installed.
+ self.on('change:login_mode', self, function() {
+ var mode = self.get('login_mode') || 'default';
+ if (mode !== 'default') {
+ return;
+ }
+ self.do_openid_select(self.$openid_selected_button, self.$openid_selected_provider, true);
+ });
+
var openIdProvider = null;
if (self.has_local_storage && self.remember_credentials) {
@@ -21,12 +31,10 @@ instance.web.Login = instance.web.Login.extend({
}
if (openIdProvider) {
- $openid_selected_provider = openIdProvider;
+ self.$openid_selected_provider = openIdProvider;
self.do_openid_select('a[href="#' + openIdProvider + '"]', openIdProvider, true);
- if (self.has_local_storage && self.remember_credentials) {
- self.$openid_selected_input.find('input').val(localStorage.getItem('openid-login'));
- }
+ self.$openid_selected_input.find('input').val(localStorage.getItem('openid-login') || '');
}
else {
self.do_openid_select('a[data-url=""]', 'login,password', true);
@@ -49,11 +57,12 @@ instance.web.Login = instance.web.Login.extend({
do_openid_select: function (button, provider, noautosubmit) {
var self = this;
+ self.$('li[data-provider]').hide();
self.$openid_selected_button.add(self.$openid_selected_input).removeClass('selected');
self.$openid_selected_button = self.$el.find(button).addClass('selected');
var input = _(provider.split(',')).map(function(p) { return 'li[data-provider="'+p+'"]'; }).join(',');
- self.$openid_selected_input = self.$el.find(input).addClass('selected');
+ self.$openid_selected_input = self.$el.find(input).show();
self.$openid_selected_input.find('input:first').focus();
self.$openid_selected_provider = (self.$openid_selected_button.attr('href') || '').substr(1);
@@ -62,7 +71,7 @@ instance.web.Login = instance.web.Login.extend({
localStorage.setItem('openid-provider', self.$openid_selected_provider);
}
- if (!noautosubmit && self.$openid_selected_input.length == 0) {
+ if (!noautosubmit && self.$openid_selected_input.length === 0) {
self.$el.find('form').submit();
}
diff --git a/addons/auth_openid/static/src/xml/auth_openid.xml b/addons/auth_openid/static/src/xml/auth_openid.xml
index 6a40439a012..75fd2a8fe45 100644
--- a/addons/auth_openid/static/src/xml/auth_openid.xml
+++ b/addons/auth_openid/static/src/xml/auth_openid.xml
@@ -4,44 +4,53 @@
-
+
-
-
+
+
Google Apps Domain
-
+
-
+
Username
-
+
-
+
OpenID URL
-
+
-
+
+ this.each(function() {
+ var $i = $(this);
+ $i.add($i.prev()).attr('data-provider', 'password');
+ });
+
+
this.each(function() {
var $i = $(this),
- dp = $i.find('input').attr('name');
- $i.add($i.prev()).attr('class', 'auth_choice').attr('data-provider', dp);
+ dp = $i.find('input').attr('name'),
+ $p = $i.prev();
+ // $p may not be the correct label when auth_signup is installed.
+ while(($p.attr('data-modes') || 'default') !== 'default') { $p = $p.prev(); }
+ $i.add($p).attr('data-provider', dp);
});
diff --git a/addons/auth_signup/res_users.py b/addons/auth_signup/res_users.py
index 4e86de5b474..b5383e41775 100644
--- a/addons/auth_signup/res_users.py
+++ b/addons/auth_signup/res_users.py
@@ -161,14 +161,12 @@ class res_users(osv.Model):
def _get_state(self, cr, uid, ids, name, arg, context=None):
res = {}
for user in self.browse(cr, uid, ids, context):
- res[user.id] = ('reset' if user.signup_valid else
- 'active' if user.login_date else
- 'new')
+ res[user.id] = ('active' if user.login_date else 'new')
return res
_columns = {
'state': fields.function(_get_state, string='Status', type='selection',
- selection=[('new', 'New'), ('active', 'Active'), ('reset', 'Resetting Password')]),
+ selection=[('new', 'Never Connected'), ('active', 'Activated')]),
}
def signup(self, cr, uid, values, token=None, context=None):
@@ -270,16 +268,7 @@ class res_users(osv.Model):
if mail_state and mail_state['state'] == 'exception':
raise self.pool.get('res.config.settings').get_config_warning(cr, _("Cannot send email: no outgoing email server configured.\nYou can configure it under %(menu:base_setup.menu_general_configuration)s."), context)
else:
- return {
- 'type': 'ir.actions.client',
- 'name': '_(Server Notification)',
- 'tag': 'action_notify',
- 'params': {
- 'title': 'Mail Sent to: %s' % user.name,
- 'text': 'You can reset the password by yourself using this link ' % user.partner_id.signup_url,
- 'sticky': True,
- }
- }
+ return True
def create(self, cr, uid, values, context=None):
# overridden to automatically invite user to sign up
diff --git a/addons/auth_signup/res_users_view.xml b/addons/auth_signup/res_users_view.xml
index 11a5315cbb7..28f66eb101d 100644
--- a/addons/auth_signup/res_users_view.xml
+++ b/addons/auth_signup/res_users_view.xml
@@ -17,13 +17,25 @@
+
+
+ A password reset has been requested for this user. An email containing the following link has been sent:
+
+
+ An invitation email containing the following subscription link has been sent:
+
+
+
+
-
-
+
-
+ type="object" name="action_reset_password"
+ attrs="{'invisible': [('state', '!=', 'active')]}"/>
+
diff --git a/addons/auth_signup/static/src/js/auth_signup.js b/addons/auth_signup/static/src/js/auth_signup.js
index fe071fde55d..bbaf907c625 100644
--- a/addons/auth_signup/static/src/js/auth_signup.js
+++ b/addons/auth_signup/static/src/js/auth_signup.js
@@ -56,7 +56,7 @@ openerp.auth_signup = function(instance) {
self.rpc("/auth_signup/get_config", {dbname: dbname}).done(function(result) {
self.signup_enabled = result.signup;
self.reset_password_enabled = result.reset_password;
- if (self.$("form input[name=login]").val()){
+ if (!self.signup_enabled || self.$("form input[name=login]").val()){
self.set('login_mode', 'default');
} else {
self.set('login_mode', 'signup');
diff --git a/addons/auth_signup/static/src/xml/auth_signup.xml b/addons/auth_signup/static/src/xml/auth_signup.xml
index 9ef4f394e27..1c41dbed181 100644
--- a/addons/auth_signup/static/src/xml/auth_signup.xml
+++ b/addons/auth_signup/static/src/xml/auth_signup.xml
@@ -12,6 +12,9 @@
Username
Username (Email)
+
+ this.attr('data-modes', 'default signup reset');
+
Confirm Password
diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml
index 91154b1ee5a..2abd994d644 100644
--- a/addons/crm/crm_lead_view.xml
+++ b/addons/crm/crm_lead_view.xml
@@ -104,9 +104,9 @@
-
+
@@ -151,7 +151,8 @@
-->
-
+
@@ -426,7 +427,7 @@
-
+
@@ -436,7 +437,7 @@
diff --git a/addons/crm_partner_assign/res_partner_view.xml b/addons/crm_partner_assign/res_partner_view.xml
index aeafc367792..433a290ae81 100644
--- a/addons/crm_partner_assign/res_partner_view.xml
+++ b/addons/crm_partner_assign/res_partner_view.xml
@@ -77,6 +77,7 @@
+
@@ -104,17 +105,19 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/hr/hr_view.xml b/addons/hr/hr_view.xml
index 8767da6bd63..e0c3edfdb39 100644
--- a/addons/hr/hr_view.xml
+++ b/addons/hr/hr_view.xml
@@ -49,7 +49,8 @@
-
+
diff --git a/addons/hr_holidays/hr_holidays_view.xml b/addons/hr_holidays/hr_holidays_view.xml
index 113d1267380..5828790c152 100644
--- a/addons/hr_holidays/hr_holidays_view.xml
+++ b/addons/hr_holidays/hr_holidays_view.xml
@@ -374,6 +374,7 @@
hr.holidays.status
+
diff --git a/addons/hr_recruitment/hr_recruitment_view.xml b/addons/hr_recruitment/hr_recruitment_view.xml
index 834b806e372..453703ce66f 100644
--- a/addons/hr_recruitment/hr_recruitment_view.xml
+++ b/addons/hr_recruitment/hr_recruitment_view.xml
@@ -108,7 +108,8 @@
-
+
@@ -353,6 +354,7 @@
hr.recruitment.stage
@@ -411,10 +414,12 @@
hr.recruitment.degree
@@ -448,8 +453,12 @@
hr.recruitment.source.form
hr.recruitment.source
-
diff --git a/addons/hr_timesheet/hr_timesheet_view.xml b/addons/hr_timesheet/hr_timesheet_view.xml
index 6edd2a74eea..a80a0b2f151 100644
--- a/addons/hr_timesheet/hr_timesheet_view.xml
+++ b/addons/hr_timesheet/hr_timesheet_view.xml
@@ -8,7 +8,8 @@
-
+
@@ -29,7 +30,8 @@
-
+
diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py
index d4e71cedbf5..4be032ba99b 100644
--- a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py
+++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py
@@ -213,6 +213,7 @@ class hr_timesheet_sheet(osv.osv):
def onchange_employee_id(self, cr, uid, ids, employee_id, context=None):
department_id = False
+ user_id = False
if employee_id:
empl_id = self.pool.get('hr.employee').browse(cr, uid, employee_id, context=context)
department_id = empl_id.department_id.id
diff --git a/addons/lunch/lunch_view.xml b/addons/lunch/lunch_view.xml
index 2d662a2f785..2f3af2f461d 100644
--- a/addons/lunch/lunch_view.xml
+++ b/addons/lunch/lunch_view.xml
@@ -324,7 +324,8 @@
-
+
@@ -409,7 +410,8 @@
-
diff --git a/addons/mail/tests/test_invite.py b/addons/mail/tests/test_invite.py
index fe4b8ed10df..faa9fd55793 100644
--- a/addons/mail/tests/test_invite.py
+++ b/addons/mail/tests/test_invite.py
@@ -31,18 +31,18 @@ class test_invite(TestMailBase):
# Do: create a mail_wizard_invite, validate it
self._init_mock_build_email()
context = {'default_res_model': 'mail.group', 'default_res_id': self.group_pigs_id}
- mail_invite_id = mail_invite.create(cr, self.user_raoul_id, {'partner_ids': [(4, self.partner_bert_id)]}, context)
+ mail_invite_id = mail_invite.create(cr, self.user_raoul_id, {'partner_ids': [(4, self.partner_bert_id)], 'send_mail': True}, context)
mail_invite.add_followers(cr, self.user_raoul_id, [mail_invite_id], {'default_model': 'mail.group', 'default_res_id': 0})
# Test: Pigs followers should contain Admin, Bert
self.group_pigs.refresh()
follower_ids = [follower.id for follower in self.group_pigs.message_follower_ids]
- self.assertEqual(set(follower_ids), set([self.partner_admin_id, self.partner_bert_id]), 'Pigs followers after invite is incorrect')
+ self.assertEqual(set(follower_ids), set([self.partner_admin_id, self.partner_bert_id]), 'invite: Pigs followers after invite is incorrect')
# Test: (pretend to) send email and check subject, body
self.assertEqual(len(self._build_email_kwargs_list), 1, 'sent email number incorrect, should be only for Bert')
for sent_email in self._build_email_kwargs_list:
- self.assertEqual(sent_email.get('subject'), 'Invitation to follow Pigs',
- 'subject of invitation email is incorrect')
- self.assertTrue('You have been invited to follow Pigs' in sent_email.get('body'),
- 'body of invitation email is incorrect')
+ self.assertEqual(sent_email.get('subject'), 'Invitation to follow Discussion group: Pigs',
+ 'invite: subject of invitation email is incorrect')
+ self.assertIn('Raoul Grosbedon invited you to follow Discussion group document: Pigs', sent_email.get('body'),
+ 'invite: body of invitation email is incorrect')
diff --git a/addons/mail/tests/test_mail_features.py b/addons/mail/tests/test_mail_features.py
index b327bd33d98..e4f340fef98 100644
--- a/addons/mail/tests/test_mail_features.py
+++ b/addons/mail/tests/test_mail_features.py
@@ -84,23 +84,6 @@ Sylvie
class test_mail(TestMailBase):
- def _mock_send_get_mail_body(self, *args, **kwargs):
- # def _send_get_mail_body(self, cr, uid, mail, partner=None, context=None)
- body = append_content_to_html(args[2].body_html, kwargs.get('partner').name if kwargs.get('partner') else 'No specific partner', plaintext=False)
- return body
-
- def setUp(self):
- super(test_mail, self).setUp()
-
- # 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
-
- 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):
""" Testing incoming emails processing. """
cr, uid, user_raoul = self.cr, self.uid, self.user_raoul
@@ -341,11 +324,15 @@ class test_mail(TestMailBase):
_subject = 'Pigs'
_mail_subject = 'Re: %s' % (group_pigs.name)
_body1 = 'Pigs rules
'
- _mail_body1 = 'Pigs rules
\n\n'
- _mail_bodyalt1 = 'Pigs rules\nRaoul\n'
+ _mail_body1 = 'Pigs rules
'
+ _mail_signature1 = 'Raoul
'
+ _mail_bodyalt1 = 'Pigs rules\n'
+ _mail_signaturealt1 = '\nRaoul\n'
_body2 = 'Pigs rules'
- _mail_body2 = '\n'
- _mail_bodyalt2 = 'Pigs rules\nRaoul'
+ _mail_body2 = ''
+ _mail_signature2 = 'Raoul
'
+ _mail_bodyalt2 = 'Pigs rules\n'
+ _mail_signaturealt2 = '\nRaoul\n'
_attachments = [('First', 'My first attachment'), ('Second', 'My second attachment')]
# ----------------------------------------
@@ -366,12 +353,14 @@ class test_mail(TestMailBase):
self.assertEqual(len(sent_emails), 2, 'sent_email number of sent emails incorrect')
for sent_email in sent_emails:
self.assertEqual(sent_email['subject'], _subject, 'sent_email subject incorrect')
- self.assertTrue(sent_email['body'] in [_mail_body1 + '\nBert Tartopoils\n', _mail_body1 + '\nAdministrator\n'],
- 'sent_email body incorrect')
+ self.assertIn(_mail_body1, sent_email['body'], 'sent_email body incorrect')
+ self.assertIn(_mail_signature1, sent_email['body'], 'sent_email body incorrect (no signature)')
+ self.assertIn("OpenERP", sent_email['body'], 'sent_email body incorrect (no OpenERP company)')
# the html2plaintext uses etree or beautiful soup, so the result may be slighly different
# depending if you have installed beautiful soup.
- self.assertTrue(sent_email['body_alternative'] in [_mail_bodyalt1 + '\nBert Tartopoils\n', _mail_bodyalt1 + '\nAdministrator\n'],
- 'sent_email body_alternative is incorrect')
+ self.assertIn(_mail_bodyalt1, sent_email['body_alternative'], 'sent_email body_alternative is incorrect')
+ self.assertIn(_mail_signaturealt1, sent_email['body_alternative'], 'sent_email body_alternative is incorrect (no signature)')
+ self.assertIn("OpenERP", sent_email['body_alternative'], 'sent_email body incorrect (no OpenERP company)')
# Test: mail_message: notified_partner_ids = group followers
message_pids = set([partner.id for partner in message1.notified_partner_ids])
test_pids = set([self.partner_admin_id, p_b_id, p_c_id])
@@ -405,7 +394,12 @@ class test_mail(TestMailBase):
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')
+ self.assertIn(_mail_signature2, sent_email['body'], 'sent_email body incorrect (no signature)')
+ self.assertIn("OpenERP", sent_email['body'], 'sent_email body incorrect (no OpenERP company)')
+ # body_alternative
+ self.assertIn(_mail_bodyalt2, sent_email['body_alternative'], 'sent_email body_alternative is incorrect')
+ self.assertIn(_mail_signaturealt2, sent_email['body_alternative'], 'sent_email body_alternative is incorrect (no signature)')
+ self.assertIn("OpenERP", sent_email['body'], 'sent_email body incorrect (no OpenERP company)')
# Test: mail_message: notified_partner_ids = group followers
message_pids = set([partner.id for partner in message2.notified_partner_ids])
test_pids = set([self.partner_admin_id, p_b_id, p_c_id, p_d_id])
diff --git a/addons/mail/wizard/invite.py b/addons/mail/wizard/invite.py
index a7cdc237a60..d3ec9a1ec14 100644
--- a/addons/mail/wizard/invite.py
+++ b/addons/mail/wizard/invite.py
@@ -32,12 +32,19 @@ class invite_wizard(osv.osv_memory):
def default_get(self, cr, uid, fields, context=None):
result = super(invite_wizard, self).default_get(cr, uid, fields, context=context)
- if 'message' in fields and result.get('res_model') and result.get('res_id'):
- document_name = self.pool.get(result.get('res_model')).name_get(cr, uid, [result.get('res_id')], context=context)[0][1]
- message = _('You have been invited to follow %s.
' % document_name)
+ user_name = self.pool.get('res.users').name_get(cr, uid, [uid], context=context)[0][1]
+ model = result.get('res_model')
+ res_id = result.get('res_id')
+ if 'message' in fields and model and res_id:
+ ir_model = self.pool.get('ir.model')
+ model_ids = ir_model.search(cr, uid, [('model', '=', self.pool.get(model)._name)], context=context)
+ model_name = ir_model.name_get(cr, uid, model_ids, context=context)[0][1]
+
+ document_name = self.pool.get(model).name_get(cr, uid, [res_id], context=context)[0][1]
+ message = _('Hello,
%s invited you to follow %s document: %s.
') % (user_name, model_name, document_name)
result['message'] = message
elif 'message' in fields:
- result['message'] = _('You have been invited to follow a new document.
')
+ result['message'] = _('Hello,
%s invited you to follow a new document.
') % user_name
return result
_columns = {
@@ -46,8 +53,12 @@ class invite_wizard(osv.osv_memory):
help='Model of the followed resource'),
'res_id': fields.integer('Related Document ID', select=1,
help='Id of the followed resource'),
- 'partner_ids': fields.many2many('res.partner', string='Partners'),
+ 'partner_ids': fields.many2many('res.partner', string='Recipients',
+ help="List of partners that will be added as follower of the current document."),
'message': fields.html('Message'),
+ 'send_mail': fields.boolean('Send Email',
+ help="If checked, the partners will receive an email warning they have been "
+ "added in the document's followers."),
}
def add_followers(self, cr, uid, ids, context=None):
@@ -59,21 +70,25 @@ class invite_wizard(osv.osv_memory):
new_follower_ids = [p.id for p in wizard.partner_ids if p not in document.message_follower_ids]
model_obj.message_subscribe(cr, uid, [wizard.res_id], new_follower_ids, context=context)
- # send an email
- if wizard.message:
+ ir_model = self.pool.get('ir.model')
+ model_ids = ir_model.search(cr, uid, [('model', '=', model_obj._name)], context=context)
+ model_name = ir_model.name_get(cr, uid, model_ids, context=context)[0][1]
+
+ # send an email if option checked and if a message exists (do not send void emails)
+ if wizard.send_mail and wizard.message:
# add signature
- user_id = self.pool.get("res.users").read(cr, uid, [uid], fields=["signature"], context=context)[0]
- signature = user_id and user_id["signature"] or ''
- if signature:
- wizard.message = tools.append_content_to_html(wizard.message, signature, plaintext=True, container_tag='div')
# FIXME 8.0: use notification_email_send, send a wall message and let mail handle email notification + message box
+ signature_company = self.pool.get('mail.notification').get_signature_footer(cr, uid, user_id=uid, res_model=wizard.res_model, res_id=wizard.res_id, context=context)
+ wizard.message = tools.append_content_to_html(wizard.message, signature_company, plaintext=False, container_tag='div')
+
+ # send mail to new followers
for follower_id in new_follower_ids:
mail_mail = self.pool.get('mail.mail')
# the invite wizard should create a private message not related to any object -> no model, no res_id
mail_id = mail_mail.create(cr, uid, {
'model': wizard.res_model,
'res_id': wizard.res_id,
- 'subject': 'Invitation to follow %s' % document.name_get()[0][1],
+ 'subject': _('Invitation to follow %s: %s') % (model_name, document.name_get()[0][1]),
'body_html': '%s' % wizard.message,
'auto_delete': True,
}, context=context)
diff --git a/addons/mail/wizard/invite_view.xml b/addons/mail/wizard/invite_view.xml
index e957d546d37..2d550da2ecd 100644
--- a/addons/mail/wizard/invite_view.xml
+++ b/addons/mail/wizard/invite_view.xml
@@ -14,7 +14,8 @@
-
+
+