Help

4

How to create a wizard with steps ?

Avatar
Antanas

Say there is such a problem: A user opens a wizard, the wizard checks for a condition, associated with a user, and if condition is "foo", the wizard procedes, if condition is "bar", another action must be taken- another wizard must be opened, and previous one must be closed. How can this be implemented in OpenERP?

Avatar
Discard
4 Answers
15
Avatar
Borni DHIFI
Best Answer

Hi,

you can use field state in the same wizard without create a new.

your_wizard.xml

<record model="ir.ui.view" id="wizard_with_step_form">
    <field name="name">wizard_with_step.form</field>
    <field name="model">wizard_with_step</field>
    <field name="type">form</field>
    <field name="arch" type="xml">
      <form string="Wizard with step" version="7.0">
       <field invisible="1" name="state" />             
          <group states="step1">
          <field name="name1" />                
          </group>
          <group states="step2">
          <field name="name2" />                
          </group>
          <footer states="step1">
            <button name="action_next" string="Next" type="object" />
          </footer>
          <footer states="step2">
            <button name="action_previous" string="Previous" type="object" />
          </footer>
      </form>
    </field>
   </record>

your_wizard.py

class wizard_with_step(osv.osv_memory):
   _name = 'wizard_with_step'
   _description = 'Wizard with step'    
   _columns = { 
              'name1': fields.char('Name 1',),
              'name2': fields.char('Name 2',),
              'state': fields.selection([('step1', 'step1'),('step2', 'step2')])  
              } 
   def action_next(self, cr, uid, ids, context=None):
      #your treatment to click  button next 
      #...
      # update state to  step2
      self.write(cr, uid, ids, {'state': 'step2',}, context=context)
      #return view
      return {
            'type': 'ir.actions.act_window',
            'res_model': 'your_wizard',
            'view_mode': 'form',
            'view_type': 'form',
            'res_id': this.id,
            'views': [(False, 'form')],
            'target': 'new',
             }
   def action_previous(self, cr, uid, ids, context=None):
      #your treatment to click  button previous 
      #...
      # update state to  step1
      self.write(cr, uid, ids, {'state': 'step1',}, context=context)
      #return view
      return {
            'type': 'ir.actions.act_window',
            'res_model': 'your_wizard',
            'view_mode': 'form',
            'view_type': 'form',
            'res_id': this.id,
            'views': [(False, 'form')],
            'target': 'new',
             }
  }
2 Comments
Avatar
Discard
Avatar
Antanas
-

Thank you for this clear explanation.

Avatar
Mind And Go
-

Hy, I read somewhere that states are depreciated for wizard. Is it true?

0
Avatar
Remy
Best Answer

UPDATE For Odoo > 8 (tested on Odoo 11)

I had need for this because of a wizard with a one2many relationship, which can only be attached in step 2 (when the wizard has self.id).

It functions the same way as a normal one2many relationship, with the model being: models.TransientModel

-----

It's actually much simpler now:

In your wizard.xml:

<record model="ir.ui.view" id="wizard_with_step_form">
<field name="name">wizard_with_step.form</field>
<field name="model">wizard_with_step</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Wizard with step" version="7.0">
<field invisible="1" name="state"/>

<group states="step1">
<field name="name1"/>
</group>

<group states="step2">
<field name="name2"/>
</group>

<footer states="step1">
<button name="action_step2" string="Next" type="object"/>
</footer>

<footer states="step2">
<button name="action_step1" string="Previous" type="object"/>
</footer>

</form>
</field>
</record>

And in your model:

state = fields.Selection(
selection=[
('step1', 'Step 1'),
('step2', 'Step 2'),
],
string="Current step",
default="step1",
readonly=True
)
@api.multi
def action_step1(self):
self.state = 'step1'
return {"type": "set_scrollTop"}

@api.multi
def action_step2(self):
self.state = 'step2'
return {"type": "set_scrollTop"}

-----

A sidenote: This return type is better than "no action" because it raises no warnings AND it makes sure that the user is scrolled back to the top.

Avatar
Discard