Initial commit: Pos packages

This commit is contained in:
Ernad Husremovic 2025-08-29 15:20:50 +02:00
commit 95dfb9edb0
1301 changed files with 264148 additions and 0 deletions

View file

@ -0,0 +1,62 @@
odoo.define('pos_restaurant.tour.ControlButtons', function (require) {
'use strict';
const { TextAreaPopup } = require('point_of_sale.tour.TextAreaPopupTourMethods');
const { NumberPopup } = require('point_of_sale.tour.NumberPopupTourMethods');
const { Chrome } = require('pos_restaurant.tour.ChromeTourMethods');
const { FloorScreen } = require('pos_restaurant.tour.FloorScreenTourMethods');
const { ProductScreen } = require('pos_restaurant.tour.ProductScreenTourMethods');
const { SplitBillScreen } = require('pos_restaurant.tour.SplitBillScreenTourMethods');
const { BillScreen } = require('pos_restaurant.tour.BillScreenTourMethods');
const { getSteps, startSteps } = require('point_of_sale.tour.utils');
var Tour = require('web_tour.tour');
// signal to start generating steps
// when finished, steps can be taken from getSteps
startSteps();
// Test TransferOrderButton
FloorScreen.do.clickTable('T2');
ProductScreen.exec.addOrderline('Water', '5', '2', '10.0');
ProductScreen.do.clickTransferButton();
FloorScreen.do.clickTable('T4');
ProductScreen.do.clickOrderline('Water', '5', '2');
Chrome.do.backToFloor();
FloorScreen.do.clickTable('T2');
ProductScreen.check.orderIsEmpty();
Chrome.do.backToFloor();
FloorScreen.do.clickTable('T4');
ProductScreen.do.clickOrderline('Water', '5', '2');
// Test SplitBillButton
ProductScreen.do.clickSplitBillButton();
SplitBillScreen.do.clickBack();
// Test OrderlineNoteButton
ProductScreen.do.clickNoteButton();
TextAreaPopup.check.isShown();
TextAreaPopup.do.inputText('test note');
TextAreaPopup.do.clickConfirm();
ProductScreen.check.orderlineHasNote('Water', '5', 'test note');
ProductScreen.exec.addOrderline('Water', '8', '1', '8.0');
// Test PrintBillButton
ProductScreen.do.clickPrintBillButton();
BillScreen.check.isShown();
BillScreen.do.clickOk();
// Test GuestButton
ProductScreen.do.clickGuestButton();
NumberPopup.do.pressNumpad('1 5');
NumberPopup.check.inputShownIs('15');
NumberPopup.do.clickConfirm();
ProductScreen.check.guestNumberIs('15')
ProductScreen.do.clickGuestButton();
NumberPopup.do.pressNumpad('5');
NumberPopup.check.inputShownIs('5');
NumberPopup.do.clickConfirm();
ProductScreen.check.guestNumberIs('5')
Tour.register('ControlButtonsTour', { test: true, url: '/pos/ui' }, getSteps());
});

View file

@ -0,0 +1,118 @@
odoo.define('pos_restaurant.tour.FloorScreen', function (require) {
'use strict';
const { Chrome } = require('pos_restaurant.tour.ChromeTourMethods');
const { FloorScreen } = require('pos_restaurant.tour.FloorScreenTourMethods');
const { TextInputPopup } = require('point_of_sale.tour.TextInputPopupTourMethods');
const { NumberPopup } = require('point_of_sale.tour.NumberPopupTourMethods');
const { ProductScreen } = require('pos_restaurant.tour.ProductScreenTourMethods');
const { getSteps, startSteps } = require('point_of_sale.tour.utils');
var Tour = require('web_tour.tour');
// signal to start generating steps
// when finished, steps can be taken from getSteps
startSteps();
// check floors if they contain their corresponding tables
FloorScreen.check.selectedFloorIs('Main Floor');
FloorScreen.check.hasTable('T2');
FloorScreen.check.hasTable('T4');
FloorScreen.check.hasTable('T5');
FloorScreen.do.clickFloor('Second Floor');
FloorScreen.check.hasTable('T3');
FloorScreen.check.hasTable('T1');
// clicking table in active mode does not open product screen
// instead, table is selected
FloorScreen.do.clickEdit();
FloorScreen.check.editModeIsActive(true);
FloorScreen.do.clickTable('T3');
FloorScreen.check.selectedTableIs('T3');
FloorScreen.do.clickTable('T1');
FloorScreen.check.selectedTableIs('T1');
// switching floor in edit mode deactivates edit mode
FloorScreen.do.clickFloor('Main Floor');
FloorScreen.check.editModeIsActive(false);
FloorScreen.do.clickEdit();
FloorScreen.check.editModeIsActive(true);
// test add table
FloorScreen.do.clickAddTable();
FloorScreen.check.selectedTableIs('T1');
FloorScreen.do.clickRename();
TextInputPopup.check.isShown();
TextInputPopup.do.inputText('T100');
TextInputPopup.do.clickConfirm();
FloorScreen.check.selectedTableIs('T100');
// test duplicate table
FloorScreen.do.clickDuplicate();
// new table is already named T101
FloorScreen.check.selectedTableIs('T101');
FloorScreen.do.clickRename();
TextInputPopup.check.isShown();
TextInputPopup.do.inputText('T1111');
TextInputPopup.do.clickConfirm();
FloorScreen.check.selectedTableIs('T1111');
// switch floor, switch back and check if
// the new tables are still there
FloorScreen.do.clickFloor('Second Floor');
FloorScreen.check.editModeIsActive(false);
FloorScreen.check.hasTable('T3');
FloorScreen.check.hasTable('T1');
FloorScreen.do.clickFloor('Main Floor');
FloorScreen.check.hasTable('T2');
FloorScreen.check.hasTable('T4');
FloorScreen.check.hasTable('T5');
FloorScreen.check.hasTable('T100');
FloorScreen.check.hasTable('T1111');
// test delete table
FloorScreen.do.clickEdit();
FloorScreen.check.editModeIsActive(true);
FloorScreen.do.clickTable('T2');
FloorScreen.check.selectedTableIs('T2');
FloorScreen.do.clickTrash();
Chrome.do.confirmPopup();
// change number of seats
FloorScreen.do.clickTable('T4');
FloorScreen.check.selectedTableIs('T4');
FloorScreen.do.clickSeats();
NumberPopup.do.pressNumpad('Backspace 9');
NumberPopup.check.inputShownIs('9');
NumberPopup.do.clickConfirm();
FloorScreen.check.tableSeatIs('T4', '9');
// change number of seat when the input is already selected
FloorScreen.do.clickTable('T4');
FloorScreen.check.selectedTableIs('T4');
FloorScreen.do.clickSeats();
NumberPopup.do.pressNumpad('1 5');
NumberPopup.check.inputShownIs('15');
NumberPopup.do.clickConfirm();
FloorScreen.check.tableSeatIs('T4', '15');
// change shape
FloorScreen.do.changeShapeTo('round');
// Opening product screen in main floor should go back to main floor
FloorScreen.do.clickEdit();
FloorScreen.check.editModeIsActive(false);
FloorScreen.check.tableIsNotSelected('T4');
FloorScreen.do.clickTable('T4');
ProductScreen.check.isShown();
Chrome.check.backToFloorTextIs('Main Floor', 'T4');
Chrome.do.backToFloor();
// Opening product screen in second floor should go back to second floor
FloorScreen.do.clickFloor('Second Floor');
FloorScreen.check.hasTable('T3');
FloorScreen.do.clickTable('T3');
Chrome.check.backToFloorTextIs('Second Floor', 'T3');
Tour.register('FloorScreenTour', { test: true, url: '/pos/ui' }, getSteps());
});

View file

@ -0,0 +1,80 @@
odoo.define('pos_restaurant.tour.SplitBillScreen', function (require) {
'use strict';
const { PaymentScreen } = require('point_of_sale.tour.PaymentScreenTourMethods');
const { Chrome } = require('pos_restaurant.tour.ChromeTourMethods');
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');
// signal to start generating steps
// when finished, steps can be taken from getSteps
startSteps();
FloorScreen.do.clickTable('T2');
ProductScreen.do.confirmOpeningPopup();
ProductScreen.exec.addOrderline('Water', '5', '2', '10.0');
ProductScreen.exec.addOrderline('Minute Maid', '3', '2', '6.0');
ProductScreen.exec.addOrderline('Coca-Cola', '1', '2', '2.0');
ProductScreen.do.clickSplitBillButton();
// Check if the screen contains all the orderlines
SplitBillScreen.check.orderlineHas('Water', '5', '0');
SplitBillScreen.check.orderlineHas('Minute Maid', '3', '0');
SplitBillScreen.check.orderlineHas('Coca-Cola', '1', '0');
// split 3 water and 1 coca-cola
SplitBillScreen.do.clickOrderline('Water');
SplitBillScreen.check.orderlineHas('Water', '5', '1');
SplitBillScreen.do.clickOrderline('Water');
SplitBillScreen.do.clickOrderline('Water');
SplitBillScreen.check.orderlineHas('Water', '5', '3');
SplitBillScreen.check.subtotalIs('6.0')
SplitBillScreen.do.clickOrderline('Coca-Cola');
SplitBillScreen.check.orderlineHas('Coca-Cola', '1', '1');
SplitBillScreen.check.subtotalIs('8.0')
// click pay to split, go back to check the lines
SplitBillScreen.do.clickPay();
PaymentScreen.do.clickBack();
ProductScreen.do.clickOrderline('Water', '3.0')
ProductScreen.do.clickOrderline('Coca-Cola', '1.0')
// go back to the original order and see if the order is changed
Chrome.do.clickTicketButton();
TicketScreen.do.selectOrder('-0001');
ProductScreen.check.isShown()
ProductScreen.do.clickOrderline('Water', '2.0')
ProductScreen.do.clickOrderline('Minute Maid', '3.0')
Tour.register('SplitBillScreenTour', { test: true, url: '/pos/ui' }, getSteps());
startSteps();
FloorScreen.do.clickTable('T2');
ProductScreen.exec.addOrderline('Water', '1', '2.0');
ProductScreen.exec.addOrderline('Minute Maid', '1', '2.0');
ProductScreen.exec.addOrderline('Coca-Cola', '1', '2.0');
Chrome.do.backToFloor();
FloorScreen.do.clickTable('T2');
ProductScreen.do.clickSplitBillButton();
SplitBillScreen.do.clickOrderline('Water');
SplitBillScreen.do.clickOrderline('Coca-Cola');
SplitBillScreen.do.clickPay();
PaymentScreen.do.clickBack();
Chrome.do.clickTicketButton();
TicketScreen.do.selectOrder('-0002');
ProductScreen.do.clickOrderline('Water', '1.0');
ProductScreen.do.clickOrderline('Coca-Cola', '1.0');
ProductScreen.check.totalAmountIs('4.40');
Chrome.do.clickTicketButton();
TicketScreen.do.selectOrder('-0001');
ProductScreen.do.clickOrderline('Minute Maid', '1.0');
ProductScreen.check.totalAmountIs('2.20');
Tour.register('SplitBillScreenTour2', { test: true, url: '/pos/ui' }, getSteps());
});

View file

@ -0,0 +1,63 @@
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');
ProductScreen.do.confirmOpeningPopup();
ProductScreen.check.isShown();
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.isShown();
ProductScreen.check.totalAmountIs('2.0');
Chrome.check.backToFloorTextIs('Main Floor', 'T2');
Chrome.do.backToFloor();
// Make sure that order is deleted properly.
FloorScreen.do.clickTable('T5');
ProductScreen.exec.addOrderline('Minute Maid', '1', '3');
ProductScreen.check.totalAmountIs('3.0');
Chrome.do.backToFloor();
FloorScreen.check.orderCountSyncedInTableIs('T5', '1');
Chrome.do.clickTicketButton();
TicketScreen.do.deleteOrder('-0004');
Chrome.do.confirmPopup();
TicketScreen.do.clickDiscard();
FloorScreen.check.isShown();
FloorScreen.check.orderCountSyncedInTableIs('T5', '0');
FloorScreen.do.clickTable('T5');
ProductScreen.check.orderIsEmpty();
Tour.register('PosResTicketScreenTour', { test: true, url: '/pos/ui' }, getSteps());
});

View file

@ -0,0 +1,127 @@
odoo.define('pos_restaurant.tour.TipScreen', function (require) {
'use strict';
const { ProductScreen } = require('point_of_sale.tour.ProductScreenTourMethods');
const { PaymentScreen } = require('point_of_sale.tour.PaymentScreenTourMethods');
const { ReceiptScreen } = require('point_of_sale.tour.ReceiptScreenTourMethods');
const { FloorScreen } = require('pos_restaurant.tour.FloorScreenTourMethods');
const { TicketScreen } = require('point_of_sale.tour.TicketScreenTourMethods');
const { TipScreen } = require('pos_restaurant.tour.TipScreenTourMethods');
const { NumberPopup } = require('point_of_sale.tour.NumberPopupTourMethods');
const { Chrome } = require('pos_restaurant.tour.ChromeTourMethods');
const { getSteps, startSteps } = require('point_of_sale.tour.utils');
var Tour = require('web_tour.tour');
startSteps();
// Create order that is synced when draft.
// order 1
FloorScreen.do.clickTable('T2');
ProductScreen.do.confirmOpeningPopup();
ProductScreen.exec.addOrderline('Minute Maid', '1', '2');
ProductScreen.check.totalAmountIs('2.0');
Chrome.do.backToFloor();
FloorScreen.check.orderCountSyncedInTableIs('T2', '1');
FloorScreen.do.clickTable('T2');
ProductScreen.check.totalAmountIs('2.0');
ProductScreen.do.clickPayButton();
PaymentScreen.do.clickPaymentMethod('Bank');
PaymentScreen.do.clickValidate();
TipScreen.check.isShown();
Chrome.do.clickTicketButton();
TicketScreen.do.clickNewTicket();
// order 2
ProductScreen.exec.addOrderline('Coca-Cola', '2', '2');
ProductScreen.check.totalAmountIs('4.0');
Chrome.do.backToFloor();
FloorScreen.check.orderCountSyncedInTableIs('T2', '1');
Chrome.do.clickTicketButton();
TicketScreen.check.nthRowContains('2', 'Tipping');
TicketScreen.do.clickDiscard();
// Create without syncing the draft.
// order 3
FloorScreen.do.clickTable('T5');
ProductScreen.exec.addOrderline('Minute Maid', '3', '2');
ProductScreen.check.totalAmountIs('6.0');
ProductScreen.do.clickPayButton();
PaymentScreen.do.clickPaymentMethod('Bank');
PaymentScreen.do.clickValidate();
TipScreen.check.isShown();
Chrome.do.clickTicketButton();
TicketScreen.do.clickNewTicket();
// order 4
ProductScreen.exec.addOrderline('Coca-Cola', '4', '2');
ProductScreen.check.totalAmountIs('8.0');
Chrome.do.backToFloor();
FloorScreen.check.orderCountSyncedInTableIs('T5', '1');
Chrome.do.clickTicketButton();
TicketScreen.check.nthRowContains('3', 'Tipping');
// Tip 20% on order1
TicketScreen.do.selectOrder('-0001');
TipScreen.check.isShown();
TipScreen.check.totalAmountIs('2.0');
TipScreen.check.percentAmountIs('15%', '0.30');
TipScreen.check.percentAmountIs('20%', '0.40');
TipScreen.check.percentAmountIs('25%', '0.50');
TipScreen.do.clickPercentTip('20%');
TipScreen.check.inputAmountIs('0.40')
Chrome.do.backToFloor();
FloorScreen.check.isShown();
Chrome.do.clickTicketButton();
// Tip 25% on order3
TicketScreen.do.selectOrder('-0003');
TipScreen.check.isShown();
TipScreen.check.totalAmountIs('6.0');
TipScreen.check.percentAmountIs('15%', '0.90');
TipScreen.check.percentAmountIs('20%', '1.20');
TipScreen.check.percentAmountIs('25%', '1.50');
TipScreen.do.clickPercentTip('25%');
TipScreen.check.inputAmountIs('1.50');
Chrome.do.backToFloor();
FloorScreen.check.isShown();
Chrome.do.clickTicketButton();
// finalize order 4 then tip custom amount
TicketScreen.do.selectOrder('-0004');
ProductScreen.check.isShown();
ProductScreen.check.totalAmountIs('8.0');
ProductScreen.do.clickPayButton();
PaymentScreen.do.clickPaymentMethod('Bank');
PaymentScreen.do.clickValidate();
TipScreen.check.isShown();
TipScreen.check.totalAmountIs('8.0');
TipScreen.check.percentAmountIs('15%', '1.20');
TipScreen.check.percentAmountIs('20%', '1.60');
TipScreen.check.percentAmountIs('25%', '2.00');
TipScreen.do.setCustomTip('1.00');
TipScreen.check.inputAmountIs('1.00')
Chrome.do.backToFloor();
FloorScreen.check.isShown();
// settle tips here
Chrome.do.clickTicketButton();
TicketScreen.do.selectFilter('Tipping');
TicketScreen.check.tipContains('1.00');
TicketScreen.do.settleTips();
TicketScreen.do.selectFilter('All active orders');
TicketScreen.check.nthRowContains(2, 'Ongoing');
// tip order2 during payment
// tip screen should not show after validating payment screen
TicketScreen.do.selectOrder('-0002');
ProductScreen.check.isShown();
ProductScreen.do.clickPayButton();
PaymentScreen.do.clickTipButton();
NumberPopup.check.isShown();
NumberPopup.do.pressNumpad('1');
NumberPopup.check.inputShownIs('1');
NumberPopup.do.clickConfirm();
PaymentScreen.do.clickPaymentMethod('Cash');
PaymentScreen.do.clickValidate();
ReceiptScreen.check.isShown();
Tour.register('PosResTipScreenTour', { test: true, url: '/pos/ui' }, getSteps());
});

View file

@ -0,0 +1,56 @@
odoo.define('pos_restaurant.tour.BillScreenTourMethods', function (require) {
'use strict';
const { createTourMethods } = require('point_of_sale.tour.utils');
class Do {
clickOk() {
return [
{
content: `go back`,
trigger: `.receipt-screen .button.next`,
},
];
}
clickBillButton() {
return [
{
content: "click bill button",
trigger: '.control-button:contains("Bill")',
},
];
}
}
class Check {
isShown() {
return [
{
content: 'Bill screen is shown',
trigger: '.receipt-screen h1:contains("Bill Printing")',
run: () => {},
},
];
}
isQRCodeShown() {
return [
{
content: "QR codes are shown",
trigger: '#posqrcode',
run: () => {},
},
];
}
isQRCodeNotShown() {
return [
{
content: "QR codes are shown",
trigger: 'body:not(:has(#posqrcode))',
run: () => {},
},
];
}
}
return createTourMethods('BillScreen', Do, Check);
});

View file

@ -0,0 +1,33 @@
odoo.define('pos_restaurant.tour.ChromeTourMethods', function (require) {
'use strict';
const { createTourMethods } = require('point_of_sale.tour.utils');
const { Do } = require('point_of_sale.tour.ChromeTourMethods');
class DoExt extends Do {
backToFloor() {
return [
{
content: 'back to floor',
trigger: '.floor-button',
},
];
}
}
class Check {
backToFloorTextIs(floor, table) {
return [
{
content: `back to floor text is '${floor} ( ${table} )'`,
trigger: `.floor-button span:contains("${floor}") ~ .table-name:contains("(${table})")`,
run: () => {},
},
];
}
}
class Execute {}
return createTourMethods('Chrome', DoExt, Check, Execute);
});

View file

@ -0,0 +1,157 @@
odoo.define('pos_restaurant.tour.FloorScreenTourMethods', function (require) {
'use strict';
const { createTourMethods } = require('point_of_sale.tour.utils');
class Do {
clickTable(name) {
return [
{
content: `click table '${name}'`,
trigger: `.floor-map .table .label:contains("${name}")`,
},
];
}
clickFloor(name) {
return [
{
content: `click '${name}' floor`,
trigger: `.floor-selector .button-floor:contains("${name}")`,
},
];
}
clickEdit() {
return [
{
content: `click edit button`,
trigger: `.floor-map .edit-button`,
},
];
}
clickAddTable() {
return [
{
content: 'add table',
trigger: `.floor-map .edit-button i[aria-label=Add]`,
},
];
}
clickDuplicate() {
return [
{
content: 'duplicate table',
trigger: `.floor-map .edit-button i[aria-label=Duplicate]`,
},
];
}
clickRename() {
return [
{
content: 'rename table',
trigger: `.floor-map .edit-button i[aria-label=Rename]`,
},
];
}
clickSeats() {
return [
{
content: 'change number of seats',
trigger: `.floor-map .edit-button i[aria-label=Seats]`,
},
];
}
clickTrash() {
return [
{
content: 'trash table',
trigger: `.floor-map .edit-button.trash`,
},
];
}
changeShapeTo(shape) {
return [
{
content: `change shape to '${shape}'`,
trigger: `.edit-button .button-option${shape === 'round' ? '.square' : '.round'}`,
},
];
}
}
class Check {
selectedFloorIs(name) {
return [
{
content: `selected floor is '${name}'`,
trigger: `.floor-selector .button-floor.active:contains("${name}")`,
run: () => {},
},
];
}
selectedTableIs(name) {
return [
{
content: `selected table is '${name}'`,
trigger: `.floor-map .table.selected .label:contains("${name}")`,
run: () => {},
},
];
}
hasTable(name) {
return [
{
content: `selected floor has '${name}' table`,
trigger: `.floor-map .tables .table .label:contains("${name}")`,
run: () => {},
},
];
}
editModeIsActive(flag) {
return [
{
content: `check if edit mode is ${flag ? 'active' : 'inactive'}`,
trigger: `.floor-map .edit-button${flag ? '.active' : ':not(:has(.active))'}`,
run: () => {},
},
];
}
tableSeatIs(table, val) {
return [
{
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 () {},
},
];
}
tableIsNotSelected(name) {
return [
{
content: `table '${name}' is not selected`,
trigger: `.floor-map .table:not(.selected) .label:contains("${name}")`,
run: function () {},
},
];
}
}
class Execute {}
return createTourMethods('FloorScreen', Do, Check, Execute);
});

View file

@ -0,0 +1,87 @@
odoo.define('pos_restaurant.tour.ProductScreenTourMethods', function (require) {
'use strict';
const { createTourMethods } = require('point_of_sale.tour.utils');
const { Do, Check, Execute } = require('point_of_sale.tour.ProductScreenTourMethods');
class DoExt extends Do {
clickSplitBillButton() {
return [
{
content: 'click split bill button',
trigger: '.control-buttons .control-button.order-split',
},
];
}
clickTransferButton() {
return [
{
content: 'click transfer button',
trigger: '.control-buttons .control-button span:contains("Transfer")',
},
];
}
clickNoteButton() {
return [
{
content: 'click note button',
trigger: '.control-buttons .control-button span:contains("Internal Note")',
},
];
}
clickPrintBillButton() {
return [
{
content: 'click print bill button',
trigger: '.control-buttons .control-button.order-printbill',
},
];
}
clickSubmitButton() {
return [
{
content: 'click print bill button',
trigger: '.control-buttons .control-button span:contains("Order")',
},
];
}
clickGuestButton() {
return [
{
content: 'click guest button',
trigger: '.control-buttons .control-button span:contains("Guests")'
}
]
}
}
class CheckExt extends Check {
orderlineHasNote(name, quantity, note) {
return [
{
content: `line has ${quantity} quantity`,
trigger: `.order .orderline .product-name:contains("${name}") ~ .info-list em:contains("${quantity}")`,
run: function () {}, // it's a check
},
{
content: `line has '${note}' note`,
trigger: `.order .orderline .info-list .orderline-note:contains("${note}")`,
run: function () {}, // it's a check
},
];
}
guestNumberIs(numberInString) {
return [
{
content: `guest number is ${numberInString}`,
trigger: `.control-buttons .control-button span.control-button-number:contains(${numberInString})`,
run: function () {}, // it's a check
}
]
}
}
class ExecuteExt extends Execute {}
return createTourMethods('ProductScreen', DoExt, CheckExt, ExecuteExt);
});

View file

@ -0,0 +1,65 @@
odoo.define('pos_restaurant.tour.SplitBillScreenTourMethods', function (require) {
'use strict';
const { createTourMethods } = require('point_of_sale.tour.utils');
class Do {
clickOrderline(name, totalQuantity) {
let trigger = `li.orderline .product-name:contains("${name}")`;
if (totalQuantity) {
trigger += ` ~ .info-list .info:contains("${totalQuantity}")`;
}
return [
{
content: `click '${name}' orderline with total quantity of '${totalQuantity}'`,
trigger,
},
];
}
clickBack() {
return [
{
content: 'click back button',
trigger: `.splitbill-screen .button.back`,
},
];
}
clickPay() {
return [
{
content: 'click pay button',
trigger: `.splitbill-screen .pay-button .button`
}
]
}
}
class Check {
orderlineHas(name, totalQuantity, splitQuantity) {
return [
{
content: `'${name}' orderline has total quantity of '${totalQuantity}'`,
trigger: `li.orderline .product-name:contains("${name}") ~ .info-list .info:contains("${totalQuantity}")`,
run: () => {},
},
{
content: `'${name}' orderline has '${splitQuantity}' quantity to split`,
trigger: `li.orderline .product-name:contains("${name}") ~ .info-list .info em:contains("${splitQuantity}")`,
run: () => {},
},
];
}
subtotalIs(amount) {
return [
{
content: `total amount of split is '${amount}'`,
trigger: `.splitbill-screen .order-info .subtotal:contains("${amount}")`,
},
];
}
}
class Execute {}
return createTourMethods('SplitBillScreen', Do, Check, Execute);
});

View file

@ -0,0 +1,60 @@
odoo.define('pos_restaurant.tour.TipScreenTourMethods', function (require) {
'use strict';
const { createTourMethods } = require('point_of_sale.tour.utils');
class Do {
clickPercentTip(percent) {
return [
{
trigger: `.tip-screen .percentage:contains("${percent}")`,
},
];
}
setCustomTip(amount) {
return [
{
trigger: `.tip-screen .custom-amount-form input`,
run: `text ${amount}`,
},
];
}
}
class Check {
isShown() {
return [
{
trigger: '.pos .tip-screen',
run: () => {},
},
];
}
totalAmountIs(amount) {
return [
{
trigger: `.tip-screen .total-amount:contains("${amount}")`,
run: () => {},
},
];
}
percentAmountIs(percent, amount) {
return [
{
trigger: `.tip-screen .percentage:contains("${percent}") ~ .amount:contains("${amount}")`,
run: () => {},
},
];
}
inputAmountIs(amount) {
return [
{
trigger: `.tip-screen .custom-amount-form input[data-amount="${amount}"]`,
run: () => {},
}
]
}
}
return createTourMethods('TipScreen', Do, Check);
});

View file

@ -0,0 +1,126 @@
odoo.define('pos_reataurant.tour.synchronized_table_management', function (require) {
'use strict';
const { BillScreen } = require('pos_restaurant.tour.BillScreenTourMethods');
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.confirmOpeningPopup();
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/ui' }, getSteps());
startSteps();
/* pos_restaurant_sync_second_login
*
* This tour should be run after the first tour is done.
*/
// 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
ProductScreen.do.clickTransferButton();
FloorScreen.do.clickTable('T4');
// Test if products still get merged after transfering the order
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/ui' }, getSteps());
startSteps();
ProductScreen.do.confirmOpeningPopup();
FloorScreen.do.clickTable("5");
ProductScreen.do.clickDisplayedProduct("Coca-Cola");
BillScreen.do.clickBillButton();
BillScreen.check.isShown();
BillScreen.check.isQRCodeNotShown();
BillScreen.do.clickOk();
ProductScreen.do.clickPayButton();
PaymentScreen.do.clickPaymentMethod("Bank");
PaymentScreen.do.clickValidate();
BillScreen.check.isQRCodeShown();
Tour.register('BillScreenTour', { test: true, url: '/pos/ui' }, getSteps());
});

View file

@ -0,0 +1,45 @@
odoo.define('pos_restaurant.tour.Refund', function (require) {
'use strict';
const { PaymentScreen } = require('point_of_sale.tour.PaymentScreenTourMethods');
const { FloorScreen } = require('pos_restaurant.tour.FloorScreenTourMethods');
const { ProductScreen } = require('pos_restaurant.tour.ProductScreenTourMethods');
const { TicketScreen } = require('point_of_sale.tour.TicketScreenTourMethods');
const { ReceiptScreen } = require('point_of_sale.tour.ReceiptScreenTourMethods');
const { getSteps, startSteps } = require('point_of_sale.tour.utils');
var Tour = require('web_tour.tour');
// signal to start generating steps
// when finished, steps can be taken from getSteps
startSteps();
// Create first order and pay it
FloorScreen.do.clickTable("T2");
ProductScreen.do.confirmOpeningPopup();
ProductScreen.do.clickDisplayedProduct("Coca-Cola");
ProductScreen.check.selectedOrderlineHas("Coca-Cola");
ProductScreen.do.clickDisplayedProduct("Coca-Cola");
ProductScreen.check.selectedOrderlineHas("Coca-Cola");
ProductScreen.do.clickDisplayedProduct("Water");
ProductScreen.check.selectedOrderlineHas("Water");
ProductScreen.check.totalAmountIs("6.60");
ProductScreen.do.clickPayButton();
PaymentScreen.do.clickPaymentMethod("Cash");
PaymentScreen.do.clickValidate();
ReceiptScreen.do.clickNextOrder();
// Go to another table and refund one of the product
FloorScreen.do.clickTable("T4");
ProductScreen.check.orderIsEmpty();
ProductScreen.do.clickRefund();
TicketScreen.do.selectOrder("-0001");
TicketScreen.do.clickOrderline("Coca-Cola");
TicketScreen.do.pressNumpad("2");
TicketScreen.check.toRefundTextContains("To Refund: 2.00");
TicketScreen.do.confirmRefund();
ProductScreen.check.isShown();
ProductScreen.check.selectedOrderlineHas("Coca-Cola");
ProductScreen.check.totalAmountIs("-4.40");
Tour.register('RefundStayCurrentTableTour', { test: true, url: '/pos/ui' }, getSteps());
});