1

Is there any way to can 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 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.

Kenly
  • 24,317
  • 7
  • 44
  • 60
holydragon
  • 6,158
  • 6
  • 39
  • 62
  • 1
    Interesting question! Sometimes we use the concept of something like a base module (base functionalities and if possible as less dependencies to other modules as possible) and integrating modules for odoo apps like sale, account and so on. On those integrating modules you can set the right dependencies and `auto_install` to `True` which will Odoo tell, to install the module if every dependency is already installed. – CZoellner Oct 12 '21 at 09:19
  • @CZoellner so that must be a different module for that matter. I would love to have just a single module. – holydragon Oct 12 '21 at 09:38
  • Yes, that's why i didn't write my idea as answer but as comment ;-) – CZoellner Oct 12 '21 at 10:57
  • 1
    @holydragon You can do it using hooks and custom fields. – Kenly Oct 14 '21 at 13:59
  • @Kenly Can you elaborate? I have never used hooks before, or maybe I have used it but I don't know but hooks are. – holydragon Oct 15 '21 at 01:49

1 Answers1

2

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>
Kenly
  • 24,317
  • 7
  • 44
  • 60