Diferencia entre revisiones de «Wizards en Odoo»
(Página creada con «== Wizards == Els wizards permeten fer un asistent interactiu per a que l'usuari complete una tasca. Com que no ha d'agafar les dades dirèctament en un formulari, si no q…») |
Sin resumen de edición |
||
Línea 1: | Línea 1: | ||
Els wizards permeten fer un asistent interactiu per a que l'usuari complete una tasca. Com que no ha d'agafar les dades dirèctament en un formulari, si no que va ajundant-lo a completar-lo, no pot ser guardat en la base de dades fins al final. | Els wizards permeten fer un asistent interactiu per a que l'usuari complete una tasca. Com que no ha d'agafar les dades dirèctament en un formulari, si no que va ajundant-lo a completar-lo, no pot ser guardat en la base de dades fins al final. | ||
Línea 6: | Línea 4: | ||
* Les dades no són persistents, encara que es guarden temporalment en la base de dades. | * Les dades no són persistents, encara que es guarden temporalment en la base de dades. | ||
* A partir de odoo 14 necessiten permisos | * A partir de odoo 14 necessiten permisos | ||
* Els records dels wizards poden tindre referències | * Els records dels wizards poden tindre referències Many2one amb el records dels models normals, però no al contrari. | ||
== Wizard bàsic == | |||
A continuació anem a veure un exemple de wizard que sols mostra un formulari i crea una instºancia d'un model a partir de les dades del formulari: | |||
<syntaxhighlight lang="python" style="font-family:monospace"> | <syntaxhighlight lang="python" style="font-family:monospace"> | ||
Línea 79: | Línea 81: | ||
Si volem, podem ficar un botó que cride al action del wizard. Observem la sintaxi del name, que és igual sempre que el button siga de tipus action, ja que és l'anomenat '''XML id'''. | Si volem, podem ficar un botó que cride al action del wizard. Observem la sintaxi del name, que és igual sempre que el button siga de tipus action, ja que és l'anomenat '''XML id'''. | ||
En aquest exemple anem a fer | == Wizard amb assistent == | ||
En aquest exemple anem a fer un wizard amb assistent. Per començar, cal crear un camp '''state''' amb varis valors possibles: | |||
<syntaxhighlight lang="python" style="font-family:monospace"> | <syntaxhighlight lang="python" style="font-family:monospace"> | ||
state = fields.Selection([ | state = fields.Selection([ | ||
Línea 157: | Línea 160: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Exemple Complet de Wizards == | |||
<div class="toccolours mw-collapsible mw-collapsed" style="overflow: hidden;"> | <div class="toccolours mw-collapsible mw-collapsed" style="overflow: hidden;"> | ||
El codi complet de l'exemple està a: [https://github.com/xxjcaxx/sge18-19/tree/master/wizards] | El codi complet de l'exemple està a: [https://github.com/xxjcaxx/sge18-19/tree/master/wizards] |
Revisión del 09:38 31 may 2021
Els wizards permeten fer un asistent interactiu per a que l'usuari complete una tasca. Com que no ha d'agafar les dades dirèctament en un formulari, si no que va ajundant-lo a completar-lo, no pot ser guardat en la base de dades fins al final.
Els wizards en Odoo són models que estenen la classe TransientModel en compte de Model. Aquesta classe és molt pareguda, però:
- Les dades no són persistents, encara que es guarden temporalment en la base de dades.
- A partir de odoo 14 necessiten permisos
- Els records dels wizards poden tindre referències Many2one amb el records dels models normals, però no al contrari.
Wizard bàsic
A continuació anem a veure un exemple de wizard que sols mostra un formulari i crea una instºancia d'un model a partir de les dades del formulari:
class wizard(models.TransientModel):
_name = 'mmog.wizard'
def _default_attacker(self):
return self.env['mmog.fortress'].browse(self._context.get('active_id')) # El context conté, entre altre coses,
#el active_id del model que està obert.
fortress_attacker = fields.Many2one('mmog.fortress',default=_default_attacker)
fortress_target = fields.Many2one('mmog.fortress')
soldiers_sent = fields.Integer(default=1)
@api.multi
def launch(self):
if self.fortress_attacker.soldiers >= self.soldiers_sent:
self.env['mmog.attack'].create({'fortress_attacking':self.fortress_attacker.id,
'fortress_defender':self.fortress_target.id,
'data':fields.datetime.now(),'soldiers_sent':self.soldiers_sent})
return {}
En el python cal observar la classe de la que hereta, el default, que extrau el active_id del form que a llançat el wizard i el mètode que és cridat pel botó de la vista.
<record model="ir.ui.view" id="wizard_mmog_fortress_view">
<field name="name">wizard.mmog.fortress</field>
<field name="model">mmog.wizard</field>
<field name="arch" type="xml">
<form string="Select fortress">
<group>
<field name="fortress_attacker"/>
<field name="fortress_target"/>
<field name="soldiers_sent"/>
</group>
<footer>
<button name="launch" type="object"
string="Launch" class="oe_highlight"/>
or
<button special="cancel" string="Cancel"/>
</footer>
</form>
</field>
</record>
<act_window id="launch_mmog_fortress_wizard"
name="Launch attack"
binding_model="mmog.fortress"
res_model="mmog.wizard"
view_mode="form"
target="new"
/>
<!-- Forma alternativa recomanada per el manual d'odoo a partir de la versió 14
<record id="launch_mmog_fortress_wizard" model="ir.actions.act_window">
<field name="name">Launch attack</field>
<field name="res_model">mmog.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
<field name="binding_model_id" ref="model_mmog_fortress"/>
</record> -->
En la vista, tenim creat un form normal amb dos botons. Un d'ells és especial per a cancel·lar el wizard. L'altre crida al mètode. També s'ha creat un action indicant el src_model sobre el que treballa i el model del wizard que utilitza. Els action que criden a wizard tenen l'atribut target a new per a que llance una finestra emergent.
<button name="%(launch_mmog_fortress_wizard)d" type="action" string="Launch attack" class="oe_highlight" />
Si volem, podem ficar un botó que cride al action del wizard. Observem la sintaxi del name, que és igual sempre que el button siga de tipus action, ja que és l'anomenat XML id.
Wizard amb assistent
En aquest exemple anem a fer un wizard amb assistent. Per començar, cal crear un camp state amb varis valors possibles:
state = fields.Selection([
('pelis', "Movie Selection"),
('dia', "Day Selection"),
], default='pelis')
@api.multi
def action_pelis(self):
self.state = 'pelis'
return {
'type': 'ir.actions.act_window',
'res_model': self._name,
'res_id': self.id,
'view_mode': 'form',
'target': 'new',
}
@api.multi
def action_dia(self):
self.state = 'dia'
return {
'type': 'ir.actions.act_window',
'res_model': self._name,
'res_id': self.id,
'view_mode': 'form',
'target': 'new',
}
I uns botons que van fent que passe d'un estar a un altre:
<header>
<button name="action_pelis" type="object"
string="Reset to movie selection"
states="dia"/>
<button name="action_dia" type="object"
string="Select dia" states="pelis"
class="oe_highlight"/>
<field name="state" widget="statusbar"/>
</header>
<group states="pelis">
<field name="cine"/>
<field name="pelicules"/>
</group>
<group states="dia">
<field name="dia"/>
</group>
Després es pot fer que el formulari tinga un aspecte diferent depèn del valor de state
Els wizards poden tornar a recarregar la vista des de la que són cridats:
return {
'name': 'Reserves',
'view_type': 'form',
'view_mode': 'form', # Pot ser form, tree, kanban...
'res_model': 'wizards.reserves', # El model de destí
'res_id': reserva.id, # El id concret per obrir el form
# 'view_id': self.ref('wizards.reserves_form') # Opcional si hi ha més d'una vista posible.
'context': self._context, # El context es pot ampliar per afegir opcions
'type': 'ir.actions.act_window',
'target': 'current', # Si ho fem en current, canvia la finestra actual.
}
L'exemple anterior és la manera llarga i completa de cridar a una vista en concret, però si sols necessitem refrescar la vista cridada, podem afegir:
return {
'type': 'ir.actions.client',
'tag': 'reload',
}