Hello Odoo Community,
I'm working on Odoo 17 and trying to send a real-time notification to the Point of Sale (POS) interface using the bus.bus service.
My goal:
When an admin user presses a button (from backend), a message should be pushed to all open POS sessions so that the cashier sees a notification popup on their screen.
What I tried:
1. POS Frontend Code (Patch):
/** @odoo-module **/
import { patch } from "@web/core/utils/patch";
import { ProductScreen } from "@point_of_sale/app/screens/product_screen/product_screen";
patch(ProductScreen.prototype, {
setup() {
super.setup();
const bus_service = this.env.services.bus_service;
const notification = this.env.services.notification;
const channel = JSON.stringify(["pos.custom.notification", "global"]);
bus_service.addChannel(channel);
onMounted(() => {
bus_service.addEventListener("notification", ({ detail }) => {
for (const { type, payload } of detail) {
if (type === "custom_alert") {
notification.add(payload.message, {
title: payload.title || "POS Notice",
type: "info",
});
}
}
});
});
},
});
2. Python Backend Code:
python
from odoo import models, _
from odoo.exceptions import UserError
class ResUsers(models.Model):
_inherit = 'res.users'
def action_notify_pos_cashier(self):
self.env['bus.bus']._sendone(
(self.env.cr.dbname, 'pos.custom.notification', 'global'),
self.env.uid,
{
'type': 'custom_alert',
'title': '🔔 POS Alert',
'message': '📢 Hello from the backend!'
}
)
What’s happening:
-
I see in the browser console that the POS is subscribed to the correct channel. -
However, when I call the backend method (action_notify_pos_cashier()), nothing is received on the frontend. -
No errors are shown in the frontend, and the channel is active.
My Question:
What is the correct way to structure a real-time notification from the backend to POS using bus.bus in Odoo 17 (OWL2 + POS OWL)?
Am I missing something in how the channel should be defined or how the payload is passed?
Additional info:
-
Odoo version: 17.0 (Community) -
JS code loaded via custom module using patch
Any guidance or working example would be greatly appreciated 🙏