Odoo – previene que el botón cierre el asistente

Tengo un modelo transitorio que sirve de diálogo. En mi vista de formulario tengo un botón como este:

El botón invoca esta función (puedo confirmar que realmente invoca):

 @api.one def check_tax_id(self, context=None): self.state = "partnerDetails" return None; 

Mi problema es que la ventana de diálogo se cierra inmediatamente una vez que hago clic en este botón. ¿Qué estoy haciendo mal?

Solución 0

 @api.multi def check_tax_id(self): self.ensure_one() self.name = "New name" return { "type": "ir.actions.do_nothing", } 

Esta solución fue proporcionada aquí por Tadeusz Karpinski.

Solución 1

Puede devolver un nuevo formulario con el mismo ID de registro.

 @api.multi def check_tax_id(self): self.ensure_one() self.name = "New name" return { 'context': self.env.context, 'view_type': 'form', 'view_mode': 'form', 'res_model': 'model_name', 'res_id': self.id, 'view_id': False, 'type': 'ir.actions.act_window', 'target': 'new', } 

Solucion 2

Puedes crear un widget en jQuery. Esto abrirá el asistente y podrá asignar el comportamiento que desee a los botones manualmente. También puede utilizar la función de llamada para llamar a las funciones de python:

 [...] new instance.web.Dialog(this, { title: _t("Title"), width: '95%', buttons: [ { text: _t("First button"), click: function() { self.first_button(); }}, { text: _t("Second button"), click: function() { self.second_button(); }}, { text: _t("Close"), click: function() { dialog.close(); }}, ], }); [...] 

Solucion 3

Por supuesto, también puede anular el método de creación para evitar la creación del registro en algunos casos

Solucion 4

Una última opción. Crear un flujo de trabajo con un campo de estado. Crea botones de flujo de trabajo para enviar señales para cambiar el estado. Puede mostrar u ocultar el rest de los campos utilizando el atributo attrs y el campo de estado. Pero no sé si eso se adaptaría a tus necesidades.

En mi caso este código funciona.

 @api.multi def test(self): l = logging.getLogger() l.warn("xD") return { "type": "ir.actions.do_nothing", } 

Lo más simple que puedes hacer es:

 @api.multi def null_action(self): return { "type": "set_scrollTop", } 

Como el tipo se usa para llamar a cualquier método en la clase ActionManager (javascript)

Es mejor que “type”: “ir.actions.do_nothing” que genera una excepción (este atributo no existe)

Ayer me topé con este mismo tema. Necesitaba mostrar un botón para hacer algo sin enviar todo el wizaard. Trabajé para evitarlo usando un botón en absoluto. Es bastante simple y eficaz. Que necesitas:

  1. una bandera booleana en tu modelo de mago
  2. un intercambio adjunto a la bandera (que reemplaza la función sumbmit)
  3. Reemplace el botón en la vista con la bandera con invisible="1" y una etiqueta que se estilizará como un botón

Aquí está el código:

 source_it = fields.Boolean(string='Source') [...] def action_source(self): # do stuff @api.onchange('source_it') def onchange_source_it(self): if self.env.context.get('sourcing_now') or not self.source_it: return self.action_source() [...]   

El truco funciona porque cuando una etiqueta tiene for atributo va a actuar como la checkbox, así que si hace clic en la etiqueta, en realidad está cambiando la checkbox.

en odoo 7

 def traszero(self ,cr ,uid ,ids ,context=None): data_obj = self.pool.get('stock.return.picking.line') ret_wizard = self.browse(cr, uid, ids, context=context) if ret_wizard.product_return_moves: line_ids = ret_wizard.product_return_moves.mapped('id') data_obj.write(cr, uid, line_ids, {'quantity': 0}, context=context) return {'name':"Return Shipment", 'res_model':"stock.return.picking", 'src_model':"stock.picking", 'view_mode':"form", 'target':"new", 'key2':"client_action_multi", 'multi':"True", 'res_id':ids[0], 'type': 'ir.actions.act_window', } 

Lo que puede hacer es hacer que el botón abra otro asistente pasando el contexto con todos los valores ingresados ​​en el primer asistente. Esto le permite ejecutar alguna función, es decir. tu boton Y mantén el estado de tu mago. Por lo tanto, el valor predeterminado para los campos en su asistente debe verificar el contexto primero y retroceder a otra cosa.

Aquí hay un ejemplo:

 class MyWizard(models.TransientModel): _name = 'myaddon.mywizard' def _get_default_char(self): return self._context.get('mychar',"") mychar = fields.Char(string="My Char", default=_get_default_char) @api.multi def my_button(self): # Execute Function Here # reload wizard with context return { 'view_type': 'form', 'view_mode': 'form', 'res_model': 'myaddon.mywizard', 'type': 'ir.actions.act_window', 'target': 'new', 'context': '{"mychar":'HELLO WORLD'}', }