summaryrefslogtreecommitdiff
path: root/addons/pos_restaurant/static
diff options
context:
space:
mode:
authorJoseph Caburnay <jcb@odoo.com>2020-07-09 12:07:14 +0000
committerJoseph Caburnay <jcb@odoo.com>2020-08-05 13:35:08 +0000
commit9ea0aca6ea30fe42e1a7e0a4eaeb79f92a521152 (patch)
treeb3c969ef00f0bbc637d94c124202a96887df450a /addons/pos_restaurant/static
parent71f719a61ea34252abdc9f1b2fb2caf8e62c7917 (diff)
[IMP] point_of_sale,pos_*: top bar improvements and ticket list
The following changes are made in this task: 1. Remove order tabs and replace with ticket list. 2. Top bar color change. 3. Search bar in the product screen is moved in the top bar. 4. List of sub-categories are now in the same line as the category breadcrumbs. closes odoo/odoo#55100 Task-id: 2276678 Signed-off-by: pimodoo <pimodoo@users.noreply.github.com>
Diffstat (limited to 'addons/pos_restaurant/static')
-rw-r--r--addons/pos_restaurant/static/src/js/ChromeWidgets/BackToFloorButton.js22
-rw-r--r--addons/pos_restaurant/static/src/js/ChromeWidgets/OrderSelector.js20
-rw-r--r--addons/pos_restaurant/static/src/js/ChromeWidgets/TicketButton.js33
-rw-r--r--addons/pos_restaurant/static/src/js/Screens/FloorScreen/FloorScreen.js4
-rw-r--r--addons/pos_restaurant/static/src/js/Screens/OrderManagementScreen/OrderManagementScreen.js3
-rw-r--r--addons/pos_restaurant/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js12
-rw-r--r--addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js4
-rw-r--r--addons/pos_restaurant/static/src/js/Screens/TicketScreen.js54
-rw-r--r--addons/pos_restaurant/static/src/js/floors.js22
-rw-r--r--addons/pos_restaurant/static/src/xml/Chrome.xml10
-rw-r--r--addons/pos_restaurant/static/src/xml/ChromeWidgets/BackToFloorButton.xml3
-rw-r--r--addons/pos_restaurant/static/src/xml/ChromeWidgets/OrderSelector.xml20
-rw-r--r--addons/pos_restaurant/static/src/xml/Screens/TicketScreen.xml15
-rw-r--r--addons/pos_restaurant/static/tests/tours/OrderManagementScreen.tour.js7
-rw-r--r--addons/pos_restaurant/static/tests/tours/SplitBillScreen.tour.js4
-rw-r--r--addons/pos_restaurant/static/tests/tours/TicketScreen.tour.js44
-rw-r--r--addons/pos_restaurant/static/tests/tours/helpers/FloorScreenTourMethods.js21
-rw-r--r--addons/pos_restaurant/static/tests/tours/pos_restaurant.js338
18 files changed, 329 insertions, 307 deletions
diff --git a/addons/pos_restaurant/static/src/js/ChromeWidgets/BackToFloorButton.js b/addons/pos_restaurant/static/src/js/ChromeWidgets/BackToFloorButton.js
index dbd21c5fd32..c2b623500c8 100644
--- a/addons/pos_restaurant/static/src/js/ChromeWidgets/BackToFloorButton.js
+++ b/addons/pos_restaurant/static/src/js/ChromeWidgets/BackToFloorButton.js
@@ -1,22 +1,28 @@
-odoo.define('pos_restaurant.BackToFloorButton', function(require) {
+odoo.define('pos_restaurant.BackToFloorButton', function (require) {
'use strict';
const PosComponent = require('point_of_sale.PosComponent');
- const { useListener } = require('web.custom_hooks');
const Registries = require('point_of_sale.Registries');
+ const { posbus } = require('point_of_sale.utils');
class BackToFloorButton extends PosComponent {
- constructor() {
- super(...arguments);
- useListener('click', this._backToFloorScreen);
+ mounted() {
+ posbus.on('table-set', this, this.render);
+ }
+ willUnmount() {
+ posbus.on('table-set', this);
}
get table() {
- return this.props.table;
+ return (this.env.pos && this.env.pos.table) || null;
}
get floor() {
- return this.props.table.floor;
+ const table = this.table;
+ return table ? table.floor : null;
+ }
+ get hasTable() {
+ return this.table !== null;
}
- async _backToFloorScreen() {
+ backToFloorScreen() {
this.showScreen('FloorScreen', { floor: this.floor });
}
}
diff --git a/addons/pos_restaurant/static/src/js/ChromeWidgets/OrderSelector.js b/addons/pos_restaurant/static/src/js/ChromeWidgets/OrderSelector.js
deleted file mode 100644
index 255b84db073..00000000000
--- a/addons/pos_restaurant/static/src/js/ChromeWidgets/OrderSelector.js
+++ /dev/null
@@ -1,20 +0,0 @@
-odoo.define('pos_restaurant.OrderSelector', function(require) {
- 'use strict';
-
- const OrderSelector = require('point_of_sale.OrderSelector');
- const Registries = require('point_of_sale.Registries');
-
- const PosResOrderSelector = OrderSelector =>
- class extends OrderSelector {
- get currentTable() {
- return this.env.pos.table;
- }
- get backToFloorButtonIsShown() {
- return this.env.pos.config.iface_floorplan && this.currentTable;
- }
- };
-
- Registries.Component.extend(OrderSelector, PosResOrderSelector);
-
- return OrderSelector;
-});
diff --git a/addons/pos_restaurant/static/src/js/ChromeWidgets/TicketButton.js b/addons/pos_restaurant/static/src/js/ChromeWidgets/TicketButton.js
new file mode 100644
index 00000000000..1e66bf91352
--- /dev/null
+++ b/addons/pos_restaurant/static/src/js/ChromeWidgets/TicketButton.js
@@ -0,0 +1,33 @@
+odoo.define('pos_restaurant.TicketButton', function (require) {
+ 'use strict';
+
+ const TicketButton = require('point_of_sale.TicketButton');
+ const Registries = require('point_of_sale.Registries');
+ const { posbus } = require('point_of_sale.utils');
+
+ const PosResTicketButton = (TicketButton) =>
+ class extends TicketButton {
+ mounted() {
+ posbus.on('table-set', this, this.render);
+ }
+ willUnmount() {
+ posbus.off('table-set', this);
+ }
+ /**
+ * If no table is set to pos, which means the current main screen
+ * is floor screen, then the order count should be based on all the orders.
+ */
+ get count() {
+ if (!this.env.pos || !this.env.pos.config) return 0;
+ if (this.env.pos.config.iface_floorplan && !this.env.pos.table) {
+ return this.env.pos.get('orders').models.length;
+ } else {
+ return super.count;
+ }
+ }
+ };
+
+ Registries.Component.extend(TicketButton, PosResTicketButton);
+
+ return TicketButton;
+});
diff --git a/addons/pos_restaurant/static/src/js/Screens/FloorScreen/FloorScreen.js b/addons/pos_restaurant/static/src/js/Screens/FloorScreen/FloorScreen.js
index 276663cf57c..1bf06c838f5 100644
--- a/addons/pos_restaurant/static/src/js/Screens/FloorScreen/FloorScreen.js
+++ b/addons/pos_restaurant/static/src/js/Screens/FloorScreen/FloorScreen.js
@@ -171,12 +171,12 @@ odoo.define('pos_restaurant.FloorScreen', function (require) {
}
}
}
- async _onSelectTable(event) {
+ _onSelectTable(event) {
const table = event.detail;
if (this.state.isEditMode) {
this.state.selectedTableId = table.id;
} else {
- await this.env.pos.set_table(table);
+ this.env.pos.set_table(table);
}
}
_onDeselectTable() {
diff --git a/addons/pos_restaurant/static/src/js/Screens/OrderManagementScreen/OrderManagementScreen.js b/addons/pos_restaurant/static/src/js/Screens/OrderManagementScreen/OrderManagementScreen.js
index e2a1ce65dce..8753be25753 100644
--- a/addons/pos_restaurant/static/src/js/Screens/OrderManagementScreen/OrderManagementScreen.js
+++ b/addons/pos_restaurant/static/src/js/Screens/OrderManagementScreen/OrderManagementScreen.js
@@ -12,10 +12,9 @@ odoo.define('pos_restaurant.OrderManagementScreen', function (require) {
_setOrder(order) {
if (this.env.pos.config.module_pos_restaurant) {
const currentOrder = this.env.pos.get_order();
+ this.env.pos.set_table(order.table, order);
if (currentOrder && currentOrder.uid === order.uid) {
this.close();
- } else {
- this.env.pos.set_table(order.table, order);
}
} else {
super._setOrder(order);
diff --git a/addons/pos_restaurant/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js b/addons/pos_restaurant/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js
index 689c3bf40ca..5909292e0db 100644
--- a/addons/pos_restaurant/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js
+++ b/addons/pos_restaurant/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js
@@ -20,6 +20,18 @@ odoo.define('pos_restaurant.ReceiptScreen', function(require) {
return super.nextScreen;
}
}
+ /**
+ * If this order is synced to/from the server, then the draft needs to be deleted
+ * after the order is paid and the receipt screen is exited via 'Next Order' button.
+ * Thus, we set this order to be removed from server. Note that only the draft version
+ * is deleted if we trace the algorithm.
+ */
+ orderDone() {
+ if (this.env.pos.config.iface_floorplan) {
+ this.env.pos.db.set_order_to_remove_from_server(this.currentOrder);
+ }
+ super.orderDone();
+ }
};
Registries.Component.extend(ReceiptScreen, PosResReceiptScreen);
diff --git a/addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js b/addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js
index 2390e35f7c4..f44af5bff7a 100644
--- a/addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js
+++ b/addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js
@@ -55,7 +55,7 @@ odoo.define('pos_restaurant.SplitBillScreen', function(require) {
} else {
this._setQuantityOnCurrentOrder();
- this.newOrder.set_screen_data('screen', { name: 'PaymentScreen' });
+ this.newOrder.set_screen_data({ name: 'PaymentScreen' });
// for the kitchen printer we assume that everything
// has already been sent to the kitchen before splitting
@@ -72,7 +72,7 @@ odoo.define('pos_restaurant.SplitBillScreen', function(require) {
this.newOrder.set_customer_count(1);
const newCustomerCount = this.currentOrder.get_customer_count() - 1;
this.currentOrder.set_customer_count(newCustomerCount || 1);
- this.currentOrder.set_screen_data('screen', { name: 'ProductScreen' });
+ this.currentOrder.set_screen_data({ name: 'ProductScreen' });
this.env.pos.get('orders').add(this.newOrder);
this.env.pos.set('selectedOrder', this.newOrder);
diff --git a/addons/pos_restaurant/static/src/js/Screens/TicketScreen.js b/addons/pos_restaurant/static/src/js/Screens/TicketScreen.js
new file mode 100644
index 00000000000..2d5c3e004b2
--- /dev/null
+++ b/addons/pos_restaurant/static/src/js/Screens/TicketScreen.js
@@ -0,0 +1,54 @@
+odoo.define('pos_restaurant.TicketScreen', function (require) {
+ 'use strict';
+
+ const TicketScreen = require('point_of_sale.TicketScreen');
+ const Registries = require('point_of_sale.Registries');
+ const { posbus } = require('point_of_sale.utils');
+
+ const PosResTicketScreen = (TicketScreen) =>
+ class extends TicketScreen {
+ close() {
+ super.close();
+ if (!this.env.pos.config.iface_floorplan) {
+ // Make sure the 'table-set' event is triggered
+ // to properly rerender the components that listens to it.
+ posbus.trigger('table-set');
+ }
+ }
+ getTable(order) {
+ return `${order.table.floor.name} (${order.table.name})`;
+ }
+ get _searchFields() {
+ if (!this.env.pos.config.iface_floorplan) {
+ return super._searchFields;
+ }
+ return Object.assign({}, super._searchFields, {
+ Table: (order) => `${order.table.floor.name} (${order.table.name})`,
+ });
+ }
+ _setOrder(order) {
+ if (!this.env.pos.config.iface_floorplan) {
+ super._setOrder(order);
+ } else if (order !== this.env.pos.get_order()) {
+ // Only call set_table if the order is not the same as the current order.
+ // This is to prevent syncing to the server because syncing is only intended
+ // when going back to the floorscreen or opening a table.
+ this.env.pos.set_table(order.table, order);
+ }
+ }
+ get showNewTicketButton() {
+ return this.env.pos.config.iface_floorplan ? Boolean(this.env.pos.table) : super.showNewTicketButton;
+ }
+ get orderList() {
+ if (this.env.pos.table) {
+ return super.orderList;
+ } else {
+ return this.env.pos.get('orders').models;
+ }
+ }
+ };
+
+ Registries.Component.extend(TicketScreen, PosResTicketScreen);
+
+ return TicketScreen;
+});
diff --git a/addons/pos_restaurant/static/src/js/floors.js b/addons/pos_restaurant/static/src/js/floors.js
index b6614c07ebe..51ded242c63 100644
--- a/addons/pos_restaurant/static/src/js/floors.js
+++ b/addons/pos_restaurant/static/src/js/floors.js
@@ -2,6 +2,8 @@ odoo.define('pos_restaurant.floors', function (require) {
"use strict";
var models = require('point_of_sale.models');
+const { Gui } = require('point_of_sale.Gui');
+const { posbus } = require('point_of_sale.utils');
// At POS Startup, load the floors, and add them to the pos model
models.load_models({
@@ -213,7 +215,12 @@ models.PosModel = models.PosModel.extend({
this._get_from_server(table.id).then(function (server_orders) {
var orders = self.get_order_list();
orders.forEach(function(order){
- if (order.server_id){
+ const screen = order.get_screen_data();
+ // Only remove the 'Receipt' status order when 'Next Order'
+ // from the receipt screen is clicked. We are bypassing the
+ // removal of paid order here to make sure those orders are
+ // still in the tickets list.
+ if (order.server_id && screen.name !== 'ReceiptScreen'){
self.get("orders").remove(order);
order.destroy();
}
@@ -257,6 +264,7 @@ models.PosModel = models.PosModel.extend({
if(!table){
this.sync_from_server(table, this.get_order_list(), this.get_order_with_uid());
this.set_order(null);
+ this.table = null;
} else if (this.order_to_transfer_to_different_table) {
var order_ids = this.get_order_with_uid();
@@ -269,6 +277,7 @@ models.PosModel = models.PosModel.extend({
this.table = table;
this.sync_to_server(table, order);
}
+ posbus.trigger('table-set');
},
// if we have tables, we do not load a default order, as the default order will be
@@ -284,9 +293,12 @@ models.PosModel = models.PosModel.extend({
add_new_order: function() {
if (this.config.iface_floorplan) {
if (this.table) {
- return _super_posmodel.add_new_order.call(this);
+ return _super_posmodel.add_new_order.apply(this, arguments);
} else {
- console.warn("WARNING: orders cannot be created when there is no active table in restaurant mode");
+ Gui.showPopup('ConfirmPopup', {
+ title: 'Unable to create order',
+ body: 'Orders cannot be created when there is no active table in restaurant mode',
+ });
return undefined;
}
} else {
@@ -298,7 +310,7 @@ models.PosModel = models.PosModel.extend({
// get the list of unpaid orders (associated to the current table)
get_order_list: function() {
var orders = _super_posmodel.get_order_list.call(this);
- if (!this.config.iface_floorplan) {
+ if (!(this.config && this.config.iface_floorplan)) {
return orders;
} else if (!this.table) {
return [];
@@ -345,7 +357,7 @@ models.PosModel = models.PosModel.extend({
this.db.set_order_to_remove_from_server(removed_order);
}
if( (reason === 'abandon' || removed_order.temporary) && order_list.length > 0){
- this.set_order(order_list[index] || order_list[order_list.length -1]);
+ this.set_order(order_list[index] || order_list[order_list.length - 1], { silent: true });
} else if (order_list.length === 0) {
this.set_order(null);
}
diff --git a/addons/pos_restaurant/static/src/xml/Chrome.xml b/addons/pos_restaurant/static/src/xml/Chrome.xml
new file mode 100644
index 00000000000..86032c07017
--- /dev/null
+++ b/addons/pos_restaurant/static/src/xml/Chrome.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templates id="template" xml:space="preserve">
+
+ <t t-name="Chrome" t-inherit="point_of_sale.Chrome" t-inherit-mode="extension" owl="1">
+ <xpath expr="//div[hasclass('search-bar-portal')]" position="before">
+ <BackToFloorButton />
+ </xpath>
+ </t>
+
+</templates>
diff --git a/addons/pos_restaurant/static/src/xml/ChromeWidgets/BackToFloorButton.xml b/addons/pos_restaurant/static/src/xml/ChromeWidgets/BackToFloorButton.xml
index 1f36d2763f3..2b5c865ca18 100644
--- a/addons/pos_restaurant/static/src/xml/ChromeWidgets/BackToFloorButton.xml
+++ b/addons/pos_restaurant/static/src/xml/ChromeWidgets/BackToFloorButton.xml
@@ -2,7 +2,7 @@
<templates id="template" xml:space="preserve">
<t t-name="BackToFloorButton" owl="1">
- <span class="order-button floor-button">
+ <span t-if="hasTable" class="order-button floor-button" t-on-click="backToFloorScreen">
<i class="fa fa-angle-double-left" role="img" aria-label="Back to floor" title="Back to floor" />
<span> </span>
<span t-esc="floor.name" />
@@ -13,6 +13,7 @@
<span> )</span>
</span>
</span>
+ <span t-else=""></span>
</t>
</templates>
diff --git a/addons/pos_restaurant/static/src/xml/ChromeWidgets/OrderSelector.xml b/addons/pos_restaurant/static/src/xml/ChromeWidgets/OrderSelector.xml
deleted file mode 100644
index 824ff26bcee..00000000000
--- a/addons/pos_restaurant/static/src/xml/ChromeWidgets/OrderSelector.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<templates id="template" xml:space="preserve">
-
- <t t-name="OrderSelector" t-inherit="point_of_sale.OrderSelector" t-inherit-mode="extension" owl="1">
- <xpath expr="//div[hasclass('order-selector')]//span[hasclass('orders')]//t" position="before">
- <BackToFloorButton t-if="backToFloorButtonIsShown" table="currentTable" />
- </xpath>
- <xpath expr="//span[hasclass('order-sequence')]" position="replace">
- <span class="order-sequence">
- <t t-if="order.server_id and env.pos.pos_session.login_number != order.uid.split('-')[1]">
- <t t-esc="order.uid.substring(order.uid.indexOf('-') +1)" />
- </t>
- <t t-else="">
- <t t-esc="order.sequence_number" />
- </t>
- </span>
- </xpath>
- </t>
-
-</templates>
diff --git a/addons/pos_restaurant/static/src/xml/Screens/TicketScreen.xml b/addons/pos_restaurant/static/src/xml/Screens/TicketScreen.xml
new file mode 100644
index 00000000000..7430ee1a6b7
--- /dev/null
+++ b/addons/pos_restaurant/static/src/xml/Screens/TicketScreen.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templates id="template" xml:space="preserve">
+
+ <t t-name="TicketScreen" t-inherit="point_of_sale.TicketScreen" t-inherit-mode="extension" owl="1">
+ <xpath expr="//div[hasclass('header-row')]//div[@name='delete']" position="before">
+ <div t-if="env.pos.config.iface_floorplan" class="col start" name="table">Table</div>
+ </xpath>
+ <xpath expr="//div[hasclass('order-row')]//div[@name='delete']" position="before">
+ <div t-if="env.pos.config.iface_floorplan" class="col start" name="table">
+ <t t-esc="getTable(order)"></t>
+ </div>
+ </xpath>
+ </t>
+
+</templates>
diff --git a/addons/pos_restaurant/static/tests/tours/OrderManagementScreen.tour.js b/addons/pos_restaurant/static/tests/tours/OrderManagementScreen.tour.js
index 2a198c9e7ab..5cedaba0a14 100644
--- a/addons/pos_restaurant/static/tests/tours/OrderManagementScreen.tour.js
+++ b/addons/pos_restaurant/static/tests/tours/OrderManagementScreen.tour.js
@@ -11,6 +11,7 @@ odoo.define('pos_restaurant.tour.OrderManagementScreen', function (require) {
} = require('point_of_sale.tour.OrderManagementScreenTourMethods');
const { FloorScreen } = require('pos_restaurant.tour.FloorScreenTourMethods');
const { ProductScreen } = require('pos_restaurant.tour.ProductScreenTourMethods');
+ const { TicketScreen } = require('point_of_sale.tour.TicketScreenTourMethods');
const { getSteps, startSteps } = require('point_of_sale.tour.utils');
var Tour = require('web_tour.tour');
@@ -36,7 +37,8 @@ odoo.define('pos_restaurant.tour.OrderManagementScreen', function (require) {
['Water', '3', '4'],
['Minute Maid', '5', '6']
);
- Chrome.do.newOrder();
+ Chrome.do.clickTicketButton();
+ TicketScreen.do.clickNewTicket();
ProductScreen.exec.addMultiOrderlines(['Coca-Cola', '1', '2'], ['Minute Maid', '5', '6']);
Chrome.do.backToFloor();
@@ -47,7 +49,8 @@ odoo.define('pos_restaurant.tour.OrderManagementScreen', function (require) {
['Water', '9', '10'],
['Minute Maid', '11', '12']
);
- Chrome.do.newOrder();
+ Chrome.do.clickTicketButton();
+ TicketScreen.do.clickNewTicket();
ProductScreen.exec.addMultiOrderlines(['Coca-Cola', '13', '14'], ['Minute Maid', '15', '16']);
Chrome.do.backToFloor();
diff --git a/addons/pos_restaurant/static/tests/tours/SplitBillScreen.tour.js b/addons/pos_restaurant/static/tests/tours/SplitBillScreen.tour.js
index 82e783dbcc7..9eb138bbb9b 100644
--- a/addons/pos_restaurant/static/tests/tours/SplitBillScreen.tour.js
+++ b/addons/pos_restaurant/static/tests/tours/SplitBillScreen.tour.js
@@ -6,6 +6,7 @@ odoo.define('pos_restaurant.tour.SplitBillScreen', function (require) {
const { FloorScreen } = require('pos_restaurant.tour.FloorScreenTourMethods');
const { ProductScreen } = require('pos_restaurant.tour.ProductScreenTourMethods');
const { SplitBillScreen } = require('pos_restaurant.tour.SplitBillScreenTourMethods');
+ const { TicketScreen } = require('point_of_sale.tour.TicketScreenTourMethods');
const { getSteps, startSteps } = require('point_of_sale.tour.utils');
var Tour = require('web_tour.tour');
@@ -42,7 +43,8 @@ odoo.define('pos_restaurant.tour.SplitBillScreen', function (require) {
ProductScreen.do.clickOrderline('Coca-Cola', '1.0')
// go back to the original order and see if the order is changed
- Chrome.do.selectOrder('1');
+ Chrome.do.clickTicketButton();
+ TicketScreen.do.selectOrder('-0001');
ProductScreen.do.clickOrderline('Water', '2.0')
ProductScreen.do.clickOrderline('Minute Maid', '3.0')
diff --git a/addons/pos_restaurant/static/tests/tours/TicketScreen.tour.js b/addons/pos_restaurant/static/tests/tours/TicketScreen.tour.js
new file mode 100644
index 00000000000..790ae060777
--- /dev/null
+++ b/addons/pos_restaurant/static/tests/tours/TicketScreen.tour.js
@@ -0,0 +1,44 @@
+odoo.define('pos_restaurant.tour.TicketScreen', function (require) {
+ 'use strict';
+
+ const { ProductScreen } = require('point_of_sale.tour.ProductScreenTourMethods');
+ const { FloorScreen } = require('pos_restaurant.tour.FloorScreenTourMethods');
+ const { TicketScreen } = require('point_of_sale.tour.TicketScreenTourMethods');
+ const { Chrome } = require('pos_restaurant.tour.ChromeTourMethods');
+ const { getSteps, startSteps } = require('point_of_sale.tour.utils');
+ var Tour = require('web_tour.tour');
+
+ startSteps();
+
+ // New Ticket button should not be in the ticket screen if no table is selected.
+ Chrome.do.clickTicketButton();
+ TicketScreen.check.noNewTicketButton();
+ TicketScreen.do.clickDiscard();
+
+ // Deleting the last order in the table brings back to floorscreen
+ FloorScreen.do.clickTable('T4');
+ Chrome.do.clickTicketButton();
+ TicketScreen.check.nthRowContains(2, '-0001');
+ TicketScreen.do.deleteOrder('-0001');
+ FloorScreen.check.isShown();
+
+ // Create 2 items in a table. From floorscreen, delete 1 item. Then select the other item.
+ // Correct order and screen should be displayed and the BackToFloorButton is shown.
+ FloorScreen.do.clickTable('T2');
+ ProductScreen.exec.addOrderline('Minute Maid', '1', '2');
+ ProductScreen.check.totalAmountIs('2.0');
+ Chrome.do.clickTicketButton();
+ TicketScreen.do.clickNewTicket();
+ ProductScreen.exec.addOrderline('Coca-Cola', '2', '2');
+ ProductScreen.check.totalAmountIs('4.0');
+ Chrome.do.backToFloor();
+ FloorScreen.check.orderCountSyncedInTableIs('T2', '2');
+ Chrome.do.clickTicketButton();
+ TicketScreen.do.deleteOrder('-0003');
+ Chrome.do.confirmPopup();
+ TicketScreen.do.selectOrder('-0002');
+ ProductScreen.check.totalAmountIs('2.0');
+ Chrome.check.backToFloorTextIs('Main Floor', 'T2');
+
+ Tour.register('PosResTicketScreenTour', { test: true, url: '/pos/web' }, getSteps());
+});
diff --git a/addons/pos_restaurant/static/tests/tours/helpers/FloorScreenTourMethods.js b/addons/pos_restaurant/static/tests/tours/helpers/FloorScreenTourMethods.js
index 6895dc3e257..b6e614357f0 100644
--- a/addons/pos_restaurant/static/tests/tours/helpers/FloorScreenTourMethods.js
+++ b/addons/pos_restaurant/static/tests/tours/helpers/FloorScreenTourMethods.js
@@ -72,9 +72,7 @@ odoo.define('pos_restaurant.tour.FloorScreenTourMethods', function (require) {
return [
{
content: `change shape to '${shape}'`,
- trigger: `.edit-button .button-option${
- shape === 'round' ? '.square' : '.round'
- }`,
+ trigger: `.edit-button .button-option${shape === 'round' ? '.square' : '.round'}`,
},
];
}
@@ -122,6 +120,23 @@ odoo.define('pos_restaurant.tour.FloorScreenTourMethods', function (require) {
{
content: `number of seats in table '${table}' is '${val}'`,
trigger: `.floor-map .tables .table .label:contains("${table}") ~ .table-seats:contains("${val}")`,
+ run: function () {},
+ },
+ ];
+ }
+ orderCountSyncedInTableIs(table, count) {
+ return [
+ {
+ trigger: `.floor-map .table .order-count:contains("${count}") ~ .label:contains("${table}")`,
+ run: function () {},
+ },
+ ];
+ }
+ isShown() {
+ return [
+ {
+ trigger: '.floor-map',
+ run: function () {},
},
];
}
diff --git a/addons/pos_restaurant/static/tests/tours/pos_restaurant.js b/addons/pos_restaurant/static/tests/tours/pos_restaurant.js
index 8d5e8f0a80d..252e9834e63 100644
--- a/addons/pos_restaurant/static/tests/tours/pos_restaurant.js
+++ b/addons/pos_restaurant/static/tests/tours/pos_restaurant.js
@@ -1,252 +1,108 @@
odoo.define('pos_reataurant.tour.synchronized_table_management', function (require) {
- "use strict";
-
- var Tour = require("web_tour.tour");
-
- function verify_order_total(total_str) {
- return [{
- content: 'order total contains ' + total_str,
- trigger: '.order .total .value:contains("' + total_str + '")',
- run: function () {}, // it's a check
- }];
- }
-
- function verify_orders_synced(order_count) {
- return [{
- content: "check synced",
- trigger: ".order-sequence",
- run: function() {
- var orders = $('.order-sequence');
- if (orders.length === order_count) {
- return
- } else {
- throw `sync failed 'there should be ${order_count} orders, however, ${orders.length} orders are displayed' `;
- }
- },
- }];
- }
-
- function add_product_to_order(product_name) {
- return [{
- content: 'buy ' + product_name,
- trigger: '.product-list .product-name:contains("' + product_name + '")',
- }, {
- content: 'the ' + product_name + ' have been added to the order',
- trigger: '.order .product-name:contains("' + product_name + '")',
- run: function () {}, // it's a check
- }];
- }
-
- function generate_keypad_steps(amount_str, keypad_selector) {
- var i, steps = [], current_char;
- for (i = 0; i < amount_str.length; ++i) {
- current_char = amount_str[i];
- steps.push({
- content: 'press ' + current_char + ' on payment keypad',
- trigger: keypad_selector + ' .input-button:contains("' + current_char + '"):visible'
- });
- }
-
- return steps;
- }
-
- function generate_payment_screen_keypad_steps(amount_str) {
- return generate_keypad_steps(amount_str, '.payment-numpad');
- }
-
- function generate_product_screen_keypad_steps(amount_str) {
- return generate_keypad_steps(amount_str, '.numpad');
- }
-
- function goto_payment_screen_and_select_payment_method() {
- return [{
- content: "go to payment screen",
- trigger: '.button.pay',
- }, {
- content: "pay with cash",
- trigger: '.paymentmethod:contains("Cash")',
- }];
- }
-
- function open_table(table_id, order_count) {
- order_count = order_count || null;
- var steps = [{
- content: 'open table ' + table_id,
- trigger: '.label:contains(' + table_id +')',
- run: 'click',
- }];
- if (order_count !== null){
- steps = steps.concat(verify_orders_synced(order_count));
- }
- return steps;
- }
-
- function transfer_order_to_table(table_id, order_uid) {
- return [{
- content: 'Click transfer button',
- trigger: '.control-button:contains("Transfer")',
- run: 'click',
- }, {
- content: 'Transfer order to table ' + table_id,
- trigger: '.label:contains(' + table_id +')',
- run: 'click',
- }, {
- content: 'Check if order ' + order_uid + ' is open after transfer',
- trigger: '.order-button.selected .order-sequence:contains("' + order_uid + '")',
- run: function(){} // Check
- }];
- }
-
- function finish_order() {
- var steps = [{
- content: "validate the order",
- trigger: '.payment-screen .button.next:visible',
- }];
- steps = steps.concat([{
- content: "next order",
- trigger: '.receipt-screen .button.next:visible',
- }]);
- return steps;
- }
-
- /* pos_restaurant_sync
- *
- * Run on new session.
- */
- var steps = [{
- content: 'waiting for loading to finish',
- trigger: 'body:not(:has(.loader))',
- run: function () {},
- }]
-
-
- steps = steps.concat(open_table('T5'));
-
- steps = steps.concat(add_product_to_order('Coca-Cola'));
- steps = steps.concat(add_product_to_order('Water'));
- steps = steps.concat(verify_order_total('4.40'));
- steps = steps.concat([{
- content: 'start new order',
- trigger: '.neworder-button',
- run: 'click',
- }]);
- steps = steps.concat(add_product_to_order('Coca-Cola'));
- steps = steps.concat(add_product_to_order('Minute Maid'));
- steps = steps.concat(verify_order_total('4.40'));
- steps = steps.concat(goto_payment_screen_and_select_payment_method());
- steps = steps.concat(generate_payment_screen_keypad_steps('6.05'));
- steps = steps.concat(finish_order());
- steps = steps.concat(open_table('T5', 1));
- steps = steps.concat(verify_order_total('4.40'));
- steps = steps.concat([{
- content: 'start new order',
- trigger: '.neworder-button',
- run: 'click',
- }]);
- steps = steps.concat(add_product_to_order('Coca-Cola'));
- steps = steps.concat(add_product_to_order('Minute Maid'));
- steps = steps.concat([{
- content: 'back to floor',
- trigger: '.floor-button',
- run: 'click',
- }]);
- steps = steps.concat(open_table('T5', 2));
- steps = steps.concat([{
- content: 'delete order',
- trigger: '.deleteorder-button',
- run: 'click',
- }, {
- content: 'confirm delete',
- trigger: '.button.confirm',
- run: 'click',
- }, {
- content: 'back to floor',
- trigger: '.floor-button',
- run: 'click',
- }, {
- content: 'back to floor',
- trigger: '.oe_status .js_connected',
- run: function() {},
- }]);
- steps = steps.concat(open_table('T5', 1));
-
- Tour.register('pos_restaurant_sync', { test: true, url: '/pos/web' }, steps);
-
+ 'use strict';
+
+ const { PaymentScreen } = require('point_of_sale.tour.PaymentScreenTourMethods');
+ const { ReceiptScreen } = require('point_of_sale.tour.ReceiptScreenTourMethods');
+ const { Chrome } = require('pos_restaurant.tour.ChromeTourMethods');
+ const { FloorScreen } = require('pos_restaurant.tour.FloorScreenTourMethods');
+ const { ProductScreen } = require('pos_restaurant.tour.ProductScreenTourMethods');
+ const { TicketScreen } = require('point_of_sale.tour.TicketScreenTourMethods');
+ const { getSteps, startSteps } = require('point_of_sale.tour.utils');
+ const Tour = require('web_tour.tour');
+
+ startSteps();
+
+ FloorScreen.do.clickTable('T5');
+
+ // Create first order
+ ProductScreen.do.clickDisplayedProduct('Coca-Cola');
+ ProductScreen.check.selectedOrderlineHas('Coca-Cola');
+ ProductScreen.do.clickDisplayedProduct('Water');
+ ProductScreen.check.selectedOrderlineHas('Water');
+ ProductScreen.check.totalAmountIs('4.40');
+
+ // Create 2nd order (paid)
+ Chrome.do.clickTicketButton();
+ TicketScreen.do.clickNewTicket();
+ ProductScreen.do.clickDisplayedProduct('Coca-Cola');
+ ProductScreen.check.selectedOrderlineHas('Coca-Cola');
+ ProductScreen.do.clickDisplayedProduct('Minute Maid');
+ ProductScreen.check.selectedOrderlineHas('Minute Maid');
+ ProductScreen.check.totalAmountIs('4.40');
+ ProductScreen.do.clickPayButton();
+ PaymentScreen.do.clickPaymentMethod('Cash');
+ PaymentScreen.do.clickValidate();
+ ReceiptScreen.do.clickNextOrder();
+
+ // After clicking next order, floor screen is shown.
+ // It should have 1 as number of draft synced order.
+ FloorScreen.check.orderCountSyncedInTableIs('T5', '1');
+ FloorScreen.do.clickTable('T5');
+ ProductScreen.check.totalAmountIs('4.40');
+
+ // Create another draft order and go back to floor
+ Chrome.do.clickTicketButton();
+ TicketScreen.do.clickNewTicket();
+ ProductScreen.do.clickDisplayedProduct('Coca-Cola');
+ ProductScreen.check.selectedOrderlineHas('Coca-Cola');
+ ProductScreen.do.clickDisplayedProduct('Minute Maid');
+ ProductScreen.check.selectedOrderlineHas('Minute Maid');
+ Chrome.do.backToFloor();
+
+ // At floor screen, there should be 2 synced draft orders
+ FloorScreen.check.orderCountSyncedInTableIs('T5', '2');
+
+ // Delete the first order then go back to floor
+ FloorScreen.do.clickTable('T5');
+ ProductScreen.check.isShown();
+ Chrome.do.clickTicketButton();
+ TicketScreen.do.deleteOrder('-0001');
+ Chrome.do.confirmPopup();
+ TicketScreen.do.selectOrder('-0003');
+ Chrome.do.backToFloor();
+
+ // There should be 1 synced draft order.
+ FloorScreen.check.orderCountSyncedInTableIs('T5', '1');
+
+ Tour.register('pos_restaurant_sync', { test: true, url: '/pos/web' }, getSteps());
+
+ startSteps();
/* pos_restaurant_sync_second_login
*
* This tour should be run after the first tour is done.
*/
- var steps = [{
- content: 'waiting for loading to finish',
- trigger: 'body:not(:has(.loader))',
- run: function () {},
- }];
- steps = steps.concat(open_table('T5', 1));
- steps = steps.concat(verify_order_total('4.40'));
+
+ // There is one draft synced order from the previous tour
+ FloorScreen.check.orderCountSyncedInTableIs('T5', '1');
+ FloorScreen.do.clickTable('T5');
+ ProductScreen.check.totalAmountIs('4.40');
// Test transfering an order
- steps = steps.concat(transfer_order_to_table('T4', '002-0001'));
+ ProductScreen.do.clickTransferButton();
+ FloorScreen.do.clickTable('T4');
// Test if products still get merged after transfering the order
- steps = steps.concat(add_product_to_order('Coca-Cola'));
- steps = steps.concat({
- content: 'check the order-line for Coca-Cola has 2 Units',
- trigger: '.orderlines:has(.orderline .product-name:contains("Coca-Cola")) .info-list:contains("2.000")',
- run: function () {},
- })
- steps = steps.concat(generate_product_screen_keypad_steps('1'));
-
- steps = steps.concat(goto_payment_screen_and_select_payment_method());
- steps = steps.concat(generate_payment_screen_keypad_steps('4.4'));
- steps = steps.concat(finish_order());
- steps = steps.concat(open_table('T2'));
-
- // Test transfering an empty order
- steps = steps.concat(transfer_order_to_table('T4', '2'));
-
- steps = steps.concat(add_product_to_order('Coca-Cola'));
- steps = steps.concat(verify_order_total('2.20'));
-
- // Take a synced order with products, remove the products
- // and check if the order is still available in the front-end
- steps = steps.concat([{
- content: 'back to floor',
- trigger: '.floor-button',
- run: 'click',
- }]);
- steps = steps.concat(open_table('T4', 1));
- steps = steps.concat([{
- content: 'click backspace to set quantity to 0',
- trigger: '.numpad-backspace',
- run: 'click',
- }, {
- content: 'click backspace to remove line',
- trigger: '.numpad-backspace',
- run: 'click',
- }]);
- steps = steps.concat([{
- content: 'back to floor',
- trigger: '.floor-button',
- run: 'click',
- }]);
- steps = steps.concat(open_table('T4', 1));
- steps = steps.concat(add_product_to_order('Coca-Cola'));
- steps = steps.concat(verify_order_total('2.20'));
- steps = steps.concat([{
- content: 'back to floor',
- trigger: '.floor-button',
- run: 'click',
- }, {
- content: 'check if in floor screen',
- trigger: '.pos-content .floor-screen',
- run: function() {},
- }, {
- content: 'wait for sync to finish',
- trigger: '.oe_status .js_connected',
- run: function() {},
- }]);
-
- Tour.register('pos_restaurant_sync_second_login', { test: true, url: '/pos/web' }, steps);
-
+ ProductScreen.do.clickDisplayedProduct('Coca-Cola');
+ ProductScreen.check.selectedOrderlineHas('Coca-Cola', '2.0');
+ ProductScreen.check.totalAmountIs('6.60');
+ ProductScreen.do.pressNumpad('1');
+ ProductScreen.check.totalAmountIs('4.40');
+ ProductScreen.do.clickPayButton();
+ PaymentScreen.do.clickPaymentMethod('Cash');
+ PaymentScreen.do.clickValidate();
+ ReceiptScreen.do.clickNextOrder();
+ // At this point, there are no draft orders.
+
+ FloorScreen.do.clickTable('T2');
+ ProductScreen.check.isShown();
+ ProductScreen.check.orderIsEmpty();
+ ProductScreen.do.clickTransferButton();
+ FloorScreen.do.clickTable('T4');
+ ProductScreen.do.clickDisplayedProduct('Coca-Cola');
+ ProductScreen.check.totalAmountIs('2.20');
+ Chrome.do.backToFloor();
+ FloorScreen.check.orderCountSyncedInTableIs('T4', '1');
+
+ Tour.register('pos_restaurant_sync_second_login', { test: true, url: '/pos/web' }, getSteps());
});