Files
tryton/trytond/doc/tutorial/module/wizard.rst
T
Lars Wuerfel 3debac9c7b Update wizard tutorial to use tryton.cfg to register model
Closes #15089
(grafted from b5a764a7c2a909bef03ea9f5e2ed2858d42d147f)

--HG--
branch : 8.0
2026-09-28 18:07:34 +02:00

174 lines
4.8 KiB
ReStructuredText

.. _tutorial-module-wizard:
Create wizard
=============
Sometime you want to add functionalities to a model that do not suite the use
of a button.
For this kind of use case the :ref:`wizard <topics-wizard>` is the preferred
solution.
A wizard is a kind of `state machine`_ where states can be a form view, an
action or transition.
.. _state machine: https://en.wikipedia.org/wiki/Finite-state_machine
Let's create a wizard that converts the opportunities by asking for the end date.
First we define a :class:`~trytond.model.ModelView` class in
:file:`opportunity.py`:
.. code-block:: python
class ConvertStart(ModelView):
__name__ = 'training.opportunity.convert.start'
end_date = fields.Date("End Date", required=True)
And we register it in the :class:`~trytond.pool.Pool` in :file:`tryton.cfg`:
.. code-block:: ini
[tryton]
...
[register]
...
model:
opportunity.ConvertStart
Then the form view record in :file:`opportunity.xml`:
.. code-block:: xml
<tryton>
<data>
...
<record model="ir.ui.view" id="opportunity_convert_start_view_form">
<field name="model">training.opportunity.convert.start</field>
<field name="type">form</field>
<field name="name">opportunity_convert_start_form</field>
</record>
</data>
</tryton>
And the view in :file:`view/opportunity_convert_start_form.xml`:
.. code-block:: xml
<form col="2">
<label string="Convert Opportunities?" id="convert_opportunities" colspan="2" xalign="0"/>
<label name="end_date"/>
<field name="end_date"/>
</form>
Now we can define the :class:`~trytond.wizard.Wizard` with a ``start``
:class:`~trytond.wizard.StateView` for the form and a ``convert``
:class:`~trytond.wizard.StateTransition` in :file:`opportunity.py`:
.. code-block:: python
from trytond.wizard import Wizard, StateView, StateTransition, Button
...
class Opportunity(...):
...
@classmethod
@Workflow.transition('converted')
def convert(cls, opportunities, end_date=None):
pool = Pool()
Date = pool.get('ir.date')
cls.write(opportunities, {
'end_date': end_date or Date.today(),
})
...
class Convert(Wizard):
__name__ = 'training.opportunity.convert'
start = StateView(
'training.opportunity.convert.start',
'opportunity.opportunity_convert_start_view_form', [
Button("Cancel", 'end', 'tryton-cancel'),
Button("Convert", 'convert', 'tryton-ok', default=True),
])
convert = StateTransition()
def transition_convert(self):
self.model.convert(self.records, self.start.end_date)
return 'end'
.. note::
We added an optional ``end_date`` to the convert method.
And we register it in the :class:`~trytond.pool.Pool` as type ``wizard`` in
:file:`tryton.cfg`:
.. code-block:: ini
[tryton]
...
[register]
...
wizard:
opportunity.Convert
Finally we just need to create a `Wizard <model-ir.action.wizard>` and an
`Action Keyword <model-ir.action>` in :file:`opportunity.xml`:
.. code-block:: xml
<tryton>
<data>
...
<record model="ir.action.wizard" id="act_convert_opportunities">
<field name="name">Convert Opportunities</field>
<field name="wiz_name">training.opportunity.convert</field>
<field name="model">training.opportunity</field>
</record>
<record model="ir.action.keyword" id="act_convert_opportunities_keyword">
<field name="keyword">form_action</field>
<field name="model">training.opportunity,-1</field>
<field name="action" ref="act_convert_opportunities"/>
</record>
</data>
</tryton>
The `Wizard <model-ir.action.wizard>` links the :class:`~trytond.wizard.Wizard`
with the :class:`~trytond.model.Model`.
``name``
The string that is shown on the menu.
``wiz_name``
The name of the :class:`~trytond.wizard.Wizard`.
``model``
The name of the :class:`~trytond.model.Model`.
And the `Action Keyword <model-ir.action>` makes the
:class:`~trytond.wizard.Wizard` available as action to any
``training.opportunity``.
``keyword``
The type of `keyword <topics-actions>`.
``model``
The model or record for which the action must be displayed.
Use ``-1`` as id for any record.
``action``
The link to the action.
Update database
---------------
As we have defined new fields and XML records, we need to update the database
with:
.. code-block:: console
$ trytond-admin -d test --all
And restart the server and reconnect with the client to test the wizard:
.. code-block:: console
$ trytond
Let's create a :ref:`a report to print opportunities <tutorial-module-report>`.