summaryrefslogtreecommitdiff
path: root/addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js')
-rw-r--r--addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js197
1 files changed, 197 insertions, 0 deletions
diff --git a/addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js b/addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js
new file mode 100644
index 00000000..f44af5bf
--- /dev/null
+++ b/addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js
@@ -0,0 +1,197 @@
+odoo.define('pos_restaurant.SplitBillScreen', function(require) {
+ 'use strict';
+
+ const PosComponent = require('point_of_sale.PosComponent');
+ const { useState } = owl.hooks;
+ const { useListener } = require('web.custom_hooks');
+ const models = require('point_of_sale.models');
+ const Registries = require('point_of_sale.Registries');
+
+ class SplitBillScreen extends PosComponent {
+ constructor() {
+ super(...arguments);
+ useListener('click-line', this.onClickLine);
+ this.splitlines = useState(this._initSplitLines(this.env.pos.get_order()));
+ this.newOrderLines = {};
+ this.newOrder = new models.Order(
+ {},
+ {
+ pos: this.env.pos,
+ temporary: true,
+ }
+ );
+ this._isFinal = false;
+ }
+ mounted() {
+ this.env.pos.on('change:selectedOrder', this._resetState, this);
+ }
+ willUnmount() {
+ this.env.pos.off('change:selectedOrder', null, this);
+ }
+ get currentOrder() {
+ return this.env.pos.get_order();
+ }
+ get orderlines() {
+ return this.currentOrder.get_orderlines();
+ }
+ onClickLine(event) {
+ const line = event.detail;
+ this._splitQuantity(line);
+ this._updateNewOrder(line);
+ }
+ back() {
+ this.showScreen('ProductScreen');
+ }
+ proceed() {
+ if (_.isEmpty(this.splitlines))
+ // Splitlines is empty
+ return;
+
+ this._isFinal = true;
+ delete this.newOrder.temporary;
+
+ if (this._isFullPayOrder()) {
+ this.showScreen('PaymentScreen');
+ } else {
+ this._setQuantityOnCurrentOrder();
+
+ this.newOrder.set_screen_data({ name: 'PaymentScreen' });
+
+ // for the kitchen printer we assume that everything
+ // has already been sent to the kitchen before splitting
+ // the bill. So we save all changes both for the old
+ // order and for the new one. This is not entirely correct
+ // but avoids flooding the kitchen with unnecessary orders.
+ // Not sure what to do in this case.
+
+ if (this.newOrder.saveChanges) {
+ this.currentOrder.saveChanges();
+ this.newOrder.saveChanges();
+ }
+
+ 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({ name: 'ProductScreen' });
+
+ this.env.pos.get('orders').add(this.newOrder);
+ this.env.pos.set('selectedOrder', this.newOrder);
+ }
+ }
+ /**
+ * @param {models.Order} order
+ * @returns {Object<{ quantity: number }>} splitlines
+ */
+ _initSplitLines(order) {
+ const splitlines = {};
+ for (let line of order.get_orderlines()) {
+ splitlines[line.id] = { product: line.get_product().id, quantity: 0 };
+ }
+ return splitlines;
+ }
+ _splitQuantity(line) {
+ const split = this.splitlines[line.id];
+
+ let totalQuantity = 0;
+
+ this.env.pos.get_order().get_orderlines().forEach(function(orderLine) {
+ if(orderLine.get_product().id === split.product)
+ totalQuantity += orderLine.get_quantity();
+ });
+
+ if(line.get_quantity() > 0) {
+ if (!line.get_unit().is_pos_groupable) {
+ if (split.quantity !== line.get_quantity()) {
+ split.quantity = line.get_quantity();
+ } else {
+ split.quantity = 0;
+ }
+ } else {
+ if (split.quantity < totalQuantity) {
+ split.quantity += line.get_unit().is_pos_groupable? 1: line.get_unit().rounding;
+ if (split.quantity > line.get_quantity()) {
+ split.quantity = line.get_quantity();
+ }
+ } else {
+ split.quantity = 0;
+ }
+ }
+ }
+ }
+ _updateNewOrder(line) {
+ const split = this.splitlines[line.id];
+ let orderline = this.newOrderLines[line.id];
+ if (split.quantity) {
+ if (!orderline) {
+ orderline = line.clone();
+ this.newOrder.add_orderline(orderline);
+ this.newOrderLines[line.id] = orderline;
+ }
+ orderline.set_quantity(split.quantity, 'do not recompute unit price');
+ } else if (orderline) {
+ this.newOrder.remove_orderline(orderline);
+ this.newOrderLines[line.id] = null;
+ }
+ }
+ _isFullPayOrder() {
+ let order = this.env.pos.get_order();
+ let full = true;
+ let splitlines = this.splitlines;
+ let groupedLines = _.groupBy(order.get_orderlines(), line => line.get_product().id);
+
+ Object.keys(groupedLines).forEach(function (lineId) {
+ var maxQuantity = groupedLines[lineId].reduce(((quantity, line) => quantity + line.get_quantity()), 0);
+ Object.keys(splitlines).forEach(id => {
+ let split = splitlines[id];
+ if(split.product === groupedLines[lineId][0].get_product().id)
+ maxQuantity -= split.quantity;
+ });
+ if(maxQuantity !== 0)
+ full = false;
+ });
+
+ return full;
+ }
+ _setQuantityOnCurrentOrder() {
+ let order = this.env.pos.get_order();
+ for (var id in this.splitlines) {
+ var split = this.splitlines[id];
+ var line = this.currentOrder.get_orderline(parseInt(id));
+
+ if(!this.props.disallow) {
+ line.set_quantity(
+ line.get_quantity() - split.quantity,
+ 'do not recompute unit price'
+ );
+ if (Math.abs(line.get_quantity()) < 0.00001) {
+ this.currentOrder.remove_orderline(line);
+ }
+ } else {
+ if(split.quantity) {
+ let decreaseLine = line.clone();
+ decreaseLine.order = order;
+ decreaseLine.noDecrease = true;
+ decreaseLine.set_quantity(-split.quantity);
+ order.add_orderline(decreaseLine);
+ }
+ }
+ }
+ }
+ _resetState() {
+ if (this._isFinal) return;
+
+ for (let id in this.splitlines) {
+ delete this.splitlines[id];
+ }
+ for (let line of this.currentOrder.get_orderlines()) {
+ this.splitlines[line.id] = { quantity: 0 };
+ }
+ this.newOrder.orderlines.reset();
+ }
+ }
+ SplitBillScreen.template = 'SplitBillScreen';
+
+ Registries.Component.add(SplitBillScreen);
+
+ return SplitBillScreen;
+});