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/point_of_sale/static/src/js/custom_hooks.js | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/point_of_sale/static/src/js/custom_hooks.js')
| -rw-r--r-- | addons/point_of_sale/static/src/js/custom_hooks.js | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/addons/point_of_sale/static/src/js/custom_hooks.js b/addons/point_of_sale/static/src/js/custom_hooks.js new file mode 100644 index 00000000..c1e87b24 --- /dev/null +++ b/addons/point_of_sale/static/src/js/custom_hooks.js @@ -0,0 +1,149 @@ +odoo.define('point_of_sale.custom_hooks', function (require) { + 'use strict'; + + const { Component } = owl; + const { onMounted, onPatched, onWillUnmount } = owl.hooks; + + /** + * Introduce error handlers in the component. + * + * IMPROVEMENT: This is a terrible hook. There could be a better way to handle + * the error when the order failed to sync. + */ + function useErrorHandlers() { + const component = Component.current; + + component._handlePushOrderError = async function (error) { + // This error handler receives `error` equivalent to `error.message` of the rpc error. + if (error.message === 'Backend Invoice') { + await this.showPopup('ConfirmPopup', { + title: this.env._t('Please print the invoice from the backend'), + body: + this.env._t( + 'The order has been synchronized earlier. Please make the invoice from the backend for the order: ' + ) + error.data.order.name, + }); + } else if (error.code < 0) { + // XmlHttpRequest Errors + const title = this.env._t('Unable to sync order'); + const body = this.env._t( + 'Check the internet connection then try to sync again by clicking on the red wifi button (upper right of the screen).' + ); + await this.showPopup('OfflineErrorPopup', { title, body }); + } else if (error.code === 200) { + // OpenERP Server Errors + await this.showPopup('ErrorTracebackPopup', { + title: error.data.message || this.env._t('Server Error'), + body: + error.data.debug || + this.env._t('The server encountered an error while receiving your order.'), + }); + } else if (error.code === 700) { + // Fiscal module errors + await this.showPopup('ErrorPopup', { + title: this.env._t('Fiscal data module error'), + body: + error.data.error.status || + this.env._t('The fiscal data module encountered an error while receiving your order.'), + }); + } else { + // ??? + await this.showPopup('ErrorPopup', { + title: this.env._t('Unknown Error'), + body: this.env._t( + 'The order could not be sent to the server due to an unknown error' + ), + }); + } + }; + } + + function useAutoFocusToLast() { + const current = Component.current; + let target = null; + function autofocus() { + const prevTarget = target; + const allInputs = current.el.querySelectorAll('input'); + target = allInputs[allInputs.length - 1]; + if (target && target !== prevTarget) { + target.focus(); + target.selectionStart = target.selectionEnd = target.value.length; + } + } + onMounted(autofocus); + onPatched(autofocus); + } + + /** + * Use this hook when you want to do something on previously selected and + * newly selected order when the order changes. + * + * Normally, a component is rendered then the current order is changed. When + * this happens, we want to rerender the component because the new information + * should be reflected in the screen. Additionally, we might want to remove listeners + * to the previous order and attach listeners to the new one. This hook is + * perfect for the described situation. + * + * Internally, this hook performs the following: + * 1. call newOrderCB on mounted + * 2. listen to order changes and perform the following sequence: + * - call prevOrderCB(prevOrder) + * - call newOrderCB(newOrder) + * 3. call prevOrderCB on willUnmount + * + * @param {Function} prevOrderCB apply this callback on the previous order + * @param {Function} newOrderCB apply this callback on the new order + */ + function onChangeOrder(prevOrderCB, newOrderCB) { + const current = Component.current; + prevOrderCB = prevOrderCB ? prevOrderCB.bind(current) : () => {}; + newOrderCB = newOrderCB ? newOrderCB.bind(current) : () => {}; + onMounted(() => { + current.env.pos.on( + 'change:selectedOrder', + async (pos, newOrder) => { + await prevOrderCB(pos.previous('selectedOrder')); + await newOrderCB(newOrder); + }, + current + ); + newOrderCB(current.env.pos.get_order()); + }); + onWillUnmount(() => { + current.env.pos.off('change:selectedOrder', null, current); + prevOrderCB(current.env.pos.get_order()); + }); + } + + function useBarcodeReader(callbackMap, exclusive = false) { + const current = Component.current; + const barcodeReader = current.env.pos.barcode_reader; + for (let [key, callback] of Object.entries(callbackMap)) { + callbackMap[key] = callback.bind(current); + } + onMounted(() => { + if (barcodeReader) { + for (let key in callbackMap) { + if (exclusive) { + barcodeReader.set_exclusive_callback(key, callbackMap[key]); + } else { + barcodeReader.set_action_callback(key, callbackMap[key]); + } + } + } + }); + onWillUnmount(() => { + if (barcodeReader) { + for (let key in callbackMap) { + if (exclusive) { + barcodeReader.remove_exclusive_callback(key, callbackMap[key]); + } else { + barcodeReader.remove_action_callback(key, callbackMap[key]); + } + } + } + }); + } + + return { useErrorHandlers, useAutoFocusToLast, onChangeOrder, useBarcodeReader }; +}); |
