mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
[IMP] stock_vertical_lift: filter notifications by screen
If the same user opens multiple shuttles operations on different screens, notifications for a specific shuttle will be displayed on all of them, regardless of the shuttle operation that triggered the notification. This commit allows filtering notifications per screen, so that only screens displaying shuttle operations related to the current notifications will display them. Notifications that are not shuttle-related are not filtered out.
This commit is contained in:
@@ -349,10 +349,20 @@ class VerticalLiftOperationBase(models.AbstractModel):
|
||||
channel = "notify_vertical_lift_screen"
|
||||
bus_message = {
|
||||
"action": "refresh",
|
||||
"params": {"model": self._name, "id": self.id},
|
||||
"params": self._get_user_notification_params(),
|
||||
}
|
||||
self.env["bus.bus"].sendone(channel, bus_message)
|
||||
|
||||
def _get_user_notification_params(self):
|
||||
return {
|
||||
"model": self._name,
|
||||
"id": self.id,
|
||||
"shuttle_info": self._get_user_notification_params_shuttle_info(),
|
||||
}
|
||||
|
||||
def _get_user_notification_params_shuttle_info(self):
|
||||
return self.shuttle_id._get_user_notification_params_shuttle_info()
|
||||
|
||||
|
||||
class VerticalLiftOperationTransfer(models.AbstractModel):
|
||||
"""Base model for shuttle pick and put operations"""
|
||||
@@ -416,7 +426,8 @@ class VerticalLiftOperationTransfer(models.AbstractModel):
|
||||
def on_barcode_scanned(self, barcode):
|
||||
self.ensure_one()
|
||||
self.env.user.notify_info(
|
||||
"Scanned barcode: {}. Not implemented.".format(barcode)
|
||||
"Scanned barcode: {}. Not implemented.".format(barcode),
|
||||
params=self._get_user_notification_params(),
|
||||
)
|
||||
|
||||
@api.depends("current_move_line_id.product_id.packaging_ids")
|
||||
|
||||
@@ -62,7 +62,8 @@ class VerticalLiftOperationPick(models.Model):
|
||||
self.next_step()
|
||||
else:
|
||||
self.env.user.notify_warning(
|
||||
_("No location found for barcode {}").format(barcode)
|
||||
_("No location found for barcode {}").format(barcode),
|
||||
params=self._get_user_notification_params(),
|
||||
)
|
||||
|
||||
def _domain_move_lines_to_do(self):
|
||||
|
||||
@@ -70,7 +70,8 @@ class VerticalLiftOperationPut(models.Model):
|
||||
self.next_step()
|
||||
else:
|
||||
self.env.user.notify_warning(
|
||||
_("No move line found for barcode {}").format(barcode)
|
||||
_("No move line found for barcode {}").format(barcode),
|
||||
params=self._get_user_notification_params(),
|
||||
)
|
||||
|
||||
def _scan_tray_type_action(self, barcode):
|
||||
@@ -85,11 +86,13 @@ class VerticalLiftOperationPut(models.Model):
|
||||
self.env.user.notify_warning(
|
||||
_('No free space for tray type "{}" in this shuttle.').format(
|
||||
tray_type.display_name
|
||||
)
|
||||
),
|
||||
params=self._get_user_notification_params(),
|
||||
)
|
||||
else:
|
||||
self.env.user.notify_warning(
|
||||
_("No tray type found for barcode {}").format(barcode)
|
||||
_("No tray type found for barcode {}").format(barcode),
|
||||
params=self._get_user_notification_params(),
|
||||
)
|
||||
|
||||
def _find_tray_type(self, barcode):
|
||||
|
||||
@@ -86,7 +86,11 @@ class VerticalLiftShuttle(models.Model):
|
||||
|
||||
self.env["vertical.lift.command"].sudo().create(command_values)
|
||||
if self.hardware == "simulation":
|
||||
self.env.user.notify_info(message=payload, title=_("Lift Simulation"))
|
||||
self.env.user.notify_info(
|
||||
message=payload,
|
||||
title=_("Lift Simulation"),
|
||||
params=self._get_user_notification_params(),
|
||||
)
|
||||
return True
|
||||
else:
|
||||
conn = self._hardware_get_server_connection()
|
||||
@@ -259,3 +263,40 @@ class VerticalLiftShuttle(models.Model):
|
||||
"""
|
||||
# XXX do we want to do something special in the notification?
|
||||
self._operation_for_mode()._send_notification_refresh()
|
||||
|
||||
def _get_user_notification_params(self):
|
||||
return {
|
||||
"model": self._name,
|
||||
"id": self.id,
|
||||
"shuttle_info": self._get_user_notification_params_shuttle_info(),
|
||||
}
|
||||
|
||||
def _get_user_notification_params_shuttle_info(self):
|
||||
"""Returns a mapping between shuttle-related models and IDs
|
||||
|
||||
Used by JS to filter notifications to be displayed: this mapping is
|
||||
set on all shuttle-related notifications, and JS takes care of comparing
|
||||
the current web page info (model and ID) with the mapping held by each
|
||||
notification.
|
||||
|
||||
IE: a notification is generated with this mapping:
|
||||
{
|
||||
"vertical.lift.shuttle": 1,
|
||||
"vertical.lift.operation.inventory": 3,
|
||||
"vertical.lift.operation.pick": 2,
|
||||
"vertical.lift.operation.put": 4,
|
||||
}
|
||||
On web page <host>/web#id=2&model=vertical.lift.operation.pick&view_type=form
|
||||
the notification is displayed (form view with matching model and ID).
|
||||
On web page <host>/web#id=1&model=vertical.lift.operation.pick&view_type=form
|
||||
the notification is not displayed (form view with matching model, but wrong ID).
|
||||
"""
|
||||
info = {self._name: self.id}
|
||||
# Property ``_model_for_mode`` holds a mapping between shuttle mode and related
|
||||
# shuttle mode specific models (``vertical.lift.operation.*``); most of the
|
||||
# views on which shuttle notifications are triggered usually display one of
|
||||
# these records, not a ``vertical.lift.shuttle`` one, therefore appending the
|
||||
# shuttle ID to the notification itself may not be enough.
|
||||
for model in self._model_for_mode.values():
|
||||
info[model] = self.env[model].search([("shuttle_id", "=", self.id)]).id
|
||||
return info
|
||||
|
||||
78
stock_vertical_lift/static/src/js/web_client.js
Normal file
78
stock_vertical_lift/static/src/js/web_client.js
Normal file
@@ -0,0 +1,78 @@
|
||||
odoo.define("stock_vertical_lift.WebClient", function (require) {
|
||||
"use strict";
|
||||
|
||||
const WebClient = require("web.WebClient");
|
||||
// Web_notify.WebClient is needed to be loaded beforehand: we can't extend it
|
||||
// directly, but we'll override its method ``bus_notification``
|
||||
require("web_notify.WebClient");
|
||||
|
||||
WebClient.include({
|
||||
/**
|
||||
* Override method to filter out shuttle notifications that are not for the current device
|
||||
*
|
||||
* @override
|
||||
**/
|
||||
bus_notification: function (notifications) {
|
||||
const shuttle_notifications = notifications.filter((n) =>
|
||||
this.is_shuttle_notification(n)
|
||||
);
|
||||
if (shuttle_notifications.length > 0) {
|
||||
const filtered_shuttle_notifications = this.filter_shuttle_notifications(
|
||||
shuttle_notifications
|
||||
);
|
||||
// Notifications will be displayed if:
|
||||
// 1) they're not shuttle-related
|
||||
// 2) they're included in the filtered shuttle notifications
|
||||
// NB: using ``filter`` allows keeping notifications' order
|
||||
notifications = notifications.filter(
|
||||
(n) =>
|
||||
!this.is_shuttle_notification(n) ||
|
||||
filtered_shuttle_notifications.indexOf(n) !== -1
|
||||
);
|
||||
}
|
||||
this._super(notifications);
|
||||
},
|
||||
|
||||
is_shuttle_notification: function (notification) {
|
||||
const values = notification[1];
|
||||
return (
|
||||
!_.isUndefined(values.params) &&
|
||||
!_.isUndefined(values.params.shuttle_info)
|
||||
);
|
||||
},
|
||||
|
||||
filter_shuttle_notifications: function (notifications) {
|
||||
const filtered_notifications = [];
|
||||
const url_hash = new URLSearchParams(window.location.hash.replace("#", ""));
|
||||
const rec_model = url_hash.get("model");
|
||||
const rec_id = parseInt(url_hash.get("id"), 10);
|
||||
const view_type = url_hash.get("view_type");
|
||||
// Check if this is a shuttle-related page displaying a form view with proper record ID
|
||||
if (
|
||||
this._get_shuttle_models().indexOf(rec_model) !== -1 &&
|
||||
view_type === "form" &&
|
||||
!_.isUndefined(rec_id) &&
|
||||
rec_id > 0
|
||||
) {
|
||||
// Display notifications only for the proper shuttle
|
||||
for (let i = 0; i < notifications.length; i++) {
|
||||
const notif = notifications[i];
|
||||
const shuttle_info = notif[1].params.shuttle_info;
|
||||
if (shuttle_info[rec_model] === rec_id) {
|
||||
filtered_notifications.push(notif);
|
||||
}
|
||||
}
|
||||
}
|
||||
return filtered_notifications;
|
||||
},
|
||||
|
||||
_get_shuttle_models: function () {
|
||||
return [
|
||||
"vertical.lift.shuttle",
|
||||
"vertical.lift.operation.inventory",
|
||||
"vertical.lift.operation.pick",
|
||||
"vertical.lift.operation.put",
|
||||
];
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -15,6 +15,10 @@
|
||||
type="text/javascript"
|
||||
src="/stock_vertical_lift/static/src/js/vertical_lift.js"
|
||||
/>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="/stock_vertical_lift/static/src/js/web_client.js"
|
||||
/>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
|
||||
@@ -118,6 +118,7 @@ class VerticalLiftOperationPut(models.Model):
|
||||
self.env.user.notify_warning(
|
||||
_("No free space found for storage type '{}' in shuttle '{}'").format(
|
||||
storage_type.name, self.name
|
||||
)
|
||||
),
|
||||
params=self._get_user_notification_params(),
|
||||
)
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user