diff --git a/addons/pos_self_order/static/src/models/line.js b/addons/pos_self_order/static/src/models/line.js
index a4f27f17eab..f366a00e30b 100644
--- a/addons/pos_self_order/static/src/models/line.js
+++ b/addons/pos_self_order/static/src/models/line.js
@@ -28,7 +28,7 @@ export class Line extends Reactive {
this.customer_note = line.customer_note;
this.price_subtotal_incl = line.price_subtotal_incl || 0;
this.price_subtotal = line.price_subtotal || 0;
- this.selected_attributes = line.selected_attributes || [];
+ this.selected_attributes = line.selected_attributes || {};
}
isChange(lastChange) {
diff --git a/addons/pos_self_order/static/src/models/order.js b/addons/pos_self_order/static/src/models/order.js
index 3c31e9abdb4..5dc3f29409d 100644
--- a/addons/pos_self_order/static/src/models/order.js
+++ b/addons/pos_self_order/static/src/models/order.js
@@ -49,7 +49,7 @@ export class Order extends Reactive {
this.lines = this.lines.map((line) => new Line(line));
}
- computelastChangesSent() {
+ updateLastChanges() {
for (const changeIdx in this.lastChangesSent) {
const changeFound = this.lines.find((line) => line.uuid === changeIdx);
if (!changeFound) {
@@ -60,7 +60,7 @@ export class Order extends Reactive {
this.lastChangesSent = this.lines.reduce((acc, line) => {
acc[line.uuid] = {
qty: line.qty,
- selected_attributes: line.selected_attributes,
+ selected_attributes: { ...line.selected_attributes },
customer_note: line.customer_note,
};
return acc;
diff --git a/addons/pos_self_order/static/src/pages/order_cart/order_cart.js b/addons/pos_self_order/static/src/pages/order_cart/order_cart.js
index 889f67a3cd4..628dae9ad90 100644
--- a/addons/pos_self_order/static/src/pages/order_cart/order_cart.js
+++ b/addons/pos_self_order/static/src/pages/order_cart/order_cart.js
@@ -20,6 +20,7 @@ export class OrderCart extends Component {
this.router = useService("router");
this.state = useState({
selectTable: false,
+ cancelConfirmation: false,
});
onWillStart(() => {
@@ -31,6 +32,10 @@ export class OrderCart extends Component {
return this.selfOrder.self_order_mode === "each" ? "Pay" : "Order";
}
+ get orderToPay() {
+ return this.selfOrder.self_order_mode === "each";
+ }
+
async selectTable(table) {
if (table) {
this.selfOrder.table = table;
@@ -62,4 +67,13 @@ export class OrderCart extends Component {
this.selfOrder.notification.add(_t("Not yet implemented!"), { type: "danger" });
}
}
+
+ cancelToggle() {
+ this.state.cancelConfirmation = !this.state.cancelConfirmation;
+ }
+
+ cancelOrder() {
+ this.selfOrder.cancelOrder();
+ this.cancelToggle();
+ }
}
diff --git a/addons/pos_self_order/static/src/pages/order_cart/order_cart.scss b/addons/pos_self_order/static/src/pages/order_cart/order_cart.scss
new file mode 100644
index 00000000000..e7cb592367a
--- /dev/null
+++ b/addons/pos_self_order/static/src/pages/order_cart/order_cart.scss
@@ -0,0 +1,4 @@
+.o_self-cancel-toggle-btn {
+ height: 55px;
+ width: 55px;
+}
diff --git a/addons/pos_self_order/static/src/pages/order_cart/order_cart.xml b/addons/pos_self_order/static/src/pages/order_cart/order_cart.xml
index 8af8525f6e5..0abbbf5abc1 100644
--- a/addons/pos_self_order/static/src/pages/order_cart/order_cart.xml
+++ b/addons/pos_self_order/static/src/pages/order_cart/order_cart.xml
@@ -3,21 +3,39 @@
-
+
-
-
+
+
+
+
+
+
diff --git a/addons/pos_self_order/static/src/pages/product_main_view/product_main_view.js b/addons/pos_self_order/static/src/pages/product_main_view/product_main_view.js
index bd65604e921..a3bf4b369b3 100644
--- a/addons/pos_self_order/static/src/pages/product_main_view/product_main_view.js
+++ b/addons/pos_self_order/static/src/pages/product_main_view/product_main_view.js
@@ -39,6 +39,15 @@ export class ProductMainView extends Component {
this.initState();
}
+ get disableAttributes() {
+ const order = this.selfOrder.currentOrder;
+ return (
+ this.selfOrder.editedLine &&
+ this.selfOrder.editedLine.uuid &&
+ order.lastChangesSent[this.selfOrder.editedLine.uuid]
+ );
+ }
+
initState() {
const editedLine = this.selfOrder.editedLine;
diff --git a/addons/pos_self_order/static/src/pages/product_main_view/product_main_view.xml b/addons/pos_self_order/static/src/pages/product_main_view/product_main_view.xml
index a7ce0be80b1..1ac966ca626 100644
--- a/addons/pos_self_order/static/src/pages/product_main_view/product_main_view.xml
+++ b/addons/pos_self_order/static/src/pages/product_main_view/product_main_view.xml
@@ -39,6 +39,7 @@
t-att-value="value.name"
t-attf-id="{{ attribute.id }}_{{ value.id }}"
t-model="state.selectedVariants[attribute.name]"
+ t-att-disabled="disableAttributes"
/>
@@ -51,7 +52,7 @@
-
diff --git a/addons/pos_self_order/static/src/self_order_service.js b/addons/pos_self_order/static/src/self_order_service.js
index e73f3ad39c4..d8d1dd52519 100644
--- a/addons/pos_self_order/static/src/self_order_service.js
+++ b/addons/pos_self_order/static/src/self_order_service.js
@@ -113,6 +113,29 @@ export class SelfOrder {
return this.editedOrder;
}
+ cancelOrder() {
+ const changes = this.currentOrder.lastChangesSent;
+ const lines = this.currentOrder.lines;
+ const keptLines = [];
+
+ for (const line of lines) {
+ const change = changes[line.uuid];
+
+ if (change) {
+ line.qty = change.qty;
+ line.customer_note = change.customer_note;
+ line.selected_attributes = change.selected_attributes;
+ keptLines.push(line);
+ }
+ }
+
+ this.currentOrder.lines = keptLines;
+
+ if (this.currentOrder.totalQuantity === 0) {
+ this.router.navigate("default");
+ }
+ }
+
formatMonetary(price) {
return formatMonetary(price, { currencyId: this.currency_id });
}
@@ -131,7 +154,7 @@ export class SelfOrder {
this.editedOrder.access_token = order.access_token;
this.updateOrdersFromServer([order], [order.access_token]);
- this.editedOrder.computelastChangesSent();
+ this.editedOrder.updateLastChanges();
if (this.self_order_mode === "each") {
this.editedOrder = null;
diff --git a/addons/pos_self_order/static/tests/tours/self_order_after_meal_cart_tour.js b/addons/pos_self_order/static/tests/tours/self_order_after_meal_cart_tour.js
index 4c8a67ce9e9..3b18723b0d2 100644
--- a/addons/pos_self_order/static/tests/tours/self_order_after_meal_cart_tour.js
+++ b/addons/pos_self_order/static/tests/tours/self_order_after_meal_cart_tour.js
@@ -11,6 +11,14 @@ registry.category("web_tour.tours").add("self_order_after_meal_cart_tour", {
PosSelf.check.isNotPrimaryBtn("My Orders"),
PosSelf.action.clickPrimaryBtn("View Menu"),
+ // Cancel an orders
+ ...PosSelf.action.addProduct("Office Chair Black", 1),
+ ...PosSelf.action.addProduct("Office Chair Black", 2, "Description"),
+ ...PosSelf.action.addProduct("Large Cabinet", 2),
+ PosSelf.action.clickPrimaryBtn("Review"),
+ ...PosSelf.action.cancelOrder(),
+ PosSelf.action.clickPrimaryBtn("View Menu"),
+
// Add some products
...PosSelf.action.addProduct("Office Chair Black", 1),
...PosSelf.action.addProduct("Office Chair Black", 2, "Description"),
@@ -39,7 +47,7 @@ registry.category("web_tour.tours").add("self_order_after_meal_cart_tour", {
// longer reduce the quantity of his orderlines. We check this behaviour.
PosSelf.action.clickPrimaryBtn("View Menu"),
PosSelf.action.clickPrimaryBtn("Review"),
- ...PosSelf.action.editOrderline("Large Cabinet", "736.00", "", -1),
+ ...PosSelf.action.editSentOrderline("Large Cabinet", "736.00", "", -1),
PosSelf.check.isNotification("You cannot reduce the quantity"),
PosSelf.check.isOrderline("Large Cabinet", "736.00", ""),
@@ -59,9 +67,9 @@ registry.category("web_tour.tours").add("self_order_after_meal_cart_tour", {
...PosSelf.action.addProduct("Office Chair Black", 1, "kidding"),
PosSelf.action.clickPrimaryBtn("Review"),
PosSelf.check.isOrderline("Office Chair Black", "277.16", "kidding"),
- ...PosSelf.action.editOrderline("Office Chair Black", "277.16", "kidding", -1),
+ ...PosSelf.action.editSentOrderline("Office Chair Black", "277.16", "kidding", -1),
PosSelf.check.isOrderline("Office Chair Black", "138.58", "kidding"),
- ...PosSelf.action.editOrderline("Office Chair Black", "138.58", "kidding", -1),
+ ...PosSelf.action.editSentOrderline("Office Chair Black", "138.58", "kidding", -1),
PosSelf.check.isNotification("You cannot reduce the quantity"),
PosSelf.action.clickPrimaryBtn("Order"),
@@ -78,11 +86,8 @@ registry.category("web_tour.tours").add("self_order_after_meal_cart_tour", {
PosSelf.action.clickPrimaryBtn("Review"),
PosSelf.check.isOrderline("Desk Organizer", "5.87", "kidding", "M, Leather"),
PosSelf.check.isOrderline("Desk Organizer", "11.74", "okkk", "L, Custom"),
- PosSelf.action.clickPrimaryBtn("Order"),
// Check if we can edit the product attributes, and if the changes are made to the orderline
- PosSelf.action.clickPrimaryBtn("View Menu"),
- PosSelf.action.clickPrimaryBtn("Review"),
...PosSelf.action.editOrderline("Desk Organizer", "5.87", "kidding", 0, "dav", {
radio: { name: "Size", value: "S" },
select: { name: "Fabric", value: "Custom" },
diff --git a/addons/pos_self_order/static/tests/tours/tour_utils.js b/addons/pos_self_order/static/tests/tours/tour_utils.js
index 99c0728e98f..81a8dabf5d9 100644
--- a/addons/pos_self_order/static/tests/tours/tour_utils.js
+++ b/addons/pos_self_order/static/tests/tours/tour_utils.js
@@ -87,6 +87,18 @@ export const PosSelf = {
},
},
action: {
+ cancelOrder: () => {
+ return [
+ {
+ content: `Toggle 'Cancel' button`,
+ trigger: `.o_self-cancel-toggle-btn`,
+ },
+ {
+ content: `Click on 'Cancel' button`,
+ trigger: `.o_self-cancel-btn`,
+ },
+ ];
+ },
clickBack: () => {
return {
content: "Click the navbar back button",
@@ -121,6 +133,19 @@ export const PosSelf = {
},
];
},
+ editSentOrderline: (name, price, description, addQuantity = 0) => {
+ return [
+ {
+ content: `Click on orderline ${name}, price ${price} and description ${description}`,
+ trigger: `.o_self_order_item_card:has(.o_self_product_name:contains("${name}")):has(span:contains("${description}")):has(span.card-text:contains("${price}"))`,
+ },
+ ...quantityHelper(addQuantity),
+ {
+ content: `Click on 'Add' button`,
+ trigger: `.o_self_order_main_button`,
+ },
+ ];
+ },
editOrderline: (name, price, description, addQuantity = 0, newDescription, newAtr) => {
return [
{