From 6fd57c21884d40433dd37472497a65d0b190e748 Mon Sep 17 00:00:00 2001 From: Holger Brunn Date: Mon, 23 Mar 2015 17:27:21 +0100 Subject: [PATCH 1/4] [FIX] allow searching for new style function fields in a search path --- openerp/addons/test_new_api/models.py | 12 ++++++++++++ .../test_new_api/tests/test_new_fields.py | 7 +++++++ openerp/osv/expression.py | 17 +++++++++++------ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/openerp/addons/test_new_api/models.py b/openerp/addons/test_new_api/models.py index 50343b0d1fc..00e2681f324 100644 --- a/openerp/addons/test_new_api/models.py +++ b/openerp/addons/test_new_api/models.py @@ -164,6 +164,9 @@ class Message(models.Model): size = fields.Integer(compute='_compute_size', search='_search_size') double_size = fields.Integer(compute='_compute_double_size') discussion_name = fields.Char(related='discussion.name') + author_partner = fields.Many2one( + 'res.partner', compute='_compute_author_partner', + search='_search_author_partner') @api.one @api.constrains('author', 'discussion') @@ -209,6 +212,15 @@ class Message(models.Model): size = self.size self.double_size = self.double_size + size + @api.one + @api.depends('author', 'author.partner_id') + def _compute_author_partner(self): + self.author_partner = author.partner_id + + @api.model + def _search_author_partner(self, operator, value): + return [('author.partner_id', operator, value)] + class MixedModel(models.Model): _name = 'test_new_api.mixed' diff --git a/openerp/addons/test_new_api/tests/test_new_fields.py b/openerp/addons/test_new_api/tests/test_new_fields.py index c588ab59aca..59d85b211bf 100644 --- a/openerp/addons/test_new_api/tests/test_new_fields.py +++ b/openerp/addons/test_new_api/tests/test_new_fields.py @@ -424,6 +424,13 @@ class TestNewFields(common.TransactionCase): defaults = self.env['test_new_api.mixed'].default_get(['number']) self.assertEqual(defaults, {'number': 3.14}) + def test_50_search_many2one(self): + """ test search through a path of computed fields""" + messages = self.env['test_new_api.message'].search( + [('author_partner.name', '=', 'Demo User')]) + self.assertEqual(messages, self.env.ref('test_new_api.message_0_1')) + + class TestMagicFields(common.TransactionCase): diff --git a/openerp/osv/expression.py b/openerp/osv/expression.py index ef8a40dab90..b71db25eaa3 100644 --- a/openerp/osv/expression.py +++ b/openerp/osv/expression.py @@ -842,12 +842,12 @@ class expression(object): # as after transforming the column, it will go through this loop once again # ---------------------------------------- - elif len(path) > 1 and column._type == 'many2one' and column._auto_join: + elif len(path) > 1 and column and column._type == 'many2one' and column._auto_join: # res_partner.state_id = res_partner__state_id.id leaf.add_join_context(comodel, path[0], 'id', path[0]) push(create_substitution_leaf(leaf, (path[1], operator, right), comodel)) - elif len(path) > 1 and column._type == 'one2many' and column._auto_join: + elif len(path) > 1 and column and column._type == 'one2many' and column._auto_join: # res_partner.id = res_partner__bank_ids.partner_id leaf.add_join_context(comodel, 'id', column._fields_id, path[0]) domain = column._domain(model) if callable(column._domain) else column._domain @@ -858,16 +858,16 @@ class expression(object): push(create_substitution_leaf(leaf, elem, comodel)) push(create_substitution_leaf(leaf, AND_OPERATOR, comodel)) - elif len(path) > 1 and column._auto_join: + elif len(path) > 1 and column and column._auto_join: raise NotImplementedError('_auto_join attribute not supported on many2many column %s' % left) - elif len(path) > 1 and column._type == 'many2one': + elif len(path) > 1 and column and column._type == 'many2one': right_ids = comodel.search(cr, uid, [(path[1], operator, right)], context=context) leaf.leaf = (path[0], 'in', right_ids) push(leaf) # Making search easier when there is a left operand as column.o2m or column.m2m - elif len(path) > 1 and column._type in ['many2many', 'one2many']: + elif len(path) > 1 and column and column._type in ['many2many', 'one2many']: right_ids = comodel.search(cr, uid, [(path[1], operator, right)], context=context) table_ids = model.search(cr, uid, [(path[0], 'in', right_ids)], context=dict(context, active_test=False)) leaf.leaf = ('id', 'in', table_ids) @@ -884,7 +884,12 @@ class expression(object): domain = [] else: # Let the field generate a domain. - recs = model.browse(cr, uid, [], context) + if len(path) > 1: + right = comodel.search( + cr, uid, [(path[1], operator, right)], + context=context) + operator = 'in' + recs = model.browse(cr, uid, [], context=context) domain = field.determine_domain(recs, operator, right) if not domain: From 014a1294b2c84cf5ffdcb3c7f5699fe91274a31d Mon Sep 17 00:00:00 2001 From: Stefan Rijnhart Date: Fri, 13 Nov 2015 12:26:50 +0100 Subject: [PATCH 2/4] [FIX] Context argument may be immutable --- addons/sale/sale.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index bee7e90979b..67f04c45fc3 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -732,7 +732,7 @@ class sale_order(osv.osv): :return: True """ - context = context or {} + context = dict(context or {}) context['lang'] = self.pool['res.users'].browse(cr, uid, uid).lang procurement_obj = self.pool.get('procurement.order') sale_line_obj = self.pool.get('sale.order.line') From 098c084eae01213727ca6cc08a564e1c367cf707 Mon Sep 17 00:00:00 2001 From: "Yuriy A. Apollov" Date: Mon, 23 Mar 2015 18:45:07 +0300 Subject: [PATCH 3/4] [FIX] orm: iteration on `browse_null` object lasts forever --- openerp/osv/orm.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index ed27033ccd4..06ef395afcd 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -289,6 +289,9 @@ class browse_null(object): def __unicode__(self): return u'' + def __iter__(self): + raise NotImplementedError("Iteration is not allowed on browse_null") + # # TODO: execute an object method on browse_record_list From e95b01db3ef0525f8213616fa32b586a1a178599 Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Tue, 26 Jan 2016 15:40:42 +0100 Subject: [PATCH 4/4] [IMP] web_graph: XLS export fail if more than 256 columns When creating a XLS file with more than 256 columns, the library used (xlwt) fail since it is targetted to support MS Excel 97 up to Excel 2003. But Odoo doesn't has no check and in this given instance (an error happening in a controller generating a binary filte) the real error message is lost. This commit check if the to-be exported data has more than 256 columns, and if this is the case display an error message without even trying the export. closes #10630 opw-660474 --- addons/web_graph/static/src/js/graph_widget.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index d936791d6a4..7ee972e095b 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -850,10 +850,15 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ // ---------------------------------------------------------------------- export_xls: function() { var c = openerp.webclient.crashmanager; + var table = this.build_table(true); + if(table.measure_row.length + 1 > 256) { + c.show_message(_t("For Excel compatibility, data cannot be exported if there is more than 256 columns.\n\nTip: try to flip axis, filter further or reduce the number of measures.")) + return; + } openerp.web.blockUI(); this.session.get_file({ url: '/web_graph/export_xls', - data: {data: JSON.stringify(this.build_table(true))}, + data: {data: JSON.stringify(table)}, complete: openerp.web.unblockUI, error: c.rpc_error.bind(c) });