Example Implementation Workflow

Before starting the implementation of the custom registry add-ons, we need to ensure the design and implementation of custom registry views within the registry database based on some set standards. These views will serve as the communication interface with PBMS - enabling rule configuration, reference lookups during calculations, and other integrations. This design will ensure that both PBMS and Background Task modules have standardized and consistent access to the necessary registry attributes, forming a unified knowledge base for PBMS functions across the registry.

Once the registry views are defined in the registry database, we can use that design as models within the g2p_registry_addons module.

Hereafter, we'll go over the implementation of farmer and student registries in odoo-extensions.

Defining Registry Models (/models)

For each of the registry models, create a python file in the /models folder of g2p_registry_addon module. These models will inherit from g2p.registry present in /models/registry.py

# g2p_registry_addon/models/farmer_registry.py
class G2PFarmerRegistry(models.Model):
    _name = "g2p.farmer.registry"
    _description = "Farmer Registry"
    _inherit = "g2p.registry"
    
    ## ... add fields as designed in the registry views ...

Once all the models are created, update the g2p_registry_type_addon/models with the newly created models. It is recommended to update the security file/security/ir.model.access.csv with your new models.

# g2p_registry_type_addon/models/registry.py
class G2PTargetModelMapping:
    """Static mapping from registry type key to model name."""

    MODEL_MAPPING = {
        "student": "g2p.student.registry",
        "farmer": "g2p.farmer.registry",
    }

    @classmethod
    def get_target_model_name(cls, key):
        """Get the model name for a given key."""
        return cls.MODEL_MAPPING.get(key)

class G2PRegistryType(Enum):
    FARMER = "farmer"
    STUDENT = "student"
    OTHER = "other"

    @classmethod
    def selection(cls):
        """Return a list of tuples for Odoo selection fields."""
        return [(member.value, member.name.replace("_", " ").title()) for member in cls]
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
g2p_student_registry_read,Read Student Registry,model_g2p_student_registry,g2p_pbms.group_beneficiary_list_viewer,1,0,0,0
g2p_student_registry_write,Write Student Registry,model_g2p_student_registry,g2p_pbms.group_beneficiary_list_editor,1,1,1,1

g2p_farmer_registry_read,Read Farmer Registry,model_g2p_farmer_registry,g2p_pbms.group_beneficiary_list_viewer,1,0,0,0
g2p_farmer_registry_write,Write Farmer Registry,model_g2p_farmer_registry,g2p_pbms.group_beneficiary_list_editor,1,1,1,1

Defining Views (/views)

Now, we can go ahead and define custom views by inheriting views from g2p_pbms. Ideally we use this section for adding registry specific view in PBMS Odoo UI, but in your custom implementation you can add new views inherit views outside of those shown here all within the scope if what's allowed in odoo.

Although these views should be present for an ideal installation as an add-on to PBMS Core Odoo:

/registry and /menu.xml

In these views we define the menu ribbon view (including both tree and form) for the new registries defined.

  • Create a window action (ir.actions.act_window) referencing your model.

    <!--- /registry/farmer_registry_view.xml --->
    <record id="action_g2p_farmer_registry" model="ir.actions.act_window">
        <field name="name">Farmer Registry</field>
        <field name="res_model">g2p.farmer.registry</field>
        <field name="view_mode">tree,form</field>
    </record>
  • Define the tree and form view for your model, listing the fields you want users to see for each record. Recommended to use create="0" tag prop since the data in these models do not reflect actual registry data.

    <record id="view_g2p_farmer_registry_form" model="ir.ui.view">
        <field name="name">g2p.farmer.registry.form</field>
        <field name="model">g2p.farmer.registry</field>
        <field name="arch" type="xml">
            <form string="G2P Farmer Registry" create="0">
                <sheet>
                    <group>
                        <field name="field_1"/>
                        ...
                        <field name="field_n"/>
                    </group>
                </sheet>
            </form>
        </field>
    </record>
    <record id="view_g2p_farmer_registry_tree" model="ir.ui.view">
        <field name="name">g2p.farmer.registry.tree</field>
        <field name="model">g2p.farmer.registry</field>
        <field name="arch" type="xml">
            <tree string="G2P Farmer Registry" create="0">
                <field name="field_1"/>
                ...
                <field name="field_n"/>
            </tree>
        </field>
    </record>
    
  • Ensure you link the action (here action_g2p_farmer_registry) into a menu item with the correct parent so users can access it. This can be done via inheriting the PBMS menu as shown in /menu.xml

    <!--- /menu.xml --->
    <odoo>
        <menuitem id="menu_g2p_farmer_registry"
                  name="Farmer Registry"
                  parent="g2p_pbms.menu_g2p_registry"
                  action="action_g2p_farmer_registry"
                  sequence="1"/>
        <menuitem id="menu_g2p_student_registry"
                  name="Student Registry"
                  parent="g2p_pbms.menu_g2p_registry"
                  action="action_g2p_student_registry"
                  sequence="2"/>
    </odoo>

/eligibility, /entitlement and /priority

These views will add model based UI enhancements which is required for effective use of PBMS operations, mainly rule based view.

Referring the existing inheritance implementation update the model based information within the <xpath> block. You are free to add or remove the domain widget blocks based on the number of models.

<!-- /eligibility/eligibility_rule_view.xml -->
<!-- Inject domain widgets inside the <group> -->
<xpath expr="//form/sheet/group" position="inside">

    <!-- Domain widget for the 'farmer' type -->
    <field name="pbms_domain" widget="domain"
            options="{'model': 'g2p.farmer.registry'}"
            invisible="target_registry != 'farmer'"/>

    <!-- Domain widget for the 'student' type -->
    <field name="pbms_domain" widget="domain"
            options="{'model': 'g2p.student.registry'}"
            invisible="target_registry != 'student'"/>

</xpath>

The views are already set to inherit from the PBMS views and it's recommended to use the same view or follow the same convention while creating new inheritance views into PBMS

<odoo>
    <record id="view_g2p_eligibility_rule_definition_form_inherit" model="ir.ui.view">
        <field name="name">g2p.eligibility.rule.definition.form.inherit</field>
        <field name="model">g2p.eligibility.rule.definition</field>
        <field name="inherit_id" ref="g2p_pbms.view_g2p_eligibility_rule_definition_form"/>
        <field name="arch" type="xml">
        ...
    </record>
</odoo>

/bgtask

This view defines the Search Beneficiaries section in PBMS UI and is paired with a custom-defined widget (in the /static folder) which integrates JavaScript to manage the search functionality.

Update your model info within the <xpath> groups. Use the correct target_registry and model as defined earlier.

<xpath expr="//page[.//field[@name='target_registry']]/group" position="after">
  <!-- Only one beneficiary_search field is shown based on registry type -->
  <group name="beneficiary_search_farmer" invisible="target_registry != 'farmer'">
    <widget name="g2p_beneficiaries_widget" model="g2p.farmer.registry" id="farmer_beneficiary_search_widget"/>
  </group>
  <group name="beneficiary_search_student" invisible="target_registry != 'student'">
    <widget name="g2p_beneficiaries_widget" model="g2p.student.registry" id="student_beneficiary_search_widget"/>
  </group>
</xpath>

Adding Functionality (/static)

Inside the static folder, we have:

  • /src/css to add any custom styles.

  • /src/js to define and use Owl Components, such as the G2PBeneficiariesComponent for custom logic related to the beneficiaries search functionality.

  • /src/xml to define registry specific views, such as the g2p_beneficiaries_info_tpl for custom beneficiary search views.

During custom implementation, based on the models the only necessary changes to be done in the /static folder is updating the table head and data fields in the beneficiaries info template based on the response structure set during registry connector setup.

Custom looking views for Eligibility and Entitlement Summary view screens are not registry specific and are explained in Summary View


Once you’ve pushed your custom add-ons code to GitHub, you can move on to building a tailored Docker image for your setup. Simply follow the existing Docker creation guide for PBMS Odoo, and update the path to point to your extensions package.

This ensures your deployment aligns with PBMS standards while giving you the flexibility to integrate new registries and custom logic cleanly.

Last updated

Was this helpful?