diff --git a/addons/account/test/account_fiscalyear_close.yml b/addons/account/test/account_fiscalyear_close.yml
index b80cfd0e6e9..cc683ca8d46 100644
--- a/addons/account/test/account_fiscalyear_close.yml
+++ b/addons/account/test/account_fiscalyear_close.yml
@@ -4,31 +4,27 @@
!record {model: account.fiscalyear, id: account_fiscalyear_fiscalyear0}:
code: !eval "'FY%s'% (datetime.now().year+1)"
company_id: base.main_company
- date_start: !eval "'%s-01-01' %(datetime.now().year+1)"
- date_stop: !eval "'%s-12-31' %(datetime.now().year+1)"
- name: !eval "'Fiscal Year %s' %(datetime.now().year+1)"
+ date_start: !eval "'%s-01-01' %(datetime.now().year-1)"
+ date_stop: !eval "'%s-12-31' %(datetime.now().year-1)"
+ name: !eval "'Fiscal Year %s' %(datetime.now().year-1)"
-
- I create a period for the opening entries for the new fiscalyear
+ I generate periods for the new fiscalyear
-
- !record {model: account.period, id: account_period_jan11}:
- company_id: base.main_company
- date_start: !eval "'%s-01-01'% (datetime.now().year+1)"
- date_stop: !eval "'%s-01-01'% (datetime.now().year+1)"
- fiscalyear_id: account_fiscalyear_fiscalyear0
- name: !eval "'OP %s' %(datetime.now().year+1)"
- special: 1
+ !python {model: account.fiscalyear}: |
+ self.create_period(cr, uid, [ref("account_fiscalyear_fiscalyear0")])
-
- I create a new account invoice a the partner in current fiscalyear
+ I create a new account invoice in the created fiscalyear
-
!record {model: account.invoice, id: account_invoice_current1}:
partner_id: base.res_partner_2
+ date_invoice: !eval "'%s-01-02' %(datetime.now().year-1)"
invoice_line:
- partner_id: base.res_partner_2
quantity: 1.0
price_unit: 15.00
name: Bying stuff
-
- I validate it the invoice
+ I validate the invoice
-
!workflow {model: account.invoice, action: invoice_open, ref: account.account_invoice_current1}
-
@@ -44,13 +40,13 @@
company_id: base.main_company
centralisation: 1
-
- I called the Generate Fiscalyear Opening Entries wizard
+ I call the Generate Fiscalyear Opening Entries wizard
-
!record {model: account.fiscalyear.close, id: account_fiscalyear_close_0}:
- fy2_id: account_fiscalyear_fiscalyear0
- fy_id: account.data_fiscalyear
+ fy2_id: account.data_fiscalyear
+ fy_id: account_fiscalyear_fiscalyear0
journal_id: account.close_journal
- period_id: account_period_jan11
+ period_id: account.period_1
report_name: End of Fiscal Year Entry
-
I clicked on create Button
@@ -63,7 +59,7 @@
I close the previous fiscalyear
-
!record {model: account.fiscalyear.close.state, id: account_fiscalyear_close_state_0}:
- fy_id: data_fiscalyear
+ fy_id: account_fiscalyear_fiscalyear0
-
I clicked on Close States Button to close fiscalyear
-
@@ -74,10 +70,10 @@
-
I check that the fiscalyear state is now "Done"
-
- !assert {model: account.fiscalyear, id: data_fiscalyear, string: Fiscal Year is in Done state}:
+ !assert {model: account.fiscalyear, id: account_fiscalyear_fiscalyear0, string: Fiscal Year is in Done state}:
- state == 'done'
-
I check that the past accounts are taken into account in partner credit
-
- !assert {model: res.partner, id: base.res_partner_2}:
- - credit == 15.0, "Total Receivable does not takes unreconciled previous moves"
+ !assert {model: res.partner, id: base.res_partner_2, string: Total Receivable does not takes unreconciled moves of previous years}:
+ - credit == 15.0
diff --git a/addons/board/controllers.py b/addons/board/controllers.py
index 3bdebe1ef26..93634627352 100644
--- a/addons/board/controllers.py
+++ b/addons/board/controllers.py
@@ -1,24 +1,22 @@
# -*- coding: utf-8 -*-
from xml.etree import ElementTree
-import openerp
from openerp.addons.web.controllers.main import load_actions_from_ir_values
+from openerp.addons.web.http import Controller, route, request
-class Board(openerp.addons.web.http.Controller):
- _cp_path = '/board'
-
- @openerp.addons.web.http.jsonrequest
- def add_to_dashboard(self, req, menu_id, action_id, context_to_save, domain, view_mode, name=''):
+class Board(Controller):
+ @route('/board/add_to_dashboard', type='json', auth='user')
+ def add_to_dashboard(self, menu_id, action_id, context_to_save, domain, view_mode, name=''):
# FIXME move this method to board.board model
- dashboard_action = load_actions_from_ir_values(
- req, 'action', 'tree_but_open', [('ir.ui.menu', menu_id)], False)
+ dashboard_action = load_actions_from_ir_values('action', 'tree_but_open',
+ [('ir.ui.menu', menu_id)], False)
if dashboard_action:
action = dashboard_action[0][2]
if action['res_model'] == 'board.board' and action['views'][0][1] == 'form':
# Maybe should check the content instead of model board.board ?
view_id = action['views'][0][0]
- board = req.session.model(action['res_model']).fields_view_get(view_id, 'form')
+ board = request.session.model(action['res_model']).fields_view_get(view_id, 'form')
if board and 'arch' in board:
xml = ElementTree.fromstring(board['arch'])
column = xml.find('./board/column')
@@ -32,10 +30,10 @@ class Board(openerp.addons.web.http.Controller):
})
column.insert(0, new_action)
arch = ElementTree.tostring(xml, 'utf-8')
- return req.session.model('ir.ui.view.custom').create({
- 'user_id': req.session._uid,
+ return request.session.model('ir.ui.view.custom').create({
+ 'user_id': request.session.uid,
'ref_id': view_id,
'arch': arch
- }, req.context)
+ }, request.context)
return False
diff --git a/addons/hr_holidays/hr_holidays_workflow.xml b/addons/hr_holidays/hr_holidays_workflow.xml
index b563dbf68d4..c539ff6de41 100644
--- a/addons/hr_holidays/hr_holidays_workflow.xml
+++ b/addons/hr_holidays/hr_holidays_workflow.xml
@@ -55,6 +55,7 @@
refuse
+
function
holidays_refuse()
diff --git a/addons/im/static/src/js/im.js b/addons/im/static/src/js/im.js
index 6fbf452f974..f4b74adebf6 100644
--- a/addons/im/static/src/js/im.js
+++ b/addons/im/static/src/js/im.js
@@ -62,16 +62,12 @@
this.user_search_dm = new instance.web.DropMisordered();
},
start: function() {
+ var self = this;
this.$el.css("right", -this.$el.outerWidth());
$(window).scroll(_.bind(this.calc_box, this));
$(window).resize(_.bind(this.calc_box, this));
this.calc_box();
-
this.on("change:current_search", this, this.search_changed);
- this.search_changed();
-
- var self = this;
-
return this.c_manager.start_polling().then(function() {
self.c_manager.on("new_conversation", self, function(conv) {
conv.$el.droppable({
@@ -80,6 +76,7 @@
}
});
});
+ self.search_changed();
});
},
calc_box: function() {
@@ -174,4 +171,4 @@
openerp.webclient.to_kitten();
};
-})();
\ No newline at end of file
+})();
diff --git a/addons/l10n_fr/fr_fiscal_templates.xml b/addons/l10n_fr/fr_fiscal_templates.xml
index b11f8d4f0dd..bf49d15e08c 100644
--- a/addons/l10n_fr/fr_fiscal_templates.xml
+++ b/addons/l10n_fr/fr_fiscal_templates.xml
@@ -2,6 +2,12 @@
+
+
+
+
diff --git a/addons/mail/mail_mail.py b/addons/mail/mail_mail.py
index 91799b0ac63..8e99655dddb 100644
--- a/addons/mail/mail_mail.py
+++ b/addons/mail/mail_mail.py
@@ -157,9 +157,9 @@ class mail_mail(osv.Model):
'action': 'mail.action_mail_redirect',
}
if mail.notification:
- fragment.update({
- 'message_id': mail.mail_message_id.id,
- })
+ fragment['message_id'] = mail.mail_message_id.id
+ elif mail.model and mail.res_id:
+ fragment.update(model=mail.model, res_id=mail.res_id)
url = urljoin(base_url, "?%s#%s" % (urlencode(query), urlencode(fragment)))
return _("""Access your messages and documents in OpenERP""") % url
else:
diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py
index b902f733207..9692b94f159 100644
--- a/addons/mail/mail_thread.py
+++ b/addons/mail/mail_thread.py
@@ -566,29 +566,37 @@ class mail_thread(osv.AbstractModel):
self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context)
act_model, act_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, *self._get_inbox_action_xml_id(cr, uid, context=context))
action = self.pool.get(act_model).read(cr, uid, act_id, [])
+ params = context.get('params')
+ msg_id = model = res_id = None
- # if msg_id specified: try to redirect to the document or fallback on the Inbox
- msg_id = context.get('params', {}).get('message_id')
- if not msg_id:
+ if params:
+ msg_id = params.get('message_id')
+ model = params.get('model')
+ res_id = params.get('res_id')
+ if not msg_id and not (model and res_id):
return action
- msg = self.pool.get('mail.message').browse(cr, uid, msg_id, context=context)
- if msg.model and msg.res_id:
- action.update({
- 'context': {
- 'search_default_model': msg.model,
- 'search_default_res_id': msg.res_id,
- }
- })
- if self.pool.get(msg.model).check_access_rights(cr, uid, 'read', raise_exception=False):
+ if msg_id and not (model and res_id):
+ msg = self.pool.get('mail.message').browse(cr, uid, msg_id, context=context)
+ model, res_id = msg.model, msg.res_id
+
+ # if model + res_id found: try to redirect to the document or fallback on the Inbox
+ if model and res_id:
+ model_obj = self.pool.get(model)
+ if model_obj.check_access_rights(cr, uid, 'read', raise_exception=False):
try:
- model_obj = self.pool.get(msg.model)
- model_obj.check_access_rule(cr, uid, [msg.res_id], 'read', context=context)
+ model_obj.check_access_rule(cr, uid, [res_id], 'read', context=context)
if not hasattr(model_obj, '_get_formview_action'):
- action = self.pool.get('mail.thread')._get_formview_action(cr, uid, msg.res_id, model=msg.model, context=context)
+ action = self.pool.get('mail.thread')._get_formview_action(cr, uid, res_id, model=model, context=context)
else:
- action = model_obj._get_formview_action(cr, uid, msg.res_id, context=context)
+ action = model_obj._get_formview_action(cr, uid, res_id, context=context)
except (osv.except_osv, orm.except_orm):
pass
+ action.update({
+ 'context': {
+ 'search_default_model': model,
+ 'search_default_res_id': res_id,
+ }
+ })
return action
#------------------------------------------------------
diff --git a/addons/mail/tests/test_mail_features.py b/addons/mail/tests/test_mail_features.py
index 0688bf02606..62c76db5a40 100644
--- a/addons/mail/tests/test_mail_features.py
+++ b/addons/mail/tests/test_mail_features.py
@@ -231,6 +231,8 @@ class test_mail(TestMail):
def test_11_notification_url(self):
""" Tests designed to test the URL added in notification emails. """
cr, uid, group_pigs = self.cr, self.uid, self.group_pigs
+ # Test URL formatting
+ base_url = self.registry('ir.config_parameter').get_param(cr, uid, 'web.base.url')
# Partner data
partner_raoul = self.res_partner.browse(cr, uid, self.partner_raoul_id)
@@ -243,19 +245,59 @@ class test_mail(TestMail):
# Test: link for nobody -> None
url = mail_mail._get_partner_access_link(self.mail_mail, cr, uid, mail)
self.assertEqual(url, None,
- 'notification email: mails not send to a specific partner should not have any URL')
+ 'notification email: mails not send to a specific partner should not have any URL')
# Test: link for partner -> None
url = mail_mail._get_partner_access_link(self.mail_mail, cr, uid, mail, partner=partner_bert)
self.assertEqual(url, None,
- 'notification email: mails send to a not-user partner should not have any URL')
+ 'notification email: mails send to a not-user partner should not have any URL')
# Test: link for user -> signin
url = mail_mail._get_partner_access_link(self.mail_mail, cr, uid, mail, partner=partner_raoul)
+ self.assertIn(base_url, url,
+ 'notification email: link should contain web.base.url')
+ self.assertIn('db=%s' % cr.dbname, url,
+ 'notification email: link should contain database name')
self.assertIn('action=mail.action_mail_redirect', url,
- 'notification email: link should contain the redirect action')
+ 'notification email: link should contain the redirect action')
self.assertIn('login=%s' % partner_raoul.user_ids[0].login, url,
- 'notification email: link should contain the user login')
+ 'notification email: link should contain the user login')
+
+ # Test: link for user -> with model and res_id
+ mail_mail_id = self.mail_mail.create(cr, uid, {'model': 'mail.group', 'res_id': group_pigs.id})
+ mail = self.mail_mail.browse(cr, uid, mail_mail_id)
+ url = mail_mail._get_partner_access_link(self.mail_mail, cr, uid, mail, partner=partner_raoul)
+ self.assertIn(base_url, url,
+ 'notification email: link should contain web.base.url')
+ self.assertIn('db=%s' % cr.dbname, url,
+ 'notification email: link should contain database name')
+ self.assertIn('action=mail.action_mail_redirect', url,
+ 'notification email: link should contain the redirect action')
+ self.assertIn('login=%s' % partner_raoul.user_ids[0].login, url,
+ 'notification email: link should contain the user login')
+ self.assertIn('model=mail.group', url,
+ 'notification email: link should contain the model when having not notification email on a record')
+ self.assertIn('res_id=%s' % group_pigs.id, url,
+ 'notification email: link should contain the res_id when having not notification email on a record')
+
+ # Test: link for user -> with model and res_id
+ mail_mail_id = self.mail_mail.create(cr, uid, {'notification': True, 'model': 'mail.group', 'res_id': group_pigs.id})
+ mail = self.mail_mail.browse(cr, uid, mail_mail_id)
+ url = mail_mail._get_partner_access_link(self.mail_mail, cr, uid, mail, partner=partner_raoul)
+ self.assertIn(base_url, url,
+ 'notification email: link should contain web.base.url')
+ self.assertIn('db=%s' % cr.dbname, url,
+ 'notification email: link should contain database name')
+ self.assertIn('action=mail.action_mail_redirect', url,
+ 'notification email: link should contain the redirect action')
+ self.assertIn('login=%s' % partner_raoul.user_ids[0].login, url,
+ 'notification email: link should contain the user login')
+ self.assertIn('message_id=%s' % mail.mail_message_id.id, url,
+ 'notification email: link based on message should contain the mail_message id')
+ self.assertNotIn('model', url,
+ 'notification email: link based on message should not contain model')
+ self.assertNotIn('res_id', url,
+ 'notification email: link based on message should not contain res_id')
@mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm')
def test_12_inbox_redirection(self):
@@ -267,24 +309,54 @@ class test_mail(TestMail):
# No specific parameters -> should redirect to Inbox
action = mail_thread.message_redirect_action(self.mail_thread, cr, self.user_raoul_id, {'params': {}})
- self.assertEqual(action.get('type'), 'ir.actions.client',
- 'URL redirection: action without parameters should redirect to client action Inbox')
- self.assertEqual(action.get('id'), act_id,
- 'URL redirection: action without parameters should redirect to client action Inbox')
+ self.assertEqual(
+ action.get('type'), 'ir.actions.client',
+ 'URL redirection: action without parameters should redirect to client action Inbox'
+ )
+ self.assertEqual(
+ action.get('id'), act_id,
+ 'URL redirection: action without parameters should redirect to client action Inbox'
+ )
- # Bert has read access to Pigs -> should redirect to form view of Pigs
+ # Raoul has read access to Pigs -> should redirect to form view of Pigs
action = mail_thread.message_redirect_action(self.mail_thread, cr, self.user_raoul_id, {'params': {'message_id': msg_id}})
- self.assertEqual(action.get('type'), 'ir.actions.act_window',
- 'URL redirection: action with message_id for read-accredited user should redirect to Pigs')
- self.assertEqual(action.get('res_id'), group_pigs.id,
- 'URL redirection: action with message_id for read-accredited user should redirect to Pigs')
+ self.assertEqual(
+ action.get('type'), 'ir.actions.act_window',
+ 'URL redirection: action with message_id for read-accredited user should redirect to Pigs'
+ )
+ self.assertEqual(
+ action.get('res_id'), group_pigs.id,
+ 'URL redirection: action with message_id for read-accredited user should redirect to Pigs'
+ )
+ action = mail_thread.message_redirect_action(self.mail_thread, cr, self.user_raoul_id, {'params': {'model': 'mail.group', 'res_id': group_pigs.id}})
+ self.assertEqual(
+ action.get('type'), 'ir.actions.act_window',
+ 'URL redirection: action with message_id for read-accredited user should redirect to Pigs'
+ )
+ self.assertEqual(
+ action.get('res_id'), group_pigs.id,
+ 'URL redirection: action with message_id for read-accredited user should redirect to Pigs'
+ )
# Bert has no read access to Pigs -> should redirect to Inbox
action = mail_thread.message_redirect_action(self.mail_thread, cr, self.user_bert_id, {'params': {'message_id': msg_id}})
- self.assertEqual(action.get('type'), 'ir.actions.client',
- 'URL redirection: action without parameters should redirect to client action Inbox')
- self.assertEqual(action.get('id'), act_id,
- 'URL redirection: action without parameters should redirect to client action Inbox')
+ self.assertEqual(
+ action.get('type'), 'ir.actions.client',
+ 'URL redirection: action without parameters should redirect to client action Inbox'
+ )
+ self.assertEqual(
+ action.get('id'), act_id,
+ 'URL redirection: action without parameters should redirect to client action Inbox'
+ )
+ action = mail_thread.message_redirect_action(self.mail_thread, cr, self.user_bert_id, {'params': {'model': 'mail.group', 'res_id': group_pigs.id}})
+ self.assertEqual(
+ action.get('type'), 'ir.actions.client',
+ 'URL redirection: action without parameters should redirect to client action Inbox'
+ )
+ self.assertEqual(
+ action.get('id'), act_id,
+ 'URL redirection: action without parameters should redirect to client action Inbox'
+ )
def test_20_message_post(self):
""" Tests designed for message_post. """
diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py
index 2ce046fe454..032952aa511 100644
--- a/addons/procurement/procurement.py
+++ b/addons/procurement/procurement.py
@@ -139,7 +139,7 @@ class procurement_order(osv.osv):
if not proc.note or '_first_pass_done_' not in proc.note or proc.state not in ('confirmed', 'exception'):
super(procurement_order, self).message_track(cr, uid, [proc.id], tracked_fields, initial_values, context=context)
if proc.state == 'exception':
- cr.execute("""UPDATE procurement_order set note = CONCAT(note, %s) WHERE id = %s""", ('_first_pass_done_',proc.id))
+ cr.execute("""UPDATE procurement_order set note = TRIM(both E'\n' FROM COALESCE(note, '') || %s) WHERE id = %s""", ('\n\n_first_pass_done_',proc.id))
return True