Introduction

Odoo’s Point of Sale (PoS) module is a powerful, customizable application built on the OWL framework. Understanding its module structure is essential for developers who need to tailor the PoS to specific business requirements. This article provides a comprehensive breakdown of the PoS module structure, covering registries, components, methods, and templates, with a focus on inheritance patterns used in Odoo 14 through 16.

PoS Module Structure Overview

The PoS module, named point_of_sale, follows the standard Odoo module layout. However, the core OWL-based logic resides in the static/src folder, specifically within the js, scss, and xml subdirectories. Key files include:

  • Registries: Registries.js, ComponentRegistry.js, ClassRegistry.js
  • Components: Chrome.js, PosComponent.js, legacy_component.js
  • Methods: Model.js, DB.js
  • Templates: Chrome.xml, ProductScreen.xml

Class Registries in Odoo PoS

Similar to the Odoo Web Client, the PoS module employs a registry system to manage class inheritance and extension. The ClassRegistry module provides methods like addByExtending to create new classes by extending existing ones. Below is an example from Odoo 16:

odoo.define('point_of_sale.ClassRegistry', function (require) {
    'use strict';

    const Registry = new ClassRegistry();

    class A {}
    Registry.addByExtending('A', A);

    class B extends A {}
    Registry.addByExtending('B', B);
});

This pattern allows developers to replace or extend core classes without modifying the original source, ensuring upgrade compatibility.

Component Architecture

Components in PoS are built using OWL’s component system. The base component is PosComponent, which extends OWL’s Component. The Chrome component serves as the main application shell, managing the overall UI layout. Legacy components are wrapped via legacy_component.js for backward compatibility.

Example: Extending a Component

odoo.define('my_module.MyComponent', function (require) {
    'use strict';

    const PosComponent = require('point_of_sale.PosComponent');
    const Registries = require('point_of_sale.Registries');

    class MyComponent extends PosComponent {
        // Custom logic
    }

    Registries.Component.add(MyComponent);
});

Methods and Data Models

The Model.js file defines the data models used by PoS, such as Product, Order, and Payment. The DB.js file provides database abstraction for local storage operations. Understanding these methods is crucial for customizing data handling.

Inheriting Models

odoo.define('my_module.MyModel', function (require) {
    'use strict';

    const Model = require('point_of_sale.Model');
    const Registries = require('point_of_sale.Registries');

    class MyModel extends Model {
        // Override methods
    }

    Registries.Model.add(MyModel);
});

Templates and XML

Templates are defined in XML files and are compiled by OWL. The Chrome.xml template defines the main UI structure, while ProductScreen.xml defines the product selection screen. Templates can be inherited using standard Odoo QWeb inheritance or by replacing them via the registry.

Template Inheritance Example

<t t-name="my_module.MyTemplate" t-inherit="point_of_sale.Chrome" t-inherit-mode="extension">
    <xpath expr="//div[hasclass('pos-chrome')]" position="inside">
        <div>Custom Content</div>
    </xpath>
</t>

Conclusion

By mastering the PoS module structure and its inheritance mechanisms, developers can create robust customizations that seamlessly integrate with Odoo’s Point of Sale. The registry system, component architecture, and template inheritance provide a flexible foundation for extending functionality while maintaining upgrade compatibility.