diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (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.js | 197 |
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; +}); |
