From 6ce8a18fbe9c5273b79f3f5f5e079417f9acf404 Mon Sep 17 00:00:00 2001 From: niv-openerp Date: Tue, 18 Oct 2011 17:57:33 +0200 Subject: [PATCH] [fix] context problem in accounting lp bug: https://launchpad.net/bugs/871771 fixed bzr revid: nicolas.vanhoren@openerp.com-20111018155733-45xhk7hg2xsmj26h --- addons/web/controllers/main.py | 110 ++++++++++++++++-------------- addons/web/static/src/js/views.js | 30 ++++---- 2 files changed, 74 insertions(+), 66 deletions(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 4ca998aea14..d8e587e3d4d 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -441,18 +441,24 @@ def load_actions_from_ir_values(req, key, key2, models, meta): return [(id, name, clean_action(req, action)) for id, name, action in actions] -def clean_action(req, action): +def clean_action(req, action, do_not_eval=False): action.setdefault('flags', {}) context = req.session.eval_context(req.context) eval_ctx = req.session.evaluation_context(context) - # values come from the server, we can just eval them - if isinstance(action.get('context'), basestring): - action['context'] = eval( action['context'], eval_ctx ) or {} - - if isinstance(action.get('domain'), basestring): - action['domain'] = eval( action['domain'], eval_ctx ) or [] + if not do_not_eval: + # values come from the server, we can just eval them + if isinstance(action.get('context'), basestring): + action['context'] = eval( action['context'], eval_ctx ) or {} + + if isinstance(action.get('domain'), basestring): + action['domain'] = eval( action['domain'], eval_ctx ) or [] + else: + if 'context' in action: + action['context'] = parse_context(action['context'], req.session) + if 'domain' in action: + action['domain'] = parse_domain(action['domain'], req.session) if 'type' not in action: action['type'] = 'ir.actions.act_window_close' @@ -786,9 +792,9 @@ class View(openerpweb.Controller): for view in field["views"].itervalues(): self.process_view(session, view, None, transform) if field.get('domain'): - field["domain"] = self.parse_domain(field["domain"], session) + field["domain"] = parse_domain(field["domain"], session) if field.get('context'): - field["context"] = self.parse_context(field["context"], session) + field["context"] = parse_context(field["context"], session) def process_toolbar(self, req, toolbar): """ @@ -800,10 +806,10 @@ class View(openerpweb.Controller): for actions in toolbar.itervalues(): for action in actions: if 'context' in action: - action['context'] = self.parse_context( + action['context'] = parse_context( action['context'], req.session) if 'domain' in action: - action['domain'] = self.parse_domain( + action['domain'] = parse_domain( action['domain'], req.session) @openerpweb.jsonrequest @@ -842,39 +848,6 @@ class View(openerpweb.Controller): self.parse_domains_and_contexts(elem, session) return root - def parse_domain(self, domain, session): - """ Parses an arbitrary string containing a domain, transforms it - to either a literal domain or a :class:`web.common.nonliterals.Domain` - - :param domain: the domain to parse, if the domain is not a string it - is assumed to be a literal domain and is returned as-is - :param session: Current OpenERP session - :type session: openerpweb.openerpweb.OpenERPSession - """ - if not isinstance(domain, (str, unicode)): - return domain - try: - return ast.literal_eval(domain) - except ValueError: - # not a literal - return web.common.nonliterals.Domain(session, domain) - - def parse_context(self, context, session): - """ Parses an arbitrary string containing a context, transforms it - to either a literal context or a :class:`web.common.nonliterals.Context` - - :param context: the context to parse, if the context is not a string it - is assumed to be a literal domain and is returned as-is - :param session: Current OpenERP session - :type session: openerpweb.openerpweb.OpenERPSession - """ - if not isinstance(context, (str, unicode)): - return context - try: - return ast.literal_eval(context) - except ValueError: - return web.common.nonliterals.Context(session, context) - def parse_domains_and_contexts(self, elem, session): """ Converts domains and contexts from the view into Python objects, either literals if they can be parsed by literal_eval or a special @@ -889,16 +862,49 @@ class View(openerpweb.Controller): for el in ['domain', 'filter_domain']: domain = elem.get(el, '').strip() if domain: - elem.set(el, self.parse_domain(domain, session)) + elem.set(el, parse_domain(domain, session)) for el in ['context', 'default_get']: context_string = elem.get(el, '').strip() if context_string: - elem.set(el, self.parse_context(context_string, session)) + elem.set(el, parse_context(context_string, session)) @openerpweb.jsonrequest def load(self, req, model, view_id, view_type, toolbar=False): return self.fields_view_get(req, model, view_id, view_type, toolbar=toolbar) +def parse_domain(domain, session): + """ Parses an arbitrary string containing a domain, transforms it + to either a literal domain or a :class:`web.common.nonliterals.Domain` + + :param domain: the domain to parse, if the domain is not a string it + is assumed to be a literal domain and is returned as-is + :param session: Current OpenERP session + :type session: openerpweb.openerpweb.OpenERPSession + """ + if not isinstance(domain, (str, unicode)): + return domain + try: + return ast.literal_eval(domain) + except ValueError: + # not a literal + return web.common.nonliterals.Domain(session, domain) + +def parse_context(context, session): + """ Parses an arbitrary string containing a context, transforms it + to either a literal context or a :class:`web.common.nonliterals.Context` + + :param context: the context to parse, if the context is not a string it + is assumed to be a literal domain and is returned as-is + :param session: Current OpenERP session + :type session: openerpweb.openerpweb.OpenERPSession + """ + if not isinstance(context, (str, unicode)): + return context + try: + return ast.literal_eval(context) + except ValueError: + return web.common.nonliterals.Context(session, context) + class ListView(View): _cp_path = "/web/listview" @@ -944,9 +950,9 @@ class SearchView(View): for field in fields.values(): # shouldn't convert the views too? if field.get('domain'): - field["domain"] = self.parse_domain(field["domain"], req.session) + field["domain"] = parse_domain(field["domain"], req.session) if field.get('context'): - field["context"] = self.parse_domain(field["context"], req.session) + field["context"] = parse_context(field["context"], req.session) return {'fields': fields} @openerpweb.jsonrequest @@ -954,8 +960,8 @@ class SearchView(View): Model = req.session.model("ir.filters") filters = Model.get_filters(model) for filter in filters: - filter["context"] = req.session.eval_context(self.parse_context(filter["context"], req.session)) - filter["domain"] = req.session.eval_domain(self.parse_domain(filter["domain"], req.session)) + filter["context"] = req.session.eval_context(parse_context(filter["context"], req.session)) + filter["domain"] = req.session.eval_domain(parse_domain(filter["domain"], req.session)) return filters @openerpweb.jsonrequest @@ -1071,7 +1077,7 @@ class Action(openerpweb.Controller): _cp_path = "/web/action" @openerpweb.jsonrequest - def load(self, req, action_id): + def load(self, req, action_id, do_not_eval=False): Actions = req.session.model('ir.actions.actions') value = False context = req.session.eval_context(req.context) @@ -1083,7 +1089,7 @@ class Action(openerpweb.Controller): ctx.update(context) action = req.session.model(action_type[0]['type']).read([action_id], False, ctx) if action: - value = clean_action(req, action[0]) + value = clean_action(req, action[0], do_not_eval) return {'result': value} @openerpweb.jsonrequest diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 32e17db641f..9aecbd475af 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -854,23 +854,27 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{ return self.widget_parent.on_action_executed.apply(null, arguments); } }; + var context = new db.web.CompoundContext(dataset.get_context(), action_data.context || {}); + var handler = function (r) { var action = r.result; if (action && action.constructor == Object) { - return self.rpc('/web/session/eval_domain_and_context', { - contexts: [dataset.get_context(), action.context || {}, { - active_id: record_id || false, - active_ids: [record_id || false], + var ncontext = new db.web.CompoundContext(context, action.context || {}); + if (record_id) { + ncontext.add({ + active_id: record_id, + active_ids: [record_id], active_model: dataset.model - }], + }); + } + return self.rpc('/web/session/eval_domain_and_context', { + contexts: [ncontext], domains: [] }).pipe(function (results) { - if (!action_data.context) { - action.context = results.context - } else { - action.context = new db.web.CompoundContext( - results.context, action_data.context); - } + action.context = results.context; + /* niv: previously we were overriding once more with action_data.context, + * I assumed this was not a correct behavior and removed it + */ return self.do_action(action, result_handler); }, null); } else { @@ -878,14 +882,12 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{ } }; - var context = new db.web.CompoundContext(dataset.get_context(), action_data.context || {}); - if (action_data.special) { return handler({result: {"type":"ir.actions.act_window_close"}}); } else if (action_data.type=="object") { return dataset.call_button(action_data.name, [[record_id], context], handler); } else if (action_data.type=="action") { - return this.rpc('/web/action/load', { action_id: parseInt(action_data.name, 10), context: context }, handler); + return this.rpc('/web/action/load', { action_id: parseInt(action_data.name, 10), context: context, do_not_eval: true}, handler); } else { return dataset.exec_workflow(record_id, action_data.name, handler); }