Merge PR #1944 into 14.0

Signed-off-by simahawk
This commit is contained in:
OCA-git-bot
2024-03-26 14:16:41 +00:00
7 changed files with 147 additions and 8 deletions

View File

@@ -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")

View File

@@ -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):

View File

@@ -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):

View File

@@ -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

View 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",
];
},
});
});

View File

@@ -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>

View File

@@ -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