From bbeb506db3dd9962064f6cda3f7546cb119e5d5a Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Fri, 8 Nov 2019 12:49:25 +0100 Subject: [PATCH] Add method to refresh a shuttle screen Example of usage in an odoo shell, when a screen is open: >>> self.env['vertical.lift.shuttle'].browse(1)._operation_for_mode().operation_descr = 'foo' >>> self.env['vertical.lift.shuttle'].browse(1)._send_notification_refresh() >>> env.cr.commit() Provided the longpolling is correctly configured with a proxy, the screen should immediately refresh with 'foo' as operation description. --- .../models/vertical_lift_operation_base.py | 22 +++++++++ .../models/vertical_lift_shuttle.py | 14 ++++++ .../static/src/js/vertical_lift.js | 48 +++++++++++++++++++ 3 files changed, 84 insertions(+) diff --git a/stock_vertical_lift/models/vertical_lift_operation_base.py b/stock_vertical_lift/models/vertical_lift_operation_base.py index 5c1d09e75..6108f7418 100644 --- a/stock_vertical_lift/models/vertical_lift_operation_base.py +++ b/stock_vertical_lift/models/vertical_lift_operation_base.py @@ -97,6 +97,28 @@ class VerticalLiftOperationBase(models.AbstractModel): ) return sum(quants.mapped("quantity")) + def _send_notification_refresh(self): + """Send a refresh notification + + Generally, you want to call the method + _send_notification_refresh() on VerticalLiftShuttle so you + don't need to know the id of the current operation. + + Other notifications can be implemented, they have to be + added in static/src/js/vertical_lift.js and the message + must contain an "action" and "params". + """ + self.ensure_one() + channel = "notify_vertical_lift_screen" + bus_message = { + "action": "refresh", + "params": { + "model": self._name, + "id": self.id, + } + } + self.env["bus.bus"].sendone(channel, bus_message) + class VerticalLiftOperationTransfer(models.AbstractModel): """Base model for shuttle pick and put operations""" diff --git a/stock_vertical_lift/models/vertical_lift_shuttle.py b/stock_vertical_lift/models/vertical_lift_shuttle.py index a7e0f35c5..013586eed 100644 --- a/stock_vertical_lift/models/vertical_lift_shuttle.py +++ b/stock_vertical_lift/models/vertical_lift_shuttle.py @@ -214,6 +214,20 @@ class VerticalLiftShuttle(models.Model): self.mode = "inventory" return self.action_open_screen() + def _send_notification_refresh(self): + """Send a refresh notification to the current opened screen + + The form controller on the front-end side will instantaneously + refresh the form with the latest committed data. + + It can be used for instance after a vertical lift hardware + event occurred to inform the user on their screen. + + The method is private only to prevent xml/rpc calls to + interact with the screen. + """ + self._operation_for_mode._send_notification_refresh() + class VerticalLiftShuttleManualBarcode(models.TransientModel): _name = "vertical.lift.shuttle.manual.barcode" diff --git a/stock_vertical_lift/static/src/js/vertical_lift.js b/stock_vertical_lift/static/src/js/vertical_lift.js index 7c0e5d6f4..542a06079 100644 --- a/stock_vertical_lift/static/src/js/vertical_lift.js +++ b/stock_vertical_lift/static/src/js/vertical_lift.js @@ -5,6 +5,7 @@ var core = require('web.core'); var KanbanRecord = require('web.KanbanRecord'); var basicFields = require('web.basic_fields'); var field_registry = require('web.field_registry'); +var FormController = require('web.FormController'); var FieldInteger = basicFields.FieldInteger; KanbanRecord.include({ @@ -44,6 +45,53 @@ var ExitButton = FieldInteger.extend({ clear_breadcrumbs: true, }); }, + +}); + + +FormController.include({ + init: function (parent, model, renderer, params) { + this._super.apply(this, arguments); + if(this.modelName.startsWith('vertical.lift.operation.')) { + this.call('bus_service', 'addChannel', 'notify_vertical_lift_screen'); + this.call( + 'bus_service', 'on', 'notification', + this, this.vlift_bus_notification + ); + this.call('bus_service', 'startPolling'); + } + }, + vlift_bus_notification: function (notifications) { + var self = this; + _.each(notifications, function (notification) { + var channel = notification[0]; + var message = notification[1]; + if(channel === 'notify_vertical_lift_screen') { + switch(message['action']) { + case 'refresh': + self.vlift_bus_action_refresh(message['params']); + break; + } + } + }); + }, + vlift_bus_action_refresh: function(params) { + var selectedIds = this.getSelectedIds(); + if(!selectedIds.length){ + return; + } + var currentId = selectedIds[0]; + if(params['id'] === currentId && params['model'] == this.modelName){ + this.reload(); + } + }, + destroy: function () { + if(this.modelName.startsWith('vertical.lift.operation.')) { + this.call('bus_service', 'deleteChannel', 'notify_vertical_lift_screen'); + } + this._super.apply(this, arguments); + } + }); field_registry.add('vlift_shuttle_exit_button', ExitButton);