Point of Sale is one of the best and most significant modules in Odoo ERP. An online application in every case should be appealing and simple to deal with. As we probably are aware Odoo is an easy-to-understand ERP with an appealing UI. Additionally, JavaScript has a vital job in guaranteeing an easy-to-use interface for this ERP. Moreover, Odoo utilizes Backbone JS to deal with the front end on the last form like Odoo 13. We realize that the most recent variant Odoo 14 presented another web library called
Odoo Web Library(OWL) - a UI current system by taking the thoughts of React and Vue.
In this blog, we are going to see how to super or override existing functions using owl in Odoo 14. As we all know, the Overriding feature in any programming language is very helpful.
So, let's see How to override a function in the owl framework.
In the screenshot attached below, so as to see the orders in the POS order line, you can click the orders button above
In the below screenshot, we can see all the products added to the order line.
From here, if we click the delete button to remove the product from the list, you can see a pop-up as shown below.
Let us now override this function to change the message in the popup received.
Now first we can check the module structure. Below I am adding the module structure screenshot.
So, First, we can start with the js file
function_super.js
odoo.define('owl_function_super.TicketScreen_Popup', function(require) {
'use strict';
const Registries = require('point_of_sale.Registries');
const TicketScreen = require('point_of_sale.TicketScreen');
const { posbus } = require('point_of_sale.utils');
});
In the above code, we added the 3 constants needed to our function overriding and assigned the required values.
const PosTicketScreen = (TicketScreen) =>
class extends TicketScreen {
async deleteOrder(order) {
const screen = order.get_screen_data();
if (['ProductScreen', 'PaymentScreen'].includes(screen.name) && order.get_orderlines().length > 0) {
const { confirmed } = await this.showPopup('ConfirmPopup', {
title: 'Existing orderlines',
body: `${order.name} has total amount of ${this.getTotal(
order
)}, are you sure you want delete this order?`,
});
if (!confirmed) return;
}
if (order) {
order.destroy({ reason: 'abandon' });
}
posbus.trigger('order-deleted');
}
In the above code, we extended the Ticket screen and copied the existing function of ‘deleteOrder’, and pasted it here. Next, we are you to override the function. Here I am going to change the popup message and its data. In the below code I have changed the popup body as I needed.
const PosTicketScreen = (TicketScreen) =>
class extends TicketScreen {
async deleteOrder(order) {
const screen = order.get_screen_data();
if (['ProductScreen', 'PaymentScreen'].includes(screen.name) && order.get_orderlines().length > 0) {
const { confirmed } = await this.showPopup('ConfirmPopup', {
title: 'Existing orderlines',
body: `Are you sure you want to delete the ${order.name}?`
});
if (!confirmed) return;
}
if (order) {
order.destroy({ reason: 'abandon' });
}
posbus.trigger('order-deleted');
}
};
Then next we need to return the Component. The screenshot is added below.
Registries.Component.extend(TicketScreen, PosTicketScreen);
return TicketScreen;
Next, we have to create an XML file for adding paths to the JS document.
Asset.xml
<odoo>
<template id="assets" inherit_id="point_of_sale.assets">
<xpath expr="." position="inside">
<script type="text/javascript" src="/owl_function_super/static/src/js/function_super.js"/>
</xpath>
</template>
</odoo>
Now the overriding process is completed. Next, we can check the effect after overriding. In code, we changed the popup data to what we needed. The resulting screenshot is added below.
In the above code, we only added the Order Number in the popup. Here ‘ ${order.name}’ is used for getting the current order number in the popup. Here we can add more data like this. For example, I added the Employee name to the popup. The code is added below.
const PosTicketScreen = (TicketScreen) =>
class extends TicketScreen {
async deleteOrder(order) {
const screen = order.get_screen_data();
if (['ProductScreen', 'PaymentScreen'].includes(screen.name) && order.get_orderlines().length > 0) {
const { confirmed } = await this.showPopup('ConfirmPopup', {
title: 'Existing orderlines',
body: `${order.employee.name} are you sure you want to delete the order ?`
});
if (!confirmed) return;
}
if (order) {
order.destroy({ reason: 'abandon' });
}
posbus.trigger('order-deleted');
}
};
Next, we can check the result of the updated code. Here we get the employee name using ‘${order.employee.name}’.The resulting screenshot is added below.
First example’s complete sample code :
odoo.define('owl_function_super.TicketScreen_Popup', function(require) {
'use strict';
const Registries = require('point_of_sale.Registries');
const TicketScreen = require('point_of_sale.TicketScreen');
const { posbus } = require('point_of_sale.utils');
const PosTicketScreen = (TicketScreen) =>
class extends TicketScreen {
async deleteOrder(order) {
const screen = order.get_screen_data();
if (['ProductScreen', 'PaymentScreen'].includes(screen.name) && order.get_orderlines().length > 0) {
const { confirmed } = await this.showPopup('ConfirmPopup', {
title: 'Existing orderlines',
body: `Are you sure you want to delete the ${order.name}?`
});
if (!confirmed) return;
}
if (order) {
order.destroy({ reason: 'abandon' });
}
posbus.trigger('order-deleted');
}
};
Registries.Component.extend(TicketScreen, PosTicketScreen);
return TicketScreen;
});