Is there any way to make optional dependencies in Odoo 14 CE?
I know that there is a dependency attribute in the manifest file that we need to specify, and yes, I have been using it to the best of my abilities.
However, I sometimes need to write some code for only when a module is installed, but even if it isn't then the rest of the code should function properly without such module.
For example, My custom module will add a field in sale
and account
, but if this database has purchase
installed then it will also add a field in it too. Pretty simple concept, right, but I can't find a way to do it in a single module.
You can use post_init_hook, which is executed right after the module’s installation, to check if the purchase
(purchase.order
is in registry) module is installed and add the custom field. You can even load an XML file to add the custom field by inheritance using the convert_xml_import function which convert and import XML files.
It is similar to adding the field manually to the corresponding model and view.
When you uninstall the module, the custom field will not be deleted and to do so, you will need to use the uninstall_hook
, you will also need to delete the view manually because of the following user error:
User Error
Cannot rename/delete fields that are still present in views
Fields: purchase.order.x_reference
View: purchase.order.form
First set the post_init_hook
, uninstall_hook
functions inside the __manifest__.py
file:
'post_init_hook': '_module_post_init',
'uninstall_hook': '_module_uninstall_hook',
Then define those functions inside the __init__.py
file:
import os
from odoo import fields, api, SUPERUSER_ID, tools, modules
from odoo.tools.misc import file_open
def _module_uninstall_hook(cr, registry):
if 'purchase.order' in registry:
env = api.Environment(cr, SUPERUSER_ID, {})
env.ref('stackoverflow_14.purchase_order_form').unlink()
env['ir.model.fields'].search([('name', '=', 'x_reference')]).unlink()
def _module_post_init(cr, registry):
if 'purchase.order' in registry:
env = api.Environment(cr, SUPERUSER_ID, {})
mp = env['ir.model'].search([('model', '=', 'purchase.order')], limit=1)
mp.write({'field_id': [(0, 0, {
'name': 'x_reference',
'field_description': "Reference",
'ttype': 'char',
})]})
pathname = os.path.join(modules.get_module_path('stackoverflow_14'), 'views', 'purchase_order.xml')
with file_open(pathname, 'rb') as fp:
tools.convert.convert_xml_import(cr, 'stackoverflow_14', fp)
The purchase_order.xml
file defined inside views
use the view inheritance to add the custom field to the purchase_order_form
form view:
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<data>
<record id="purchase_order_form" model="ir.ui.view">
<field name="name">purchase.order.form</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<field name="partner_ref" position="after">
<field name="x_reference"/>
</field>
</field>
</record>
</data>
</odoo>