Skip to Content
Menu
This question has been flagged
4 Replies
17642 Views

Lets say Wizard_1 opens new window with List view, at the same time sets some important key/value pairs in a context. Then Wizard_2 starts from this window by click on some row in the list ( action is bound to: tree_but_open). Then Wizard_3 can be started from the window opened by Wizard_2  by the same way and so on. Is there way to preserve the context set by Wizard_1 and use values from that context in Wizard_2 (and so on) ?

In the scenario described above in Wizard_2 I'm getting new default context, instead of context set by Wizard_1, I need  the context that I've set in Wizard_1. How to achieve that?

UPDATE:

(the example code correcponding to above described scenario):

XML:
================

<?xml version="1.0"?>
<openerp>
    <data>

        <record id="view_test_but_open" model="ir.ui.view">
            <field name="name">test.partners.wizard.form</field>
            <field name="model">test.partners.wizard</field>
            <field name="arch" type="xml">
                <form string="Partners Game" version="7.0">
                    <separator colspan="4" string="Do you really want to start new game?"/>
                    <footer>
                        <button string="New Game" name="test_partners_open_window" type="object" class="oe_highlight"/>
                        or
                        <button string="Cancel" class="oe_link" special="cancel"/>
                    </footer>
                </form>
            </field>
        </record>

        <record id="action_test_but_open" model="ir.actions.act_window">
            <field name="name">Partners Game</field>
            <field name="res_model">test.partners.wizard</field>
            <field name="view_type">form</field>
            <field name="view_mode">tree,form</field>
            <field name="view_id" ref="view_test_but_open"/>
            <field name="target">new</field>
        </record>

        <menuitem id="test_but_open_main"
            name="DEVELOPMENT"
            />
        <menuitem id="test_but_open_sub_section"
            name="Games"
            parent="test_but_open_main"
            />
        <menuitem id="test_but_open_sub"
            parent="test_but_open_sub_section"
            name="Partners Game"
            action="action_test_but_open"
            />

        <record id="action_partners_game_tree_1" model="ir.actions.act_window">
            <field name="name">Partners Game</field>
            <field name="res_model">res.partner</field>
            <field name="view_type">tree</field>
            <field name="view_id" ref="base.view_partner_tree"/>
        </record>

        <record id="view_test_next_level" model="ir.ui.view">
            <field name="name">view.test.next.level.form</field>
            <field name="model">test.partners.level.wizard</field>
            <field name="arch" type="xml">
                <form string="Partners Game - Next Level" version="7.0">
                    <separator colspan="4" string="Do you really want to go to next level of game?"/>
                    <footer>
                        <button string="Next Level" name="next_level" type="object" class="oe_highlight"/>
                        or
                        <button string="Cancel" class="oe_link" special="cancel"/>
                    </footer>
                </form>
            </field>
        </record>

        <record id="action_next_level" model="ir.actions.act_window">
            <field name="name">Next Level</field>
            <field name="res_model">test.partners.level.wizard</field>
            <field name="view_type">form</field>
            <field name="view_mode">tree,form</field>
            <field name="view_id" ref="view_test_next_level"/>
            <field name="target">new</field>
        </record>

        <record model="ir.values" id="ir_open_next_level">
            <field name="key">action</field>
            <field name="key2">tree_but_open</field>
            <field name="model">res.partner</field>
            <field name="name">Next Level</field>
            <field name="value" eval="'ir.actions.act_window,%d'%action_next_level"/>
            <field name="object" eval="True"/>
        </record>

    </data>
</openerp>

PYTHON:
================

# -*- coding: utf-8 -*-

from openerp.osv import fields, osv

import random

random.seed()

class test_partners_wizard(osv.osv_memory):
    _name = "test.partners.wizard"
    _description = "Testing tree_but_open for context durability"
    _columns = {
    }
    _defaults = {
    }
    def test_partners_open_window(self, cr, uid, ids, context=None):
        mod_obj = self.pool.get('ir.model.data')
        act_obj = self.pool.get('ir.actions.act_window')
        if context is None:
            context = {}
        result = mod_obj.get_object_reference(cr, uid, 'test_but_open', 'action_partners_game_tree_1')
        id = result and result[1] or False
        result = act_obj.read(cr, uid, [id], context=context)[0]
        important_value = random.randint(1,100)
        print '[step1] IMPORTANT_VALUE: %s' %important_value # print the important_vaule...

        result['context'] = str({'important_value':important_value})
        return result

test_partners_wizard()

class test_partners_level_wizard(osv.osv_memory):
        _name = "test.partners.level.wizard"
        _description = "Move game to next level"
        _columns = {
        }
        _defaults = {
        }
        def next_level(self, cr, uid, ids, context=None):
            if context == None:
                context = {} 
            print '[step2] IMPORTANT_VALUE: %s' %context.get('important_value',False) # it prints: "[step2] IMPORTANT_VALUE: False", i.e. the important_value is lost for the moment. Any suggestions?
            # ....

test_partners_level_wizard()

#
# ....then Wizard3 and stuff like that

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

How to carry forward values in a context from the first wizard  to the second in above code?

Avatar
Discard
Author Best Answer

As I could not find any existing way to solve this problem and I solved this by changing the "load_actions_from_ir_values" function described in a "web" module(web/controllers/main.py). After changes applied to this function it's possible to put list of keys to carry forward in the context itself with the key: "persist_values". With mentioned changes in the "web" module, this problem will be solved in the example code posted in my question as follows:

PYTHON:
================

# -*- coding: utf-8 -*-

from openerp.osv import fields, osv

import random

random.seed()

class test_partners_wizard(osv.osv_memory):
    _name = "test.partners.wizard"
    _description = "Testing tree_but_open for context durability"
    _columns = {
    }
    _defaults = {
    }
    def test_partners_open_window(self, cr, uid, ids, context=None):
        mod_obj = self.pool.get('ir.model.data')
        act_obj = self.pool.get('ir.actions.act_window')
        if context is None:
            context = {}
        result = mod_obj.get_object_reference(cr, uid, 'test_but_open', 'action_partners_game_tree_1')
        id = result and result[1] or False
        result = act_obj.read(cr, uid, [id], context=context)[0]
        important_value = random.randint(1,100)
        print '[step1] IMPORTANT_VALUE: %s' %important_value # print the important_vaule...        xtx = 

        result['context'] = str({'important_value': important_value, 'persist_values': [ 'important_value' ] })
        return result

test_partners_wizard()

class test_partners_level_wizard(osv.osv_memory):
        _name = "test.partners.level.wizard"
        _description = "Move game to next level"
        _columns = {
        }
        _defaults = {
        }
        def next_level(self, cr, uid, ids, context=None):
            if context == None:
                context = {} 
            print '[step2] IMPORTANT_VALUE: %s' %context.get('important_value',False) # Now it prints: "[step2] IMPORTANT_VALUE: <same number as in the previous print (step1)>", i.e. the important_value is preserved, because it was listed in 'persist_values' list. of course it's possible to put more then one key to persist in the list and all these keys will be persisted through multiple tree_but_open actions.
            # ....

test_partners_level_wizard()

#
# ....then Wizard3 and stuff like that

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

 

I've made  pull request in v7.0, if odoo will merge these changes into the main branch, then this possibility will be available to everyone, or you can use directly this changes if you're facing the same issue as described above.

 

 

Avatar
Discard
Best Answer

Yes , you can preserve context across multiple action of wizard.

on first wizard's button set attribute type="object"

Ex. <button name="open_wizard_2" string="Open View" icon="gtk-ok" type="object" class="oe_highlight"/>

now create "open_wizard_2" method and on return pass action of second wizard with context

Ex. def open_wizard_2(self, cr, uid, ids, context=None):

        -------

        if not context:context={}

        context.update({'test':True})

       return {
                'view_type': 'form',
                'view_mode': 'form',
                'res_model': 'process.wizard_2'
                'view_id': False,
                'type': 'ir.actions.act_window',
                'target': 'new',
                'context':context
            }

Now, you can use of context parameter in second wizard.

Avatar
Discard
Author

Thank you for reply... my case is a bit different. I'm opening only first window with button. All next windows are opened by click on row in a list, as I mentioned in my question actions are bound to 'tree_but_open', I'm looking for a way to preserve context in this conditions.

Author

so this solution does not solves my problem.

Best Answer

What about a flow like this

Wizard -> add action, such as when close, to trigger the tree view, pass the context to it -> Other Wizard called from the tree

So, now the tree view has the context. Because what I see is that the problem is the tree view doesn't have the context.

Avatar
Discard
Author

Hi Ben. The flow in my case is the same as you describe, only I've third wizard also (but this does not mater, If it'll be solved for 2 wizard than this'll be same also for third). However You're wrong about context of tree, I'm passing context from first wizard to the tree, and this context is set properly in the tree opened by first wizard. Actually context is lost (i.e. overwritten by default context) when I'm starting second wizard from the tree.

The context should be there, maybe in you have to check __contexts. I forget, there should be more context type.

I think this is more complicated than I thought. Good luck :D

Author

Thanks, at least you understand the issue.

Best Answer

I believe you have a wizard (Wizard 1) and it consists of lines/ child typcially a list view of that...

So for each record in the List view, you have button to open new wizard (wizard 2)..

If am correct in analysing your scenario..

then try this...

In wizard 1:

you will be having say like this in XML

<field name="LINE_IDS" .... context="{'xx': 'yyy'}"/>

In this field, redefine the context, pass all necessary values you want to carry forward... by that way context of wizard 1 will be carried forwarded to wizard 2

Avatar
Discard
Author

Hi deep. as I mention in my question, I'm using tree_but_open for run wizard from list (it's kind of entry in XML, like: <field name="key2">tree_but_open</field> ) so I have NOT any button in each record in the List view. If I'll have buttons inside each row, then it should be workaround for my problem, but I can't add buttons as my requirement is run the wizard by click on the row, (click anywhere in a row and NOT on button inside the row). Also I can't put context value directly in XML as you suggested, this is literal context and 'xx' will always 'yyy' if I'll do this way. However in my case I'm calculating this value in python before putting it in context. So write context value in XML is NOT solution as value "yyy" will be known only when wizard_1 will run.