Post on 15-Apr-2017
Cómo hacer un módulo Odoo compatible con todo
Jornadas Odoo 2016
@PedroMBaeza
pedro.baeza@tecnativa.com
● Al instalar un módulo, una cosa deja de funcionar● Al desinstalar un módulo de “prueba”, las cosas no se quedan
como estaban.● Al hacer una actualización completa (--update=all), saltan
errores por todas partes. “Solución”: no actualizar completamente nunca.
● Al actualizar, se pierden cosas que se habían puesto.
www.tecnativa.comCómo hacer un módulo de Odoo compatible con todo
Situaciones comunes
www.tecnativa.comCómo hacer un módulo de Odoo compatible con todo
Problema
En el 99% de los casos, no se ha respetado la herencia
● Utilizar módulos de calidad contrastada (OCA). No todos pueden garantizar 100% esa compatibilidad, pero la mayoría sí. Si no la tiene, los módulos OCA lo indican en el README
● Técnicas de programación
● Evitar pruebas en BDs reales.
● Técnicas de programación para desarrollos propios.
www.tecnativa.comCómo hacer un módulo de Odoo compatible con todo
¿Cómo solucionarlo?
● Utilizar las posibilidades de la nueva API:– Declarar el campo de nuevo (nombre técnico y tipo), pero añadiendo sólo los
atributos que cambian:
field = fields.Type(readonly=True) # Hacer readonly– selection_add para añadir valores a un campo selection:
selection_field = fields.Selection(selection_add=[('new_value', 'New value')])– Campos compute entre comillas, y sólo habrá que redefinir el método (pero
llamando al super):
computed_field = fields.Float(compute=”_compute_computed_field”)
www.tecnativa.comCómo hacer un módulo de Odoo compatible con todo
Compatibilidad en modelos
● Herencia en métodos:– Nunca sobreescribir un método y no llamar al super.– TÉCNICAS:
● Rescatar datos del valor devuelto y reprocesar el/los registros.
www.tecnativa.comCómo hacer un módulo de Odoo compatible con todo
Compatibilidad en modelos (II)
SUPER
def method(self):
record = self.env[‘model’].create({…})
return record.id
SOBREESCRITURA
def method(self):
record_id = super(Class, self).method()
record = self.env[‘model’].browse(record_id)
record.field = “...”
return record_id
● Herencia en métodos:– TÉCNICAS:
● Guardar "instantánea" antes y después de llamar al super.
www.tecnativa.comCómo hacer un módulo de Odoo compatible con todo
Compatibilidad en modelos (II)
SUPER
def method(self):
record1 = self.env[‘model’].create({…})
record2 = self.env[‘model’].create({…})
SOBREESCRITURA
def method(self):
old_records = self.env[‘model’].search([])
super(Class, self).method()
current_records = self.env[‘model’].search([])
new_records = current_records - old_records
# process new_records
● Herencia en métodos:– TÉCNICAS:
● Técnicas creativas.
https://github.com/odoomrp/odoomrp-wip/blob/0b55ab14925322b3e167fef24e7aa9d5b38fddb5/procurement_purchase_no_grouping/models/procurement_order.py#L13
https://github.com/odoomrp/odoomrp-wip/blob/0b55ab14925322b3e167fef24e7aa9d5b38fddb5/procurement_purchase_no_grouping/models/purchase_order.py#L17
www.tecnativa.comCómo hacer un módulo de Odoo compatible con todo
Compatibilidad en modelos (III)
● No hacer position=”replace”
– Si no se vuelve a añadir el campo
● puede haber error porque otro elemento se posicione en base a él.
– Si se vuelve a añadir el campo en otro sitio:
● Se pierden los atributos que se hayan modificado por herencia…
● …y además se pierden los cambios que se puedan hacer en el campo original en actualizaciones.
www.tecnativa.comCómo hacer un módulo de Odoo compatible con todo
Compatibilidad en vistas
● No hacer position=”replace”– ¿qué hacer entonces?
● Si solo se quiere ocultar el campo, hacer position=”attributes”, y luego <attribute name=”invisible”>1</attribute>
● Si se quiere mover de sitio…– No lo hagas.– No, en serio, no lo hagas. Odoo no siempre tiene la mejor disposición según qué sectores,
pero tiene unos criterios razonables. Convencer al cliente es la mejor opción.– Si no hay manera, la manera de hacerlo es: A) crear campo related al campo que quieres
hacer el replace; B) ocultar el campo original; C) Insertar el campo related. Aún así, perderás las posibles propiedades heredadas.
www.tecnativa.comCómo hacer un módulo de Odoo compatible con todo
Compatibilidad en vistas (II)
● De nuevo, no hacer position=”replace” (o bueno, no indiscriminadamente)– Es común que otros módulos añadan datos a un informe estándar. Ejemplo:
https://github.com/OCA/bank-payment/blob/9dc92beb4c2f07dbf189487875f0405385cb762e/account_payment_partner/views/report_invoice.xml#L5
– Si se tiene que cambiar mucho el formato, mejor hacer un replace de la plantilla entera, que andar cambiando múltiples cosas. No se obtendrán los campos de los módulos adicionales, pero por lo menos no dará error. <template id="report_invoice_inherit" inherit_id="account.report_invoice"> <xpath expr="//t[@t-raw]" position="replace"> <t t-raw="translate_doc(…, 'custom.report_invoice_document_custom')"/> </xpath> </template>
www.tecnativa.comCómo hacer un módulo de Odoo compatible con todo
Compatibilidad en informes
● Se puede aplicar lo mismo que para los informes.
● Los elementos que añadamos nosotros deben llevar el atributo id para facilitar la herencia desde nuestros elementos.
● Los que están estándar, si están bien hechos (definidas plantillas por separado y con IDs), nos pueden permitir cierto juego de cambio de sitio jugando con la prioridad de las vistas.
www.tecnativa.comCómo hacer un módulo de Odoo compatible con todo
Compatibilidad en website