server-ux/multi_step_wizard/models/multi_step_wizard.py

83 lines
2.4 KiB
Python
Raw Permalink Normal View History

2021-04-28 15:44:37 +00:00
# Copyright 2019 Camptocamp SA
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
import logging
from flectra import api, fields, models
_logger = logging.getLogger(__name__)
class MultiStepWizard(models.AbstractModel):
"""Mixin to ease the creation of multisteps wizards
_selection_state must return all possible step of
the wizard.
For each state but final, there must be a method named
"state_exit_X" where X is the name of the state. Each
of these method must set the next state in self.state.
For each state but start, there may be a method named
"state_previous_X" where X is the name of the state. Each
of these method must set the next state in self.state.
The final state has no related method because the view
should only display a button to close the wizard.
open_next, open_previous and _reopen_self should not need to be
overidden, but _selection_state and state_exit_start
likely will need to.
"""
_name = "multi.step.wizard.mixin"
_description = "Multi Steps Wizard Mixin"
state = fields.Selection(
selection="_selection_state", default="start", required=True
)
allow_back = fields.Boolean(compute="_compute_allow_back")
@api.depends("state")
def _compute_allow_back(self):
for record in self:
record.allow_back = getattr(
record, "state_previous_%s" % record.state, False
)
@api.model
def _selection_state(self):
return [("start", "Start"), ("final", "Final")]
def open_next(self):
state_method = getattr(self, "state_exit_{}".format(self.state), None)
if state_method is None:
raise NotImplementedError(
"No method defined for state {}".format(self.state)
)
state_method()
return self._reopen_self()
def open_previous(self):
state_method = getattr(self, "state_previous_{}".format(self.state), None)
if state_method is None:
raise NotImplementedError(
"No method defined for state {}".format(self.state)
)
state_method()
return self._reopen_self()
def _reopen_self(self):
return {
"type": "ir.actions.act_window",
"res_model": self._name,
"res_id": self.id,
"view_mode": "form",
"target": "new",
}
def state_exit_start(self):
self.state = "final"