summaryrefslogtreecommitdiff
path: root/addons/point_of_sale/static/src/js/custom_hooks.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/point_of_sale/static/src/js/custom_hooks.js
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (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.js149
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 };
+});