diff --git a/addons/l10n_ae_pos/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml b/addons/l10n_ae_pos/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml index b18b043abac..3ec842972ab 100644 --- a/addons/l10n_ae_pos/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml +++ b/addons/l10n_ae_pos/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml @@ -3,7 +3,7 @@
- VAT + VAT Total Taxes
diff --git a/addons/l10n_co_pos/static/src/js/PaymentScreen.js b/addons/l10n_co_pos/static/src/js/PaymentScreen.js index 279d756b0c1..d091c625a55 100644 --- a/addons/l10n_co_pos/static/src/js/PaymentScreen.js +++ b/addons/l10n_co_pos/static/src/js/PaymentScreen.js @@ -7,7 +7,7 @@ patch(PaymentScreen.prototype, "l10n_co_pos.PaymentScreen", { async _postPushOrderResolve(order, order_server_ids) { const _super = this._super; try { - if (this.env.pos.is_colombian_country()) { + if (this.pos.globalState.is_colombian_country()) { const result = await this.orm.searchRead( "pos.order", [["id", "in", order_server_ids]], diff --git a/addons/l10n_fr_pos_cert/static/src/js/Chrome.js b/addons/l10n_fr_pos_cert/static/src/js/Chrome.js index 10a37002fcd..8785c136e80 100644 --- a/addons/l10n_fr_pos_cert/static/src/js/Chrome.js +++ b/addons/l10n_fr_pos_cert/static/src/js/Chrome.js @@ -9,12 +9,13 @@ patch(Chrome.prototype, "l10n_fr_pos_cert.Chrome", { setup() { this._super(...arguments); onMounted(async () => { - if (this.env.pos.is_french_country() && this.env.pos.pos_session.start_at) { + const { globalState } = this.pos; + if (globalState.is_french_country() && globalState.pos_session.start_at) { const now = Date.now(); - const limitDate = new Date(this.env.pos.pos_session.start_at); + const limitDate = new Date(globalState.pos_session.start_at); limitDate.setDate(limitDate.getDate() + 1); if (limitDate.getTime() < now) { - const info = await this.env.pos.getClosePosInfo(); + const info = await globalState.getClosePosInfo(); this.popup.add(ClosePosPopup, { info }); } } diff --git a/addons/l10n_fr_pos_cert/static/src/js/PaymentScreen.js b/addons/l10n_fr_pos_cert/static/src/js/PaymentScreen.js index 1ec6539ca03..a78e3847276 100644 --- a/addons/l10n_fr_pos_cert/static/src/js/PaymentScreen.js +++ b/addons/l10n_fr_pos_cert/static/src/js/PaymentScreen.js @@ -7,7 +7,7 @@ patch(PaymentScreen.prototype, "l10n_fr_pos_cert.PaymentScreen", { async _postPushOrderResolve(order, order_server_ids) { const _super = this._super; try { - if (this.env.pos.is_french_country()) { + if (this.pos.globalState.is_french_country()) { const result = await this.orm.searchRead( "pos.order", [["id", "in", order_server_ids]], diff --git a/addons/l10n_fr_pos_cert/static/src/xml/Orderline.xml b/addons/l10n_fr_pos_cert/static/src/xml/Orderline.xml index 49420409f77..ef790a1be8a 100644 --- a/addons/l10n_fr_pos_cert/static/src/xml/Orderline.xml +++ b/addons/l10n_fr_pos_cert/static/src/xml/Orderline.xml @@ -3,7 +3,7 @@ - +
  • Old unit price: diff --git a/addons/l10n_gcc_pos/static/src/xml/OrderReceipt.xml b/addons/l10n_gcc_pos/static/src/xml/OrderReceipt.xml index 88fa1fbc571..ae30b96d2eb 100644 --- a/addons/l10n_gcc_pos/static/src/xml/OrderReceipt.xml +++ b/addons/l10n_gcc_pos/static/src/xml/OrderReceipt.xml @@ -114,7 +114,7 @@
    - + x diff --git a/addons/l10n_in_pos/static/src/xml/pos_receipt.xml b/addons/l10n_in_pos/static/src/xml/pos_receipt.xml index ea461cc9d7d..3402f545ab7 100644 --- a/addons/l10n_in_pos/static/src/xml/pos_receipt.xml +++ b/addons/l10n_in_pos/static/src/xml/pos_receipt.xml @@ -2,7 +2,7 @@ - +
    @@ -19,7 +19,7 @@ - +
    HSN Code: diff --git a/addons/point_of_sale/static/src/app/debug/debug_widget.js b/addons/point_of_sale/static/src/app/debug/debug_widget.js index ac3b0e03ae8..bcada4e2630 100644 --- a/addons/point_of_sale/static/src/app/debug/debug_widget.js +++ b/addons/point_of_sale/static/src/app/debug/debug_widget.js @@ -8,6 +8,7 @@ import { OrderImportPopup } from "@point_of_sale/js/Popups/OrderImportPopup"; import { useBus, useService } from "@web/core/utils/hooks"; import { useEffect, useRef, useState, Component } from "@odoo/owl"; +import { usePos } from "../pos_hook"; export class DebugWidget extends Component { static components = { Transition }; @@ -15,6 +16,7 @@ export class DebugWidget extends Component { static props = { state: { type: Object, shape: { showWidget: Boolean } } }; setup() { super.setup(); + this.pos = usePos(); this.debug = useService("debug"); this.popup = useService("popup"); this.barcodeReader = useService("barcode_reader"); @@ -29,11 +31,11 @@ export class DebugWidget extends Component { buffer: numberBuffer.get(), }); this.root = useRef("root"); - this.pos = useState({ left: null, top: null }); + this.position = useState({ left: null, top: null }); useEffect( (root) => { - this.pos.left = root?.offsetLeft; - this.pos.top = root?.offsetTop; + this.position.left = root?.offsetLeft; + this.position.top = root?.offsetTop; }, () => [this.root.el] ); @@ -41,12 +43,12 @@ export class DebugWidget extends Component { useMovable({ ref: this.root, onMoveStart: () => { - posBeforeMove = { ...this.pos }; + posBeforeMove = { ...this.position }; }, onMove: ({ dx, dy }) => { const { minX, minY, maxX, maxY } = getLimits(this.root.el, document.body); - this.pos.left = constrain(posBeforeMove.left + dx, minX, maxX); - this.pos.top = constrain(posBeforeMove.top + dy, minY, maxY); + this.position.left = constrain(posBeforeMove.left + dx, minX, maxX); + this.position.top = constrain(posBeforeMove.top + dy, minY, maxY); }, }); @@ -96,8 +98,8 @@ export class DebugWidget extends Component { ), }); if (confirmed) { - this.env.pos.db.remove_all_orders(); - this.env.pos.set_synch("connected", 0); + this.pos.globalState.db.remove_all_orders(); + this.pos.globalState.set_synch("connected", 0); } } async deleteUnpaidOrders() { @@ -108,7 +110,7 @@ export class DebugWidget extends Component { ), }); if (confirmed) { - this.env.pos.db.remove_all_unpaid_orders(); + this.pos.globalState.db.remove_all_unpaid_orders(); window.location = "/"; } } @@ -122,7 +124,7 @@ export class DebugWidget extends Component { // The implementation can be better. preparePaidOrders() { try { - this.paidOrdersBlob = this._createBlob(this.env.pos.export_paid_orders()); + this.paidOrdersBlob = this._createBlob(this.pos.globalState.export_paid_orders()); this.state.isPaidOrdersReady = true; } catch (error) { console.warn(error); @@ -138,7 +140,7 @@ export class DebugWidget extends Component { // FIXME POSREF why is this two steps? prepareUnpaidOrders() { try { - this.unpaidOrdersBlob = this._createBlob(this.env.pos.export_unpaid_orders()); + this.unpaidOrdersBlob = this._createBlob(this.pos.globalState.export_unpaid_orders()); this.state.isUnpaidOrdersReady = true; } catch (error) { console.warn(error); @@ -154,7 +156,7 @@ export class DebugWidget extends Component { async importOrders(event) { const file = event.target.files[0]; if (file) { - const report = this.env.pos.import_orders(await file.text()); + const report = this.pos.globalState.import_orders(await file.text()); await this.popup.add(OrderImportPopup, { report }); } } @@ -168,7 +170,7 @@ export class DebugWidget extends Component { return `"${this.state.buffer}"`; } get style() { - const { left, top } = this.pos; + const { left, top } = this.position; return top === null ? "" : `position: absolute; left: ${left}px; top: ${top}px;`; } } diff --git a/addons/point_of_sale/static/src/app/navbar/navbar.js b/addons/point_of_sale/static/src/app/navbar/navbar.js index 1f5b33e5ff1..00829589067 100644 --- a/addons/point_of_sale/static/src/app/navbar/navbar.js +++ b/addons/point_of_sale/static/src/app/navbar/navbar.js @@ -46,7 +46,7 @@ export class Navbar extends Component { } get customerFacingDisplayButtonIsShown() { - return this.env.pos.config.iface_customer_facing_display; + return this.pos.globalState.config.iface_customer_facing_display; } onCashMoveButtonClick() { @@ -58,14 +58,15 @@ export class Navbar extends Component { this.pos.closeScreen(); } else { if (this._shouldLoadOrders()) { + const { globalState } = this.pos; try { - this.env.pos.setLoadingOrderState(true); - const message = await this.env.pos._syncAllOrdersFromServer(); + globalState.setLoadingOrderState(true); + const message = await globalState._syncAllOrdersFromServer(); if (message) { this.notification.add(message, 5000); } } finally { - this.env.pos.setLoadingOrderState(false); + globalState.setLoadingOrderState(false); this.pos.showScreen("TicketScreen"); } } else { @@ -75,7 +76,7 @@ export class Navbar extends Component { } _shouldLoadOrders() { - return this.env.pos.config.trusted_config_ids.length > 0; + return this.pos.globalState.config.trusted_config_ids.length > 0; } get isTicketScreenShown() { @@ -83,11 +84,7 @@ export class Navbar extends Component { } get orderCount() { - // FIXME POSREF: can this condition ever be false? - if (this.env.pos) { - return this.env.pos.get_order_list().length; - } - return 0; + return this.pos.globalState.get_order_list().length; } isBurgerMenuClosed() { diff --git a/addons/point_of_sale/static/src/app/navbar/navbar.xml b/addons/point_of_sale/static/src/app/navbar/navbar.xml index 5c692b92ba7..2fad487fa80 100644 --- a/addons/point_of_sale/static/src/app/navbar/navbar.xml +++ b/addons/point_of_sale/static/src/app/navbar/navbar.xml @@ -11,7 +11,7 @@
    - +
    diff --git a/addons/point_of_sale/static/src/js/Chrome.js b/addons/point_of_sale/static/src/js/Chrome.js index dce34977ad0..ab1854ecf13 100644 --- a/addons/point_of_sale/static/src/js/Chrome.js +++ b/addons/point_of_sale/static/src/js/Chrome.js @@ -1,7 +1,6 @@ /** @odoo-module */ import { useService } from "@web/core/utils/hooks"; -import { batched } from "@point_of_sale/js/utils"; import { throttleForAnimation } from "@web/core/utils/timing"; import { Transition } from "@web/core/transition"; import { MainComponentsContainer } from "@web/core/main_components_container"; @@ -36,16 +35,12 @@ export class Chrome extends Component { get isMobile() { return window.innerWidth <= 768; }, - pos: reactive( - reactivePos, - batched(() => this.render(true)) // FIXME POSREF remove render(true) - ), }); let currentIsMobile = this.env.isMobile; const updateUI = throttleForAnimation(() => { if (this.env.isMobile !== currentIsMobile) { currentIsMobile = this.env.isMobile; - // FIXME POSREF + // FIXME POSREF use reactive mobile instead this.render(true); } }); diff --git a/addons/point_of_sale/static/src/js/ChromeWidgets/CashierName.js b/addons/point_of_sale/static/src/js/ChromeWidgets/CashierName.js index 78345988cdf..c3e1d36f349 100644 --- a/addons/point_of_sale/static/src/js/ChromeWidgets/CashierName.js +++ b/addons/point_of_sale/static/src/js/ChromeWidgets/CashierName.js @@ -1,17 +1,21 @@ /** @odoo-module */ import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; // Previously UsernameWidget export class CashierName extends Component { static template = "CashierName"; + setup() { + this.pos = usePos(); + } get username() { - const { name } = this.env.pos.get_cashier(); + const { name } = this.pos.globalState.get_cashier(); return name ? name : ""; } get avatar() { - const user_id = this.env.pos.get_cashier_user_id(); + const user_id = this.pos.globalState.get_cashier_user_id(); const id = user_id ? user_id : -1; return `/web/image/res.users/${id}/avatar_128`; } diff --git a/addons/point_of_sale/static/src/js/ChromeWidgets/HeaderButton.js b/addons/point_of_sale/static/src/js/ChromeWidgets/HeaderButton.js index 73374baad11..bdb6847a43f 100644 --- a/addons/point_of_sale/static/src/js/ChromeWidgets/HeaderButton.js +++ b/addons/point_of_sale/static/src/js/ChromeWidgets/HeaderButton.js @@ -3,6 +3,7 @@ import { useService } from "@web/core/utils/hooks"; import { ClosePosPopup } from "@point_of_sale/js/Popups/ClosePosPopup"; import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; // Previously HeaderButtonWidget // This is the close session button @@ -11,11 +12,12 @@ export class HeaderButton extends Component { setup() { super.setup(...arguments); + this.pos = usePos(); this.popup = useService("popup"); } async onClick() { - const info = await this.env.pos.getClosePosInfo(); + const info = await this.pos.globalState.getClosePosInfo(); this.popup.add(ClosePosPopup, { info: info, keepBehind: true }); } } diff --git a/addons/point_of_sale/static/src/js/ChromeWidgets/ProxyStatus.js b/addons/point_of_sale/static/src/js/ChromeWidgets/ProxyStatus.js index bd84357755e..6c76b4bfed9 100644 --- a/addons/point_of_sale/static/src/js/ChromeWidgets/ProxyStatus.js +++ b/addons/point_of_sale/static/src/js/ChromeWidgets/ProxyStatus.js @@ -24,7 +24,7 @@ export class ProxyStatus extends Component { iface_print_via_proxy, iface_cashdrawer, iface_electronic_scale, - } = this.env.pos.config; + } = this.pos.globalState.config; const devices = [ { name: _t("Scanner"), diff --git a/addons/point_of_sale/static/src/js/ChromeWidgets/SaleDetailsButton.js b/addons/point_of_sale/static/src/js/ChromeWidgets/SaleDetailsButton.js index fee2b50d0b6..fa7c571b149 100644 --- a/addons/point_of_sale/static/src/js/ChromeWidgets/SaleDetailsButton.js +++ b/addons/point_of_sale/static/src/js/ChromeWidgets/SaleDetailsButton.js @@ -4,31 +4,34 @@ import { useService } from "@web/core/utils/hooks"; import { renderToElement } from "@web/core/utils/render"; import { ErrorPopup } from "../Popups/ErrorPopup"; import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; export class SaleDetailsButton extends Component { static template = "SaleDetailsButton"; setup() { super.setup(...arguments); + this.pos = usePos(); this.popup = useService("popup"); this.orm = useService("orm"); this.hardwareProxy = useService("hardware_proxy"); } async onClick() { + const { globalState } = this.pos; // IMPROVEMENT: Perhaps put this logic in a parent component // so that for unit testing, we can check if this simple // component correctly triggers an event. const saleDetails = await this.orm.call( "report.point_of_sale.report_saledetails", "get_sale_details", - [false, false, false, [this.env.pos.pos_session.id]] + [false, false, false, [globalState.pos_session.id]] ); const report = renderToElement( "SaleDetailsReport", Object.assign({}, saleDetails, { date: new Date().toLocaleString(), - pos: this.env.pos, + pos: globalState, formatCurrency: this.env.utils.formatCurrency, }) ); diff --git a/addons/point_of_sale/static/src/js/ChromeWidgets/SyncNotification.js b/addons/point_of_sale/static/src/js/ChromeWidgets/SyncNotification.js index 3ad8a8a46c4..739b7e8a301 100644 --- a/addons/point_of_sale/static/src/js/ChromeWidgets/SyncNotification.js +++ b/addons/point_of_sale/static/src/js/ChromeWidgets/SyncNotification.js @@ -1,11 +1,18 @@ /** @odoo-module */ import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; export class SyncNotification extends Component { static template = "SyncNotification"; + setup() { + this.pos = usePos(); + } + get sync() { + return this.pos.globalState.synch; + } onClick() { - this.env.pos.push_orders({ show_error: true }); + this.pos.globalState.push_orders({ show_error: true }); } } diff --git a/addons/point_of_sale/static/src/js/ControlButtonsMixin.js b/addons/point_of_sale/static/src/js/ControlButtonsMixin.js index 17dc38cbd25..7afbdb3e43b 100644 --- a/addons/point_of_sale/static/src/js/ControlButtonsMixin.js +++ b/addons/point_of_sale/static/src/js/ControlButtonsMixin.js @@ -27,9 +27,11 @@ export const ControlButtonsMixin = (x) => { * @param {Object} controlButton * @param {new (...args: any[]) => Component} controlButton.component the * component class + * FIXME POSREF: maybe just pass the pos explicitly to allow for arrow functions? + * Should probably refactor this so that it's not a mixin anymore. * @param {Function} controlButton.condition zero argument function that is bound - * to the instance of ProductScreen, such that `this.env.pos` can be used - * inside the function. + * to the instance of ProductScreen. This gives the condition acces to + * the pos store and related object which it may need. * @param {Array} [controlButton.position] array of two elements * [locator, relativeTo] * locator: string -> any of ('before', 'after', 'replace') diff --git a/addons/point_of_sale/static/src/js/Misc/MobileOrderWidget.js b/addons/point_of_sale/static/src/js/Misc/MobileOrderWidget.js index 38d617b8d67..cd5410da5e2 100644 --- a/addons/point_of_sale/static/src/js/Misc/MobileOrderWidget.js +++ b/addons/point_of_sale/static/src/js/Misc/MobileOrderWidget.js @@ -11,7 +11,7 @@ export class MobileOrderWidget extends Component { this.pos = usePos(); } get order() { - return this.env.pos.get_order(); + return this.pos.globalState.get_order(); } get total() { const _total = this.order ? this.order.get_total_with_tax() : 0; diff --git a/addons/point_of_sale/static/src/js/Screens/PartnerListScreen/PartnerDetailsEdit.js b/addons/point_of_sale/static/src/js/Screens/PartnerListScreen/PartnerDetailsEdit.js index 5e04369a380..c06106c8b88 100644 --- a/addons/point_of_sale/static/src/js/Screens/PartnerListScreen/PartnerDetailsEdit.js +++ b/addons/point_of_sale/static/src/js/Screens/PartnerListScreen/PartnerDetailsEdit.js @@ -5,6 +5,7 @@ import { getDataURLFromFile } from "@web/core/utils/urls"; import { ErrorPopup } from "@point_of_sale/js/Popups/ErrorPopup"; import { useService } from "@web/core/utils/hooks"; import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; export class PartnerDetailsEdit extends Component { static template = "PartnerDetailsEdit"; @@ -12,6 +13,7 @@ export class PartnerDetailsEdit extends Component { setup() { super.setup(); this.popup = useService("popup"); + this.pos = usePos(); this.intFields = ["country_id", "state_id", "property_product_pricelist"]; const partner = this.props.partner; this.changes = { @@ -23,13 +25,12 @@ export class PartnerDetailsEdit extends Component { save: () => this.saveChanges(), }); } + // FIXME POSREF naming setDefaultPricelist(partner) { if (partner.property_product_pricelist) { return partner.property_product_pricelist[0]; - } else if (this.env.pos.default_pricelist) { - return this.env.pos.default_pricelist.id; } - return false; + return this.pos.globalState.default_pricelist?.id ?? false; } get partnerImageUrl() { @@ -82,8 +83,6 @@ export class PartnerDetailsEdit extends Component { if (loadedImage) { const resizedImage = await this._resizeImage(loadedImage, 800, 600); this.changes.image_1920 = resizedImage.toDataURL(); - // Rerender to reflect the changes in the screen - this.render(true); } } } diff --git a/addons/point_of_sale/static/src/js/Screens/PartnerListScreen/PartnerListScreen.js b/addons/point_of_sale/static/src/js/Screens/PartnerListScreen/PartnerListScreen.js index 8910d2b57b5..9a02a4cbea7 100644 --- a/addons/point_of_sale/static/src/js/Screens/PartnerListScreen/PartnerListScreen.js +++ b/addons/point_of_sale/static/src/js/Screens/PartnerListScreen/PartnerListScreen.js @@ -7,7 +7,7 @@ import { useService } from "@web/core/utils/hooks"; import { PartnerLine } from "./PartnerLine"; import { PartnerDetailsEdit } from "./PartnerDetailsEdit"; import { usePos } from "@point_of_sale/app/pos_hook"; -import { Component, onWillUnmount, useRef } from "@odoo/owl"; +import { Component, onWillUnmount, useRef, useState } from "@odoo/owl"; import { sprintf } from "@web/core/utils/strings"; /** @@ -36,12 +36,7 @@ export class PartnerListScreen extends Component { this.notification = useService("pos_notification"); this.searchWordInputRef = useRef("search-word-input-partner"); - // We are not using useState here because the object - // passed to useState converts the object and its contents - // to Observer proxy. Not sure of the side-effects of making - // a persistent object, such as pos, into Observer. But it - // is better to be safe. - this.state = { + this.state = useState({ query: null, selectedPartner: this.props.partner, detailIsShown: false, @@ -50,7 +45,7 @@ export class PartnerListScreen extends Component { }, previousQuery: "", currentOffset: 0, - }; + }); this.updatePartnerList = debounce(this.updatePartnerList, 70); onWillUnmount(this.updatePartnerList.cancel); this.partnerEditor = {}; // create an imperative handle for PartnerDetailsEdit @@ -59,7 +54,6 @@ export class PartnerListScreen extends Component { back() { if (this.state.detailIsShown) { this.state.detailIsShown = false; - this.render(true); } else { this.props.resolve({ confirmed: false, payload: false }); this.pos.closeTempScreen(); @@ -71,20 +65,19 @@ export class PartnerListScreen extends Component { } activateEditMode() { this.state.detailIsShown = true; - this.render(true); } // Getters get currentOrder() { - return this.env.pos.get_order(); + return this.pos.globalState.get_order(); } get partners() { let res; if (this.state.query && this.state.query.trim() !== "") { - res = this.env.pos.db.search_partner(this.state.query.trim()); + res = this.pos.globalState.db.search_partner(this.state.query.trim()); } else { - res = this.env.pos.db.get_partners_sorted(1000); + res = this.pos.globalState.db.get_partners_sorted(1000); } res.sort(function (a, b) { return (a.name || "").localeCompare(b.name || ""); @@ -134,13 +127,11 @@ export class PartnerListScreen extends Component { _clearSearch() { this.searchWordInputRef.el.value = ""; this.state.query = ""; - this.render(true); } // We declare this event handler as a debounce function in // order to lower its trigger rate. async updatePartnerList(event) { this.state.query = event.target.value; - this.render(true); } clickPartner(partner) { if (this.state.selectedPartner && this.state.selectedPartner.id === partner.id) { @@ -156,16 +147,15 @@ export class PartnerListScreen extends Component { } createPartner() { // initialize the edit screen with default details about country & state - this.state.editModeProps.partner = { - country_id: this.env.pos.company.country_id, - state_id: this.env.pos.company.state_id, - }; + const { country_id, state_id } = this.pos.globalState.company; + this.state.editModeProps.partner = { country_id, state_id }; this.activateEditMode(); } async saveChanges(processedChanges) { + const { globalState } = this.pos; const partnerId = await this.orm.call("res.partner", "create_from_ui", [processedChanges]); - await this.env.pos.load_new_partners(); - this.state.selectedPartner = this.env.pos.db.get_partner_by_id(partnerId); + await globalState.load_new_partners(); + this.state.selectedPartner = globalState.db.get_partner_by_id(partnerId); this.confirm(); } async searchPartner() { @@ -173,8 +163,7 @@ export class PartnerListScreen extends Component { this.state.currentOffset = 0; } const result = await this.getNewPartners(); - this.env.pos.addPartners(result); - this.render(true); + this.pos.globalState.addPartners(result); if (this.state.previousQuery == this.state.query) { this.state.currentOffset += result.length; } else { diff --git a/addons/point_of_sale/static/src/js/Screens/PaymentScreen/PaymentScreen.js b/addons/point_of_sale/static/src/js/Screens/PaymentScreen/PaymentScreen.js index 75daffd1d6a..11d12140883 100644 --- a/addons/point_of_sale/static/src/js/Screens/PaymentScreen/PaymentScreen.js +++ b/addons/point_of_sale/static/src/js/Screens/PaymentScreen/PaymentScreen.js @@ -34,8 +34,8 @@ export class PaymentScreen extends Component { this.report = useService("report"); this.notification = useService("pos_notification"); this.hardwareProxy = useService("hardware_proxy"); - this.payment_methods_from_config = this.env.pos.payment_methods.filter((method) => - this.env.pos.config.payment_method_ids.includes(method.id) + this.payment_methods_from_config = this.pos.globalState.payment_methods.filter((method) => + this.pos.globalState.config.payment_method_ids.includes(method.id) ); this.numberBuffer = useService("number_buffer"); this.numberBuffer.use(this._getNumberBufferConfig); @@ -71,7 +71,7 @@ export class PaymentScreen extends Component { return config; } get currentOrder() { - return this.env.pos.get_order(); + return this.pos.globalState.get_order(); } get paymentLines() { return this.currentOrder.get_paymentlines(); @@ -130,9 +130,7 @@ export class PaymentScreen extends Component { } } toggleIsToInvoice() { - // click_invoice this.currentOrder.set_to_invoice(!this.currentOrder.is_to_invoice()); - this.render(true); } openCashbox() { this.hardwareProxy.printer.openCashbox(); @@ -147,7 +145,7 @@ export class PaymentScreen extends Component { title: tip ? this.env._t("Change Tip") : this.env._t("Add Tip"), startingValue: value, isInputSelected: true, - inputSuffix: this.env.pos.currency.symbol, + inputSuffix: this.pos.globalState.currency.symbol, }); if (confirmed) { @@ -167,7 +165,6 @@ export class PaymentScreen extends Component { } } deletePaymentLine(cid) { - var self = this; const line = this.paymentLines.find((line) => line.cid === cid); // If a paymentline with a payment terminal linked to // it is removed, the terminal should get a cancel @@ -176,27 +173,24 @@ export class PaymentScreen extends Component { line.set_payment_status("waitingCancel"); line.payment_method.payment_terminal .send_payment_cancel(this.currentOrder, cid) - .then(function () { - self.currentOrder.remove_paymentline(line); + .then(() => { + this.currentOrder.remove_paymentline(line); this.numberBuffer.reset(); - self.render(true); }); } else if (line.get_payment_status() !== "waitingCancel") { this.currentOrder.remove_paymentline(line); this.numberBuffer.reset(); - this.render(true); } } selectPaymentLine(cid) { const line = this.paymentLines.find((line) => line.cid === cid); this.currentOrder.select_paymentline(line); this.numberBuffer.reset(); - this.render(true); } async validateOrder(isForceValidate) { this.numberBuffer.capture(); - if (this.env.pos.config.cash_rounding) { - if (!this.env.pos.get_order().check_paymentlines_rounding()) { + if (this.pos.globalState.config.cash_rounding) { + if (!this.pos.globalState.get_order().check_paymentlines_rounding()) { this.popup.add(ErrorPopup, { title: this.env._t("Rounding error in payment lines"), body: this.env._t( @@ -217,9 +211,10 @@ export class PaymentScreen extends Component { } } async _finalizeValidation() { + const { globalState } = this.pos; if ( (this.currentOrder.is_paid_with_cash() || this.currentOrder.get_change()) && - this.env.pos.config.iface_cashdrawer + globalState.config.iface_cashdrawer ) { this.hardwareProxy.printer.openCashbox(); } @@ -231,7 +226,7 @@ export class PaymentScreen extends Component { try { // 1. Save order to server. - syncOrderResult = await this.env.pos.push_single_order(this.currentOrder); + syncOrderResult = await globalState.push_single_order(this.currentOrder); // 2. Invoice. if (this.currentOrder.is_to_invoice()) { @@ -283,10 +278,10 @@ export class PaymentScreen extends Component { this.pos.showScreen(this.nextScreen); // Remove the order from the local storage so that when we refresh the page, the order // won't be there - this.env.pos.db.remove_unpaid_order(this.currentOrder); + globalState.db.remove_unpaid_order(this.currentOrder); // Ask the user to sync the remaining unsynced orders. - if (!hasError && syncOrderResult && this.env.pos.db.get_orders().length) { + if (!hasError && syncOrderResult && globalState.db.get_orders().length) { const { confirmed } = await this.popup.add(ConfirmPopup, { title: this.env._t("Remaining unsynced orders"), body: this.env._t( @@ -297,7 +292,7 @@ export class PaymentScreen extends Component { // NOTE: Not yet sure if this should be awaited or not. // If awaited, some operations like changing screen // might not work. - this.env.pos.push_orders(); + globalState.push_orders(); } } } @@ -404,11 +399,7 @@ export class PaymentScreen extends Component { this.currentOrder.get_rounding_applied() ) > 0.00001 ) { - var cash = false; - for (var i = 0; i < this.env.pos.payment_methods.length; i++) { - cash = cash || this.env.pos.payment_methods[i].is_cash_count; - } - if (!cash) { + if (!this.pos.globalState.payment_methods.some((pm) => pm.is_cash_count)) { this.popup.add(ErrorPopup, { title: this.env._t("Cannot return change without a cash payment method"), body: this.env._t( @@ -472,10 +463,11 @@ export class PaymentScreen extends Component { line.can_be_reversed = payment_terminal.supports_reversals; // Automatically validate the order when after an electronic payment, // the current order is fully paid and due is zero. + const { config, currency } = this.pos.globalState; if ( this.currentOrder.is_paid() && - floatIsZero(this.currentOrder.get_due(), this.env.pos.currency.decimal_places) && - this.env.pos.config.auto_validate_terminal_payment + floatIsZero(this.currentOrder.get_due(), currency.decimal_places) && + config.auto_validate_terminal_payment ) { this.validateOrder(false); } diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/OrderlineCustomerNoteButton.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/OrderlineCustomerNoteButton.js index f435e22be44..b5473e84ab2 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/OrderlineCustomerNoteButton.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/OrderlineCustomerNoteButton.js @@ -4,16 +4,18 @@ import { ProductScreen } from "@point_of_sale/js/Screens/ProductScreen/ProductSc import { useService } from "@web/core/utils/hooks"; import { TextAreaPopup } from "@point_of_sale/js/Popups/TextAreaPopup"; import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; export class OrderlineCustomerNoteButton extends Component { static template = "OrderlineCustomerNoteButton"; setup() { - super.setup(); + this.pos = usePos(); this.popup = useService("popup"); } async onClick() { - const selectedOrderline = this.env.pos.get_order().get_selected_orderline(); + const selectedOrderline = this.pos.globalState.get_order().get_selected_orderline(); + // FIXME POSREF can this happen? Shouldn't the orderline just be a prop? if (!selectedOrderline) { return; } diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/ProductInfoButton.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/ProductInfoButton.js index 5cd793e867a..5e5eec04b89 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/ProductInfoButton.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/ProductInfoButton.js @@ -4,20 +4,21 @@ import { ProductScreen } from "@point_of_sale/js/Screens/ProductScreen/ProductSc import { useService } from "@web/core/utils/hooks"; import { ProductInfoPopup } from "@point_of_sale/js/Popups/ProductInfoPopup"; import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; export class ProductInfoButton extends Component { static template = "ProductInfoButton"; setup() { - super.setup(); + this.pos = usePos(); this.popup = useService("popup"); } async click() { - const orderline = this.env.pos.get_order().get_selected_orderline(); + const orderline = this.pos.globalState.get_order().get_selected_orderline(); if (orderline) { const product = orderline.get_product(); const quantity = orderline.get_quantity(); - const info = await this.env.pos.getProductInfo(product, quantity); + const info = await this.pos.globalState.getProductInfo(product, quantity); this.popup.add(ProductInfoPopup, { info: info, product: product }); } } diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/RefundButton.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/RefundButton.js index 516d0768b8d..45a42ffcd0d 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/RefundButton.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/RefundButton.js @@ -8,15 +8,15 @@ export class RefundButton extends Component { static template = "point_of_sale.RefundButton"; setup() { - super.setup(); this.pos = usePos(); } click() { - const partner = this.env.pos.get_order().get_partner(); + const order = this.pos.globalState.get_order(); + const partner = order.get_partner(); const searchDetails = partner ? { fieldName: "PARTNER", searchTerm: partner.name } : {}; this.pos.showScreen("TicketScreen", { ui: { filter: "SYNCED", searchDetails }, - destinationOrder: this.env.pos.get_order(), + destinationOrder: order, }); } } diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/SaveButton.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/SaveButton.js index dc472d66420..72efd32fc22 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/SaveButton.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/SaveButton.js @@ -1,6 +1,7 @@ /** @odoo-module */ import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; import { ProductScreen } from "@point_of_sale/js/Screens/ProductScreen/ProductScreen"; import { useService } from "@web/core/utils/hooks"; @@ -8,11 +9,11 @@ export class SaveButton extends Component { static template = "point_of_sale.SaveButton"; setup() { - super.setup(); + this.pos = usePos(); this.notification = useService("pos_notification"); } onClick() { - const orderline = this.env.pos.get_order().get_selected_orderline(); + const orderline = this.pos.globalState.get_order().get_selected_orderline(); if (!orderline) { this.notification.add(this.env._t("You cannot save an empty order"), 3000); return; @@ -21,13 +22,14 @@ export class SaveButton extends Component { this.notification.add(this.env._t("Order saved for later"), 3000); } _selectEmptyOrder() { - const orders = this.env.pos.get_order_list(); + const { globalState } = this.pos; + const orders = globalState.get_order_list(); const emptyOrders = orders.filter((order) => order.is_empty()); if (emptyOrders.length > 0) { - this.env.pos.sendDraftToServer(); - this.env.pos.set_order(emptyOrders[0]); + globalState.sendDraftToServer(); + globalState.set_order(emptyOrders[0]); } else { - this.env.pos.add_new_order(); + globalState.add_new_order(); } } } @@ -35,6 +37,6 @@ export class SaveButton extends Component { ProductScreen.addControlButton({ component: SaveButton, condition: function () { - return this.env.pos.config.trusted_config_ids.length > 0; + return this.pos.globalState.config.trusted_config_ids.length > 0; }, }); diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/SetFiscalPositionButton.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/SetFiscalPositionButton.js index b7525feb1de..ccd69d8cbc1 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/SetFiscalPositionButton.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/SetFiscalPositionButton.js @@ -4,16 +4,17 @@ import { ProductScreen } from "@point_of_sale/js/Screens/ProductScreen/ProductSc import { useService } from "@web/core/utils/hooks"; import { SelectionPopup } from "@point_of_sale/js/Popups/SelectionPopup"; import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; export class SetFiscalPositionButton extends Component { static template = "SetFiscalPositionButton"; setup() { - super.setup(); + this.pos = usePos(); this.popup = useService("popup"); } get currentOrder() { - return this.env.pos.get_order(); + return this.pos.globalState.get_order(); } get currentFiscalPositionName() { return this.currentOrder && this.currentOrder.fiscal_position @@ -29,7 +30,7 @@ export class SetFiscalPositionButton extends Component { isSelected: !currentFiscalPosition, }, ]; - for (const fiscalPos of this.env.pos.fiscal_positions) { + for (const fiscalPos of this.pos.globalState.fiscal_positions) { fiscalPosList.push({ id: fiscalPos.id, label: fiscalPos.name, @@ -60,7 +61,7 @@ export class SetFiscalPositionButton extends Component { ProductScreen.addControlButton({ component: SetFiscalPositionButton, condition: function () { - return this.env.pos.fiscal_positions.length > 0; + return this.pos.globalState.fiscal_positions.length > 0; }, position: ["before", "SetPricelistButton"], }); diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/SetPricelistButton.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/SetPricelistButton.js index 86ff979bd68..212aad7af0c 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/SetPricelistButton.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ControlButtons/SetPricelistButton.js @@ -4,16 +4,17 @@ import { ProductScreen } from "@point_of_sale/js/Screens/ProductScreen/ProductSc import { useService } from "@web/core/utils/hooks"; import { SelectionPopup } from "@point_of_sale/js/Popups/SelectionPopup"; import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; export class SetPricelistButton extends Component { static template = "SetPricelistButton"; setup() { - super.setup(); + this.pos = usePos(); this.popup = useService("popup"); } get currentOrder() { - return this.env.pos.get_order(); + return this.pos.globalState.get_order(); } get currentPricelistName() { const order = this.currentOrder; @@ -23,7 +24,7 @@ export class SetPricelistButton extends Component { // Create the list to be passed to the SelectionPopup. // Pricelist object is passed as item in the list because it // is the object that will be returned when the popup is confirmed. - const selectionList = this.env.pos.pricelists.map((pricelist) => ({ + const selectionList = this.pos.globalState.pricelists.map((pricelist) => ({ id: pricelist.id, label: pricelist.name, isSelected: @@ -31,7 +32,7 @@ export class SetPricelistButton extends Component { item: pricelist, })); - if (!this.env.pos.default_pricelist) { + if (!this.pos.globalState.default_pricelist) { selectionList.push({ id: null, label: this.env._t("Default Price"), @@ -54,6 +55,7 @@ export class SetPricelistButton extends Component { ProductScreen.addControlButton({ component: SetPricelistButton, condition: function () { - return this.env.pos.config.use_pricelist && this.env.pos.pricelists.length > 0; + const { config, pricelists } = this.pos.globalState; + return config.use_pricelist && pricelists.length > 0; }, }); diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/NumpadWidget.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/NumpadWidget.js index 2e5cabc793d..91c72b7653f 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/NumpadWidget.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/NumpadWidget.js @@ -2,6 +2,7 @@ import { useService } from "@web/core/utils/hooks"; import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; /** * @prop {'quantity' | 'price' | 'discount'} activeMode @@ -15,18 +16,20 @@ export class NumpadWidget extends Component { disableSign: false, }; setup() { + this.pos = usePos(); this.numberBuffer = useService("number_buffer"); this.localization = useService("localization"); } get hasPriceControlRights() { return ( - this.env.pos.cashierHasPriceControlRights() && + this.pos.globalState.cashierHasPriceControlRights() && !this.props.disabledModes.includes("price") ); } get hasManualDiscount() { return ( - this.env.pos.config.manual_discount && !this.props.disabledModes.includes("discount") + this.pos.globalState.config.manual_discount && + !this.props.disabledModes.includes("discount") ); } changeMode(mode) { @@ -38,7 +41,7 @@ export class NumpadWidget extends Component { } this.numberBuffer.capture(); this.numberBuffer.reset(); - this.env.pos.numpadMode = mode; + this.pos.globalState.numpadMode = mode; } sendInput(key) { this.numberBuffer.sendKey(key); diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/OrderSummary.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/OrderSummary.js index dbf5a7f2011..2fb46ee7a38 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/OrderSummary.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/OrderSummary.js @@ -1,11 +1,15 @@ /** @odoo-module */ import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; import { floatIsZero } from "@web/core/utils/numbers"; export class OrderSummary extends Component { static template = "OrderSummary"; + setup() { + this.pos = usePos(); + } getTotal() { return this.env.utils.formatCurrency(this.props.order.get_total_with_tax()); } @@ -14,7 +18,7 @@ export class OrderSummary extends Component { const totalWithoutTax = this.props.order.get_total_without_tax(); const taxAmount = total - totalWithoutTax; return { - hasTax: !floatIsZero(taxAmount, this.env.pos.currency.decimal_places), + hasTax: !floatIsZero(taxAmount, this.pos.globalState.currency.decimal_places), displayAmount: this.env.utils.formatCurrency(taxAmount), }; } diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/OrderWidget.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/OrderWidget.js index 604692fc88a..6cefca19bb6 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/OrderWidget.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/OrderWidget.js @@ -6,6 +6,7 @@ import { EditListPopup } from "@point_of_sale/js/Popups/EditListPopup"; import { Orderline } from "./Orderline"; import { OrderSummary } from "./OrderSummary"; import { Component, useEffect, useRef } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; export class OrderWidget extends Component { static components = { Orderline, OrderSummary }; @@ -13,6 +14,7 @@ export class OrderWidget extends Component { setup() { super.setup(); + this.pos = usePos(); this.popup = useService("popup"); this.numberBuffer = useService("number_buffer"); this.scrollableRef = useRef("scrollable"); @@ -29,7 +31,7 @@ export class OrderWidget extends Component { ); } get order() { - return this.env.pos.get_order(); + return this.pos.globalState.get_order(); } get orderlinesArray() { return this.order ? this.order.get_orderlines() : []; diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/Orderline.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/Orderline.js index 1554c4c977f..d1391274170 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/Orderline.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/Orderline.js @@ -18,7 +18,7 @@ export class Orderline extends Component { selectLine() { const line = this.props.line; // the orderline - if (this.env.pos.get_order().selected_orderline.id !== line.id) { + if (this.pos.globalState.get_order().selected_orderline.id !== line.id) { this.mp_dbclk_time = new Date().getTime(); } else if (!this.mp_dbclk_time) { this.mp_dbclk_time = new Date().getTime(); diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductItem.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductItem.js index eefccbc7748..74fcee1645f 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductItem.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductItem.js @@ -25,11 +25,11 @@ export class ProductItem extends Component { return `/web/image?model=product.product&field=image_128&id=${product.id}&unique=${product.write_date}`; } get pricelist() { - const current_order = this.env.pos.get_order(); + const current_order = this.pos.globalState.get_order(); if (current_order) { return current_order.pricelist; } - return this.env.pos.default_pricelist; + return this.pos.globalState.default_pricelist; } get price() { const formattedUnitPrice = this.env.utils.formatCurrency( @@ -37,7 +37,7 @@ export class ProductItem extends Component { ); if (this.props.product.to_weight) { return `${formattedUnitPrice}/${ - this.env.pos.units_by_id[this.props.product.uom_id[0]].name + this.pos.globalState.units_by_id[this.props.product.uom_id[0]].name }`; } else { return formattedUnitPrice; diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductScreen.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductScreen.js index a8cb02ad496..d4c2aae9e35 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductScreen.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductScreen.js @@ -76,21 +76,19 @@ export class ProductScreen extends ControlButtonsMixin(Component) { return this.currentOrder ? this.currentOrder.get_partner() : null; } get currentOrder() { - return this.env.pos.get_order(); + return this.pos.globalState.get_order(); } async updateSelectedOrderline({ buffer, key }) { - if (this.env.pos.numpadMode === "quantity" && this.env.pos.disallowLineQuantityChange()) { - const order = this.env.pos.get_order(); + const { globalState } = this.pos; + if (globalState.numpadMode === "quantity" && globalState.disallowLineQuantityChange()) { + const order = globalState.get_order(); if (!order.orderlines.length) { return; } const selectedLine = order.get_selected_orderline(); const orderlines = order.orderlines; const lastId = orderlines.length !== 0 && orderlines.at(orderlines.length - 1).cid; - const currentQuantity = this.env.pos - .get_order() - .get_selected_orderline() - .get_quantity(); + const currentQuantity = globalState.get_order().get_selected_orderline().get_quantity(); if (selectedLine.noDecrease) { this.popup.add(ErrorPopup, { @@ -112,20 +110,21 @@ export class ProductScreen extends ControlButtonsMixin(Component) { this._setValue(val); if (val == "remove") { this.numberBuffer.reset(); - this.env.pos.numpadMode = "quantity"; + globalState.numpadMode = "quantity"; } } } _setValue(val) { + const { numpadMode } = this.pos.globalState; if (this.currentOrder.get_selected_orderline()) { - if (this.env.pos.numpadMode === "quantity") { + if (numpadMode === "quantity") { const result = this.currentOrder.get_selected_orderline().set_quantity(val); if (!result) { this.numberBuffer.reset(); } - } else if (this.env.pos.numpadMode === "discount") { + } else if (numpadMode === "discount") { this.currentOrder.get_selected_orderline().set_discount(val); - } else if (this.env.pos.numpadMode === "price") { + } else if (numpadMode === "price") { var selected_orderline = this.currentOrder.get_selected_orderline(); selected_orderline.price_manually_set = true; selected_orderline.set_unit_price(val); @@ -133,7 +132,8 @@ export class ProductScreen extends ControlButtonsMixin(Component) { } } async _barcodeProductAction(code) { - let product = this.env.pos.db.get_product_by_barcode(code.base_code); + const { globalState } = this.pos; + let product = globalState.db.get_product_by_barcode(code.base_code); if (!product) { // find the barcode in the backend let foundProductIds = []; @@ -141,9 +141,9 @@ export class ProductScreen extends ControlButtonsMixin(Component) { ["barcode", "=", code.base_code], ]); if (foundProductIds.length) { - await this.env.pos._addProducts(foundProductIds); + await globalState._addProducts(foundProductIds); // assume that the result is unique. - product = this.env.pos.db.get_product_by_id(foundProductIds[0]); + product = globalState.db.get_product_by_id(foundProductIds[0]); } else { return this.popup.add(ErrorBarcodePopup, { code: code.base_code }); } @@ -178,7 +178,7 @@ export class ProductScreen extends ControlButtonsMixin(Component) { this.numberBuffer.reset(); } _barcodePartnerAction(code) { - const partner = this.env.pos.db.get_partner_by_barcode(code.code); + const partner = this.pos.globalState.db.get_partner_by_barcode(code.code); if (partner) { if (this.currentOrder.get_partner() !== partner) { this.currentOrder.set_partner(partner); @@ -207,8 +207,8 @@ export class ProductScreen extends ControlButtonsMixin(Component) { }); const newQuantity = inputNumber && inputNumber !== "" ? parseFloat(inputNumber) : null; if (confirmed && newQuantity !== null) { - const order = this.env.pos.get_order(); - const selectedLine = this.env.pos.get_order().get_selected_orderline(); + const order = this.pos.globalState.get_order(); + const selectedLine = order.get_selected_orderline(); const currentQuantity = selectedLine.get_quantity(); if (newQuantity >= currentQuantity) { selectedLine.set_quantity(newQuantity); @@ -230,22 +230,23 @@ export class ProductScreen extends ControlButtonsMixin(Component) { } } async onClickPay() { - if (this.env.pos.get_order().server_id) { + const { globalState } = this.pos; + if (globalState.get_order().server_id) { try { const isPaid = await this.orm.call("pos.order", "is_already_paid", [ - this.env.pos.get_order().server_id, + globalState.get_order().server_id, ]); if (isPaid) { const searchDetails = { fieldName: "RECEIPT_NUMBER", - searchTerm: this.env.pos.get_order().uid, + searchTerm: globalState.get_order().uid, }; this.pos.showScreen("TicketScreen", { ui: { filter: "SYNCED", searchDetails }, }); this.notification.add(this.env._t("The order has been already paid."), 3000); - this.env.pos.removeOrder(this.env.pos.get_order(), false); - this.env.pos.add_new_order(); + globalState.removeOrder(globalState.get_order(), false); + globalState.add_new_order(); return; } } catch (error) { @@ -257,14 +258,13 @@ export class ProductScreen extends ControlButtonsMixin(Component) { } } if ( - this.env.pos + globalState .get_order() .orderlines.some( (line) => line.get_product().tracking !== "none" && !line.has_valid_product_lot() ) && - (this.env.pos.picking_type.use_create_lots || - this.env.pos.picking_type.use_existing_lots) + (globalState.picking_type.use_create_lots || globalState.picking_type.use_existing_lots) ) { const { confirmed } = await this.popup.add(ConfirmPopup, { title: this.env._t("Some Serial/Lot Numbers are missing"), diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductsWidget.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductsWidget.js index a2257e9f470..04319154e9e 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductsWidget.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductsWidget.js @@ -35,63 +35,63 @@ export class ProductsWidget extends Component { return Object.keys(this.pos.globalState.db.product_by_id).length > 0; } get selectedCategoryId() { - return this.env.pos.selectedCategoryId; + return this.pos.globalState.selectedCategoryId; } get searchWord() { - return this.env.pos.searchProductWord.trim(); + return this.pos.globalState.searchProductWord.trim(); } get productsToDisplay() { + const { db } = this.pos.globalState; let list = []; if (this.searchWord !== "") { - list = this.env.pos.db.search_product_in_category( - this.selectedCategoryId, - this.searchWord - ); + list = db.search_product_in_category(this.selectedCategoryId, this.searchWord); } else { - list = this.env.pos.db.get_product_by_category(this.selectedCategoryId); + list = db.get_product_by_category(this.selectedCategoryId); } return list.sort(function (a, b) { return a.display_name.localeCompare(b.display_name); }); } get subcategories() { - return this.env.pos.db + const { db } = this.pos.globalState; + return db .get_category_childs_ids(this.selectedCategoryId) - .map((id) => this.env.pos.db.get_category_by_id(id)); + .map((id) => db.get_category_by_id(id)); } get breadcrumbs() { - if (this.selectedCategoryId === this.env.pos.db.root_category_id) { + const { db } = this.pos.globalState; + if (this.selectedCategoryId === db.root_category_id) { return []; } return [ - ...this.env.pos.db.get_category_ancestors_ids(this.selectedCategoryId).slice(1), + ...db.get_category_ancestors_ids(this.selectedCategoryId).slice(1), this.selectedCategoryId, - ].map((id) => this.env.pos.db.get_category_by_id(id)); + ].map((id) => db.get_category_by_id(id)); } get hasNoCategories() { - return this.env.pos.db.get_category_childs_ids(0).length === 0; + return this.pos.globalState.db.get_category_childs_ids(0).length === 0; } get shouldShowButton() { return this.productsToDisplay.length === 0 && this.searchWord; } switchCategory(categoryId) { - this.env.pos.setSelectedCategoryId(categoryId); + this.pos.globalState.setSelectedCategoryId(categoryId); } updateSearch(searchWord) { - this.env.pos.searchProductWord = searchWord; + this.pos.globalState.searchProductWord = searchWord; } clearSearch() { - this.env.pos.searchProductWord = ""; + this.pos.globalState.searchProductWord = ""; } updateProductList(event) { - this.render(true); this.switchCategory(0); } async onPressEnterKey() { - if (!this.env.pos.searchProductWord) { + const { searchProductWord } = this.pos.globalState; + if (!searchProductWord) { return; } - if (this.state.previousSearchWord != this.env.pos.searchProductWord) { + if (this.state.previousSearchWord !== searchProductWord) { this.state.currentOffset = 0; } const result = await this.loadProductFromDB(); @@ -100,28 +100,26 @@ export class ProductsWidget extends Component { sprintf( this.env._t('%s product(s) found for "%s".'), result.length, - this.env.pos.searchProductWord + searchProductWord ), 3000 ); } else { this.notification.add( - sprintf( - this.env._t('No more product found for "%s".'), - this.env.pos.searchProductWord - ), + sprintf(this.env._t('No more product found for "%s".'), searchProductWord), 3000 ); } - if (this.state.previousSearchWord == this.env.pos.searchProductWord) { + if (this.state.previousSearchWord === searchProductWord) { this.state.currentOffset += result.length; } else { - this.state.previousSearchWord = this.env.pos.searchProductWord; + this.state.previousSearchWord = searchProductWord; this.state.currentOffset = result.length; } } async loadProductFromDB() { - if (!this.env.pos.searchProductWord) { + const { searchProductWord } = this.pos.globalState; + if (!searchProductWord) { return; } @@ -136,9 +134,9 @@ export class ProductsWidget extends Component { ["available_in_pos", "=", true], "|", "|", - ["name", "ilike", this.env.pos.searchProductWord], - ["default_code", "ilike", this.env.pos.searchProductWord], - ["barcode", "ilike", this.env.pos.searchProductWord], + ["name", "ilike", searchProductWord], + ["default_code", "ilike", searchProductWord], + ["barcode", "ilike", searchProductWord], ], ], { @@ -147,7 +145,7 @@ export class ProductsWidget extends Component { } ); if (ProductIds.length) { - await this.env.pos._addProducts(ProductIds, false); + await this.pos.globalState._addProducts(ProductIds, false); } this.updateProductList(); return ProductIds; diff --git a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductsWidgetControlPanel.js b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductsWidgetControlPanel.js index 5580a6c556c..9cddb336802 100644 --- a/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductsWidgetControlPanel.js +++ b/addons/point_of_sale/static/src/js/Screens/ProductScreen/ProductsWidgetControlPanel.js @@ -24,26 +24,26 @@ export class ProductsWidgetControlPanel extends Component { this.state.mobileSearchBarIsShown = !this.state.mobileSearchBarIsShown; } _clearSearch() { - this.env.pos.searchProductWord = ""; + this.pos.globalState.searchProductWord = ""; this.props.clearSearch(); } get displayCategImages() { return ( - Object.values(this.env.pos.db.category_by_id).some((categ) => categ.has_image) && - !this.env.isMobile + !this.env.isMobile && + Object.values(this.pos.globalState.db.category_by_id).some((categ) => categ.has_image) ); } updateSearch(event) { - this.props.updateSearch(this.env.pos.searchProductWord); + this.props.updateSearch(this.pos.globalState.searchProductWord); } async _onPressEnterKey() { - if (!this.env.pos.searchProductWord) { + if (!this.pos.globalState.searchProductWord) { return; } this.props.loadProductFromServer(); } searchProductFromInfo(productName) { - this.env.pos.searchProductWord = productName; + this.pos.globalState.searchProductWord = productName; this.props.switchCategory(0); this.props.updateSearch(productName); } diff --git a/addons/point_of_sale/static/src/js/Screens/ReceiptScreen/OrderReceipt.js b/addons/point_of_sale/static/src/js/Screens/ReceiptScreen/OrderReceipt.js index b911c366bac..c84efd8f570 100644 --- a/addons/point_of_sale/static/src/js/Screens/ReceiptScreen/OrderReceipt.js +++ b/addons/point_of_sale/static/src/js/Screens/ReceiptScreen/OrderReceipt.js @@ -1,5 +1,6 @@ /** @odoo-module */ +import { usePos } from "@point_of_sale/app/pos_hook"; import { WrappedProductNameLines } from "./WrappedProductNameLines"; import { Component, onWillUpdateProps } from "@odoo/owl"; @@ -9,6 +10,7 @@ export class OrderReceipt extends Component { setup() { super.setup(); + this.pos = usePos(); this._receiptEnv = this.props.order.getOrderReceiptEnv(); onWillUpdateProps((nextProps) => { diff --git a/addons/point_of_sale/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js b/addons/point_of_sale/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js index 672180e42f6..514d75e3703 100644 --- a/addons/point_of_sale/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js +++ b/addons/point_of_sale/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js @@ -22,7 +22,7 @@ export class ReceiptScreen extends AbstractReceiptScreen { this.orderReceipt = useRef("order-receipt"); this.buttonMailReceipt = useRef("order-mail-receipt-button"); this.buttonPrintReceipt = useRef("order-print-receipt-button"); - this.currentOrder = this.env.pos.get_order(); + this.currentOrder = this.pos.globalState.get_order(); const partner = this.currentOrder.get_partner(); this.orderUiState = this.currentOrder.uiState.ReceiptScreen; this.orderUiState.inputEmail = @@ -52,7 +52,7 @@ export class ReceiptScreen extends AbstractReceiptScreen { }); } _addNewOrder() { - this.env.pos.add_new_order(); + this.pos.globalState.add_new_order(); } onSendEmail() { if (this.buttonMailReceipt.el.classList.contains("fa-spin")) { @@ -92,8 +92,7 @@ export class ReceiptScreen extends AbstractReceiptScreen { get orderAmountPlusTip() { const order = this.currentOrder; const orderTotalAmount = order.get_total_with_tax(); - const tip_product_id = - this.env.pos.config.tip_product_id && this.env.pos.config.tip_product_id[0]; + const tip_product_id = this.pos.globalState.config.tip_product_id?.[0]; const tipLine = order .get_orderlines() .find((line) => tip_product_id && line.product.id === tip_product_id); @@ -134,19 +133,19 @@ export class ReceiptScreen extends AbstractReceiptScreen { } } orderDone() { - this.env.pos.removeOrder(this.currentOrder); + this.pos.globalState.removeOrder(this.currentOrder); this._addNewOrder(); const { name, props } = this.nextScreen; this.pos.showScreen(name, props); } resumeOrder() { - this.env.pos.removeOrder(this.currentOrder); - this.env.pos.selectNextOrder(); + this.pos.globalState.removeOrder(this.currentOrder); + this.pos.globalState.selectNextOrder(); const { name, props } = this.ticketScreen; this.pos.showScreen(name, props); } isResumeVisible() { - return this.env.pos.get_order_list().length > 1; + return this.pos.globalState.get_order_list().length > 1; } async printReceipt() { this.buttonPrintReceipt.el.className = "fa fa-fw fa-spin fa-circle-o-notch"; @@ -160,7 +159,7 @@ export class ReceiptScreen extends AbstractReceiptScreen { this.buttonPrintReceipt.el.className = "fa fa-print"; } _shouldAutoPrint() { - return this.env.pos.config.iface_print_auto && !this.currentOrder._printed; + return this.pos.globalState.config.iface_print_auto && !this.currentOrder._printed; } _shouldCloseImmediately() { var invoiced_finalized = this.currentOrder.is_to_invoice() @@ -168,7 +167,7 @@ export class ReceiptScreen extends AbstractReceiptScreen { : true; return ( this.hardwareProxy.printer && - this.env.pos.config.iface_print_skip_screen && + this.pos.globalState.config.iface_print_skip_screen && invoiced_finalized ); } @@ -183,7 +182,7 @@ export class ReceiptScreen extends AbstractReceiptScreen { email: this.orderUiState.inputEmail, name: partner ? partner.name : this.orderUiState.inputEmail, }; - const order_server_id = this.env.pos.validated_orders_name_server_id_map[orderName]; + const order_server_id = this.pos.globalState.validated_orders_name_server_id_map[orderName]; if (!order_server_id) { this.popup.add(OfflineErrorPopup, { title: this.env._t("Unsynced order"), diff --git a/addons/point_of_sale/static/src/js/Screens/ScaleScreen/ScaleScreen.js b/addons/point_of_sale/static/src/js/Screens/ScaleScreen/ScaleScreen.js index 368fba28c8c..de57faf59b9 100644 --- a/addons/point_of_sale/static/src/js/Screens/ScaleScreen/ScaleScreen.js +++ b/addons/point_of_sale/static/src/js/Screens/ScaleScreen/ScaleScreen.js @@ -14,7 +14,7 @@ export class ScaleScreen extends Component { * @param {Object} props.product The product to weight. */ setup() { - super.setup(); + this.pos = usePos(); this.hardwareProxy = useService("hardware_proxy"); useExternalListener(document, "keyup", this._onHotkeys); this.state = useState({ weight: 0 }); @@ -60,8 +60,8 @@ export class ScaleScreen extends Component { setTimeout(() => this._setWeight(), 500); } get _activePricelist() { - const current_order = this.env.pos.get_order(); - let current_pricelist = this.env.pos.default_pricelist; + const current_order = this.pos.globalState.get_order(); + let current_pricelist = this.pos.globalState.default_pricelist; if (current_order) { current_pricelist = current_order.pricelist; } @@ -69,14 +69,14 @@ export class ScaleScreen extends Component { } get productWeightString() { const defaultstr = (this.state.weight || 0).toFixed(3) + " Kg"; - if (!this.props.product || !this.env.pos) { + if (!this.props.product) { return defaultstr; } const unit_id = this.props.product.uom_id; if (!unit_id) { return defaultstr; } - const unit = this.env.pos.units_by_id[unit_id[0]]; + const unit = this.pos.globalState.units_by_id[unit_id[0]]; const weight = round_pr(this.state.weight || 0, unit.rounding); let weightstr = weight.toFixed(Math.ceil(Math.log(1.0 / unit.rounding) / Math.log(10))); weightstr += " " + unit.name; @@ -90,14 +90,13 @@ export class ScaleScreen extends Component { return (product ? product.get_price(this._activePricelist, this.state.weight) : 0) || 0; } get productName() { - return ( - (this.props.product ? this.props.product.display_name : undefined) || "Unnamed Product" - ); + return this.props.product?.display_name || "Unnamed Product"; } get productUom() { - return this.props.product - ? this.env.pos.units_by_id[this.props.product.uom_id[0]].name - : ""; + if (!this.props.product) { + return ""; + } + return this.pos.globalState.units_by_id[this.props.product.uom_id[0]].name; } } diff --git a/addons/point_of_sale/static/src/js/Screens/TicketScreen/OrderlineDetails.js b/addons/point_of_sale/static/src/js/Screens/TicketScreen/OrderlineDetails.js index 036302cd65b..b4125297e3e 100644 --- a/addons/point_of_sale/static/src/js/Screens/TicketScreen/OrderlineDetails.js +++ b/addons/point_of_sale/static/src/js/Screens/TicketScreen/OrderlineDetails.js @@ -4,6 +4,7 @@ import { Component } from "@odoo/owl"; import { sprintf } from "@web/core/utils/strings"; import { formatFloat } from "@web/views/fields/formatters"; import { roundPrecision as round_pr } from "@web/core/utils/numbers"; +import { usePos } from "@point_of_sale/app/pos_hook"; /** * @props {pos.order.line} line @@ -11,12 +12,15 @@ import { roundPrecision as round_pr } from "@web/core/utils/numbers"; export class OrderlineDetails extends Component { static template = "OrderlineDetails"; + setup() { + this.pos = usePos(); + } get line() { const line = this.props.line; const formatQty = (line) => { const quantity = line.get_quantity(); const unit = line.get_unit(); - const decimals = this.env.pos.dp["Product Unit of Measure"]; + const decimals = this.pos.globalState.dp["Product Unit of Measure"]; const rounding = Math.max(unit.rounding, Math.pow(10, -decimals)); const roundedQuantity = round_pr(quantity, rounding); return formatFloat(roundedQuantity, { digits: [69, decimals] }); @@ -51,17 +55,17 @@ export class OrderlineDetails extends Component { return this.props.line.get_customer_note(); } getToRefundDetail() { - return this.env.pos.toRefundLines[this.props.line.id]; + return this.pos.globalState.toRefundLines[this.props.line.id]; } hasRefundedQty() { - return !this.env.pos.isProductQtyZero(this.props.line.refunded_qty); + return !this.pos.globalState.isProductQtyZero(this.props.line.refunded_qty); } getFormattedRefundedQty() { return this.env.utils.formatProductQty(this.props.line.refunded_qty); } hasToRefundQty() { const toRefundDetail = this.getToRefundDetail(); - return !this.env.pos.isProductQtyZero(toRefundDetail && toRefundDetail.qty); + return !this.pos.globalState.isProductQtyZero(toRefundDetail && toRefundDetail.qty); } getFormattedToRefundQty() { const toRefundDetail = this.getToRefundDetail(); diff --git a/addons/point_of_sale/static/src/js/Screens/TicketScreen/ReprintReceiptScreen.js b/addons/point_of_sale/static/src/js/Screens/TicketScreen/ReprintReceiptScreen.js index 0407b211f3b..7d7d7d27d72 100644 --- a/addons/point_of_sale/static/src/js/Screens/TicketScreen/ReprintReceiptScreen.js +++ b/addons/point_of_sale/static/src/js/Screens/TicketScreen/ReprintReceiptScreen.js @@ -21,7 +21,8 @@ export class ReprintReceiptScreen extends AbstractReceiptScreen { this.pos.showScreen("TicketScreen", { reuseSavedUIState: true }); } async printReceipt() { - if (this.hardwareProxy.printer && this.env.pos.config.iface_print_skip_screen) { + const { iface_print_skip_screen } = this.pos.globalState.config; + if (this.hardwareProxy.printer && iface_print_skip_screen) { const result = await this._printReceipt(); if (result) { this.pos.showScreen("TicketScreen", { reuseSavedUIState: true }); diff --git a/addons/point_of_sale/static/src/js/Screens/TicketScreen/TicketScreen.js b/addons/point_of_sale/static/src/js/Screens/TicketScreen/TicketScreen.js index eb2142a149b..b4d78da85e5 100644 --- a/addons/point_of_sale/static/src/js/Screens/TicketScreen/TicketScreen.js +++ b/addons/point_of_sale/static/src/js/Screens/TicketScreen/TicketScreen.js @@ -54,7 +54,7 @@ export class TicketScreen extends IndependentToOrderScreen { this.numberBuffer.use({ triggerAtInput: (event) => this._onUpdateSelectedOrderline(event), }); - this._state = this.env.pos.TICKET_SCREEN_STATE; + this._state = this.pos.globalState.TICKET_SCREEN_STATE; this.state = useState({ showSearchBar: !this.env.isMobile, }); @@ -62,7 +62,7 @@ export class TicketScreen extends IndependentToOrderScreen { ? this._state.ui : { selectedSyncedOrderId: null, - searchDetails: this.env.pos.getDefaultSearchDetails(), + searchDetails: this.pos.globalState.getDefaultSearchDetails(), filter: null, selectedOrderlineIds: {}, }; @@ -115,13 +115,13 @@ export class TicketScreen extends IndependentToOrderScreen { } } onCreateNewOrder() { - this.env.pos.add_new_order(); + this.pos.globalState.add_new_order(); this.pos.showScreen("ProductScreen"); } _selectNextOrder(currentOrder) { const currentOrderIndex = this._getOrderList().indexOf(currentOrder); const orderList = this._getOrderList(); - this.env.pos.set_order( + this.pos.globalState.set_order( orderList[currentOrderIndex + 1] || orderList[currentOrderIndex - 1] ); } @@ -145,14 +145,15 @@ export class TicketScreen extends IndependentToOrderScreen { return; } } + const { globalState } = this.pos; if (order && (await this._onBeforeDeleteOrder(order))) { - if (order === this.env.pos.get_order()) { + if (order === globalState.get_order()) { this._selectNextOrder(order); } - this.env.pos.removeOrder(order); + globalState.removeOrder(order); } - if (this.env.pos.isOpenOrderShareable()) { - this.env.pos._removeOrdersFromServer(); + if (globalState.isOpenOrderShareable()) { + globalState._removeOrdersFromServer(); } } async onNextPage() { @@ -168,7 +169,7 @@ export class TicketScreen extends IndependentToOrderScreen { } } async onInvoiceOrder(orderId) { - this.env.pos._invalidateSyncedOrdersCache([orderId]); + this.pos.globalState._invalidateSyncedOrdersCache([orderId]); await this._fetchSyncedOrders(); } onClickOrderline(orderline) { @@ -178,7 +179,7 @@ export class TicketScreen extends IndependentToOrderScreen { } onClickRefundOrderUid(orderUid) { // Open the refund order. - const refundOrder = this.env.pos.orders.find((order) => order.uid == orderUid); + const refundOrder = this.pos.globalState.orders.find((order) => order.uid == orderUid); if (refundOrder) { this._setOrder(refundOrder); } @@ -258,9 +259,10 @@ export class TicketScreen extends IndependentToOrderScreen { ? this.props.destinationOrder : this._getEmptyOrder(partner); + const { globalState } = this.pos; // Add orderline for each toRefundDetail to the destinationOrder. for (const refundDetail of allToRefundDetails) { - const product = this.env.pos.db.get_product_by_id(refundDetail.orderline.productId); + const product = globalState.db.get_product_by_id(refundDetail.orderline.productId); const options = this._prepareRefundOrderlineOptions(refundDetail); await destinationOrder.add_product(product, options); refundDetail.destinationOrderUid = destinationOrder.uid; @@ -272,8 +274,8 @@ export class TicketScreen extends IndependentToOrderScreen { destinationOrder.updatePricelist(partner); } - if (this.env.pos.get_order().cid !== destinationOrder.cid) { - this.env.pos.set_order(destinationOrder); + if (globalState.get_order().cid !== destinationOrder.cid) { + globalState.set_order(destinationOrder); } this.onCloseScreen(); @@ -361,7 +363,7 @@ export class TicketScreen extends IndependentToOrderScreen { const productScreenStatus = this._getScreenToStatusMap().ProductScreen; return ( order.get_orderlines().length === 0 && - this.env.pos.get_order_list().length === 1 && + this.pos.globalState.get_order_list().length === 1 && status === productScreenStatus && order.get_paymentlines().length === 0 ); @@ -385,12 +387,12 @@ export class TicketScreen extends IndependentToOrderScreen { const selectedOrder = this.getSelectedSyncedOrder(); return selectedOrder ? order.backendId == selectedOrder.backendId : false; } else { - const activeOrder = this.env.pos.get_order(); + const activeOrder = this.pos.globalState.get_order(); return activeOrder ? activeOrder.uid == order.uid : false; } } showCardholderName() { - return this.env.pos.payment_methods.some((method) => method.use_payment_terminal); + return this.pos.globalState.payment_methods.some((method) => method.use_payment_terminal); } getSearchBarConfig() { return { @@ -424,7 +426,7 @@ export class TicketScreen extends IndependentToOrderScreen { if (this._doesOrderHaveSoleItem(order)) { return true; } - const total = Object.values(this.env.pos.toRefundLines) + const total = Object.values(this.pos.globalState.toRefundLines) .filter( (toRefundDetail) => toRefundDetail.orderline.orderUid === order.uid && @@ -432,7 +434,7 @@ export class TicketScreen extends IndependentToOrderScreen { ) .map((toRefundDetail) => toRefundDetail.qty) .reduce((acc, val) => acc + val, 0); - return !this.env.pos.isProductQtyZero(total); + return !this.pos.globalState.isProductQtyZero(total); } //#endregion //#region PRIVATE METHODS @@ -447,7 +449,7 @@ export class TicketScreen extends IndependentToOrderScreen { _getEmptyOrder(partner) { let emptyOrderForPartner = null; let emptyOrder = null; - for (const order of this.env.pos.orders) { + for (const order of this.pos.globalState.orders) { if (order.get_orderlines().length === 0 && order.get_paymentlines().length === 0) { if (order.get_partner() === partner) { emptyOrderForPartner = order; @@ -458,7 +460,7 @@ export class TicketScreen extends IndependentToOrderScreen { } } } - return emptyOrderForPartner || emptyOrder || this.env.pos.add_new_order(); + return emptyOrderForPartner || emptyOrder || this.pos.globalState.add_new_order(); } _doesOrderHaveSoleItem(order) { const orderlines = order.get_orderlines(); @@ -467,7 +469,7 @@ export class TicketScreen extends IndependentToOrderScreen { } const theOrderline = orderlines[0]; const refundableQty = theOrderline.get_quantity() - theOrderline.refunded_qty; - return this.env.pos.isProductQtyZero(refundableQty - 1); + return this.pos.globalState.isProductQtyZero(refundableQty - 1); } _prepareAutoRefundOnOrder(order) { const selectedOrderlineId = this.getSelectedOrderlineId(); @@ -478,7 +480,7 @@ export class TicketScreen extends IndependentToOrderScreen { const toRefundDetail = this._getToRefundDetail(orderline); const refundableQty = orderline.get_quantity() - orderline.refunded_qty; - if (this.env.pos.isProductQtyZero(refundableQty - 1) && toRefundDetail.qty === 0) { + if (this.pos.globalState.isProductQtyZero(refundableQty - 1) && toRefundDetail.qty === 0) { toRefundDetail.qty = 1; } return true; @@ -491,30 +493,30 @@ export class TicketScreen extends IndependentToOrderScreen { * @returns */ _getToRefundDetail(orderline) { - if (orderline.id in this.env.pos.toRefundLines) { - return this.env.pos.toRefundLines[orderline.id]; - } else { - const partner = orderline.order.get_partner(); - const orderPartnerId = partner ? partner.id : false; - const newToRefundDetail = { - qty: 0, - orderline: { - id: orderline.id, - productId: orderline.product.id, - price: orderline.price, - qty: orderline.quantity, - refundedQty: orderline.refunded_qty, - orderUid: orderline.order.uid, - orderBackendId: orderline.order.backendId, - orderPartnerId, - tax_ids: orderline.get_taxes().map((tax) => tax.id), - discount: orderline.discount, - }, - destinationOrderUid: false, - }; - this.env.pos.toRefundLines[orderline.id] = newToRefundDetail; - return newToRefundDetail; + const { toRefundLines } = this.pos.globalState; + if (orderline.id in toRefundLines) { + return toRefundLines[orderline.id]; } + const partner = orderline.order.get_partner(); + const orderPartnerId = partner ? partner.id : false; + const newToRefundDetail = { + qty: 0, + orderline: { + id: orderline.id, + productId: orderline.product.id, + price: orderline.price, + qty: orderline.quantity, + refundedQty: orderline.refunded_qty, + orderUid: orderline.order.uid, + orderBackendId: orderline.order.backendId, + orderPartnerId, + tax_ids: orderline.get_taxes().map((tax) => tax.id), + discount: orderline.discount, + }, + destinationOrderUid: false, + }; + toRefundLines[orderline.id] = newToRefundDetail; + return newToRefundDetail; } /** * Select the lines from toRefundLines, as they can come from different orders. @@ -527,9 +529,9 @@ export class TicketScreen extends IndependentToOrderScreen { * @returns {Array} refundableDetails */ _getRefundableDetails(partner) { - return Object.values(this.env.pos.toRefundLines).filter( + return Object.values(this.pos.globalState.toRefundLines).filter( ({ qty, orderline, destinationOrderUid }) => - !this.env.pos.isProductQtyZero(qty) && + !this.pos.globalState.isProductQtyZero(qty) && (partner ? orderline.orderPartnerId == partner.id : true) && !destinationOrderUid ); @@ -553,14 +555,15 @@ export class TicketScreen extends IndependentToOrderScreen { }; } _setOrder(order) { - if (this.env.pos.isOpenOrderShareable()) { - this.env.pos.sendDraftToServer(); + const { globalState } = this.pos; + if (globalState.isOpenOrderShareable()) { + globalState.sendDraftToServer(); } - this.env.pos.set_order(order); + globalState.set_order(order); this.close(); } _getOrderList() { - return this.env.pos.get_order_list(); + return this.pos.globalState.get_order_list(); } _getFilterOptions() { const orderStates = this._getOrderStates(); @@ -659,20 +662,17 @@ export class TicketScreen extends IndependentToOrderScreen { * order is not fetched anymore, instead, we use info from cache. */ async _fetchSyncedOrders() { + const { globalState } = this.pos; const domain = this._computeSyncedOrdersDomain(); const limit = this._state.syncedOrders.nPerPage; const offset = (this._state.syncedOrders.currentPage - 1) * this._state.syncedOrders.nPerPage; + const config_id = globalState.config.id; const { ordersInfo, totalCount } = await this.orm.call( "pos.order", "search_paid_order_ids", [], - { - config_id: this.env.pos.config.id, - domain, - limit, - offset, - } + { config_id, domain, limit, offset } ); const idsNotInCache = ordersInfo.filter( (orderInfo) => !(orderInfo[0] in this._state.syncedOrders.cache) @@ -686,14 +686,14 @@ export class TicketScreen extends IndependentToOrderScreen { if (idsToLoad.length > 0) { const fetchedOrders = await this.orm.call("pos.order", "export_for_ui", [idsToLoad]); // Check for missing products and partners and load them in the PoS - await this.env.pos._loadMissingProducts(fetchedOrders); - await this.env.pos._loadMissingPartners(fetchedOrders); + await globalState._loadMissingProducts(fetchedOrders); + await globalState._loadMissingPartners(fetchedOrders); // Cache these fetched orders so that next time, no need to fetch // them again, unless invalidated. See `_onInvoiceOrder`. fetchedOrders.forEach((order) => { this._state.syncedOrders.cache[order.id] = new Order( {}, - { pos: this.env.pos, json: order } + { pos: globalState, json: order } ); }); //Update the datetime indicator of the cache refresh diff --git a/addons/point_of_sale/static/src/xml/ChromeWidgets/SyncNotification.xml b/addons/point_of_sale/static/src/xml/ChromeWidgets/SyncNotification.xml index 89ecf5d5930..dabfda0276d 100644 --- a/addons/point_of_sale/static/src/xml/ChromeWidgets/SyncNotification.xml +++ b/addons/point_of_sale/static/src/xml/ChromeWidgets/SyncNotification.xml @@ -3,23 +3,23 @@
    - - + + -
    +
    -
    +
    -
    +
    -
    +
    diff --git a/addons/point_of_sale/static/src/xml/Screens/PartnerListScreen/PartnerDetailsEdit.xml b/addons/point_of_sale/static/src/xml/Screens/PartnerListScreen/PartnerDetailsEdit.xml index 5348218207b..a042c9284e5 100644 --- a/addons/point_of_sale/static/src/xml/Screens/PartnerListScreen/PartnerDetailsEdit.xml +++ b/addons/point_of_sale/static/src/xml/Screens/PartnerListScreen/PartnerDetailsEdit.xml @@ -40,7 +40,7 @@ - +
    -
    +
    Pricelist - + +
    diff --git a/addons/point_of_sale/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml b/addons/point_of_sale/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml index 0c8c9ce1865..a3af3e91579 100644 --- a/addons/point_of_sale/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml +++ b/addons/point_of_sale/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml @@ -197,7 +197,7 @@
    - + @@ -211,7 +211,7 @@
    - + x diff --git a/addons/pos_discount/static/src/js/DiscountButton.js b/addons/pos_discount/static/src/js/DiscountButton.js index 531aef87e42..5b58cf95ec4 100644 --- a/addons/pos_discount/static/src/js/DiscountButton.js +++ b/addons/pos_discount/static/src/js/DiscountButton.js @@ -6,19 +6,20 @@ import { NumberPopup } from "@point_of_sale/js/Popups/NumberPopup"; import { ErrorPopup } from "@point_of_sale/js/Popups/ErrorPopup"; import { Component } from "@odoo/owl"; import { sprintf } from "@web/core/utils/strings"; +import { usePos } from "@point_of_sale/app/pos_hook"; export class DiscountButton extends Component { static template = "DiscountButton"; setup() { - super.setup(); + this.pos = usePos(); this.popup = useService("popup"); } async click() { var self = this; const { confirmed, payload } = await this.popup.add(NumberPopup, { title: this.env._t("Discount Percentage"), - startingValue: this.env.pos.config.discount_pc, + startingValue: this.pos.globalState.config.discount_pc, isInputSelected: true, }); if (confirmed) { @@ -28,9 +29,10 @@ export class DiscountButton extends Component { } async apply_discount(pc) { - var order = this.env.pos.get_order(); - var lines = order.get_orderlines(); - var product = this.env.pos.db.get_product_by_id(this.env.pos.config.discount_product_id[0]); + const { globalState } = this.pos; + const order = globalState.get_order(); + const lines = order.get_orderlines(); + const product = globalState.db.get_product_by_id(globalState.config.discount_product_id[0]); if (product === undefined) { await this.popup.add(ErrorPopup, { title: this.env._t("No discount product found"), @@ -56,7 +58,14 @@ export class DiscountButton extends Component { .filter((id) => id !== "") .map((id) => Number(id)); - const baseToDiscount = order.calculate_base_amount(tax_ids_array, lines.filter((line) => !this.env.pos.config.tip_product_id || line.product.id !== this.env.pos.config.tip_product_id[0])); + const baseToDiscount = order.calculate_base_amount( + tax_ids_array, + lines.filter( + (line) => + !globalState.config.tip_product_id || + line.product.id !== globalState.config.tip_product_id[0] + ) + ); // We add the price as manually set to avoid recomputation when changing customer. const discount = (-pc / 100.0) * baseToDiscount; @@ -72,7 +81,7 @@ export class DiscountButton extends Component { ? sprintf( this.env._t("Tax: %s"), tax_ids_array - .map((taxId) => this.env.pos.taxes_by_id[taxId].amount + "%") + .map((taxId) => globalState.taxes_by_id[taxId].amount + "%") .join(", ") ) : this.env._t("No tax")), @@ -88,6 +97,7 @@ export class DiscountButton extends Component { ProductScreen.addControlButton({ component: DiscountButton, condition: function () { - return this.env.pos.config.module_pos_discount && this.env.pos.config.discount_product_id; + const { module_pos_discount, discount_product_id } = this.pos.globalState.config; + return module_pos_discount && discount_product_id; }, }); diff --git a/addons/pos_hr/static/src/app/navbar.xml b/addons/pos_hr/static/src/app/navbar.xml index afa366f7e35..f792a4c1c1b 100644 --- a/addons/pos_hr/static/src/app/navbar.xml +++ b/addons/pos_hr/static/src/app/navbar.xml @@ -4,10 +4,10 @@
    - - - -
    + + + +
    diff --git a/addons/pos_hr/static/src/js/CashierName.js b/addons/pos_hr/static/src/js/CashierName.js index 9fa6e9a1d0f..3767338cd12 100644 --- a/addons/pos_hr/static/src/js/CashierName.js +++ b/addons/pos_hr/static/src/js/CashierName.js @@ -11,15 +11,15 @@ patch(CashierName.prototype, "pos_hr.CashierName", { }, //@Override get avatar() { - if (this.env.pos.config.module_pos_hr) { - const cashier = this.env.pos.get_cashier(); + if (this.pos.globalState.config.module_pos_hr) { + const cashier = this.pos.globalState.get_cashier(); return `/web/image/hr.employee/${cashier.id}/avatar_128`; } return this._super(...arguments); }, //@Override get cssClass() { - if (this.env.pos.config.module_pos_hr) { + if (this.pos.globalState.config.module_pos_hr) { return { oe_status: true }; } return this._super(...arguments); diff --git a/addons/pos_hr/static/src/js/Chrome.js b/addons/pos_hr/static/src/js/Chrome.js index a4ed3088905..b26ba2191d2 100644 --- a/addons/pos_hr/static/src/js/Chrome.js +++ b/addons/pos_hr/static/src/js/Chrome.js @@ -5,9 +5,7 @@ import { patch } from "@web/core/utils/patch"; patch(Chrome.prototype, "pos_hr.Chrome", { get showCashMoveButton() { - return ( - this._super(...arguments) && - (!this.env.pos.cashier || this.env.pos.cashier.role == "manager") - ); + const { cashier } = this.pos.globalState; + return this._super(...arguments) && (!cashier || cashier.role == "manager"); }, }); diff --git a/addons/pos_hr/static/src/js/HeaderLockButton.js b/addons/pos_hr/static/src/js/HeaderLockButton.js index 1dd8371fb1b..5a947f53b68 100644 --- a/addons/pos_hr/static/src/js/HeaderLockButton.js +++ b/addons/pos_hr/static/src/js/HeaderLockButton.js @@ -11,7 +11,7 @@ export class HeaderLockButton extends Component { this.pos = usePos(); } async showLoginScreen() { - this.env.pos.reset_cashier(); + this.pos.globalState.reset_cashier(); await this.pos.showTempScreen("LoginScreen"); } } diff --git a/addons/pos_hr/static/src/js/LoginScreen.js b/addons/pos_hr/static/src/js/LoginScreen.js index c9cdc47b259..4f29ad8aa15 100644 --- a/addons/pos_hr/static/src/js/LoginScreen.js +++ b/addons/pos_hr/static/src/js/LoginScreen.js @@ -19,12 +19,12 @@ export class LoginScreen extends Component { back() { this.props.resolve({ confirmed: false, payload: false }); this.pos.closeTempScreen(); - this.env.pos.hasLoggedIn = true; + this.pos.globalState.hasLoggedIn = true; this.pos.openCashControl(); } get shopName() { - return this.env.pos.config.name; + return this.pos.globalState.config.name; } } diff --git a/addons/pos_hr/static/src/js/PaymentScreen.js b/addons/pos_hr/static/src/js/PaymentScreen.js index de88ea8677e..1c30569a260 100644 --- a/addons/pos_hr/static/src/js/PaymentScreen.js +++ b/addons/pos_hr/static/src/js/PaymentScreen.js @@ -5,7 +5,7 @@ import { patch } from "@web/core/utils/patch"; patch(PaymentScreen.prototype, "pos_hr.PaymentScreen", { async _finalizeValidation() { - this.currentOrder.cashier = this.env.pos.get_cashier(); + this.currentOrder.cashier = this.pos.globalState.get_cashier(); await this._super(...arguments); }, }); diff --git a/addons/pos_hr/static/src/js/SelectCashierMixin.js b/addons/pos_hr/static/src/js/SelectCashierMixin.js index 41d2e41175d..8c15498ad09 100644 --- a/addons/pos_hr/static/src/js/SelectCashierMixin.js +++ b/addons/pos_hr/static/src/js/SelectCashierMixin.js @@ -7,26 +7,26 @@ import { NumberPopup } from "@point_of_sale/js/Popups/NumberPopup"; import { SelectionPopup } from "@point_of_sale/js/Popups/SelectionPopup"; import { ErrorPopup } from "@point_of_sale/js/Popups/ErrorPopup"; import { useService } from "@web/core/utils/hooks"; -import { useEnv } from "@odoo/owl"; import { useBarcodeReader } from "@point_of_sale/app/barcode_reader_hook"; +import { usePos } from "@point_of_sale/app/pos_hook"; export function useCashierSelector( { onCashierChanged, exclusive } = { onCashierChanged: () => {}, exclusive: false } ) { const popup = useService("popup"); - const env = useEnv(); + const { globalState } = usePos(); useBarcodeReader( { async cashier(code) { - const employee = env.pos.employees.find( + const employee = globalState.employees.find( (emp) => emp.barcode === Sha1.hash(code.code) ); if ( employee && - employee !== env.pos.get_cashier() && + employee !== globalState.get_cashier() && (!employee.pin || (await checkPin(employee))) ) { - env.pos.set_cashier(employee); + globalState.set_cashier(employee); if (onCashierChanged) { onCashierChanged(); } @@ -60,9 +60,9 @@ export function useCashierSelector( * Select a cashier, the returning value will either be an object or nothing (undefined) */ return async function selectCashier() { - if (env.pos.config.module_pos_hr) { - const employeesList = env.pos.employees - .filter((employee) => employee.id !== env.pos.get_cashier().id) + if (globalState.config.module_pos_hr) { + const employeesList = globalState.employees + .filter((employee) => employee.id !== globalState.get_cashier().id) .map((employee) => { return { id: employee.id, @@ -80,7 +80,7 @@ export function useCashierSelector( return; } - env.pos.set_cashier(employee); + globalState.set_cashier(employee); if (onCashierChanged) { onCashierChanged(); } diff --git a/addons/pos_loyalty/static/src/js/ControlButtons/PromoCodeButton.js b/addons/pos_loyalty/static/src/js/ControlButtons/PromoCodeButton.js index 84dca1bdd14..e33e38cbed2 100644 --- a/addons/pos_loyalty/static/src/js/ControlButtons/PromoCodeButton.js +++ b/addons/pos_loyalty/static/src/js/ControlButtons/PromoCodeButton.js @@ -4,12 +4,13 @@ import { ProductScreen } from "@point_of_sale/js/Screens/ProductScreen/ProductSc import { useService } from "@web/core/utils/hooks"; import { TextInputPopup } from "@point_of_sale/js/Popups/TextInputPopup"; import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; export class PromoCodeButton extends Component { static template = "PromoCodeButton"; setup() { - super.setup(); + this.pos = usePos(); this.popup = useService("popup"); } @@ -22,7 +23,7 @@ export class PromoCodeButton extends Component { if (confirmed) { code = code.trim(); if (code !== "") { - this.env.pos.get_order().activateCode(code); + this.pos.globalState.get_order().activateCode(code); } } } @@ -31,7 +32,7 @@ export class PromoCodeButton extends Component { ProductScreen.addControlButton({ component: PromoCodeButton, condition: function () { - return this.env.pos.programs.some((p) => + return this.pos.globalState.programs.some((p) => ["coupons", "promotion", "gift_card", "promo_code"].includes(p.program_type) ); }, diff --git a/addons/pos_loyalty/static/src/js/ControlButtons/ResetProgramsButton.js b/addons/pos_loyalty/static/src/js/ControlButtons/ResetProgramsButton.js index 38efd9899d3..5d67469dc82 100644 --- a/addons/pos_loyalty/static/src/js/ControlButtons/ResetProgramsButton.js +++ b/addons/pos_loyalty/static/src/js/ControlButtons/ResetProgramsButton.js @@ -2,24 +2,27 @@ import { ProductScreen } from "@point_of_sale/js/Screens/ProductScreen/ProductScreen"; import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; export class ResetProgramsButton extends Component { static template = "ResetProgramsButton"; setup() { - super.setup(); + this.pos = usePos(); } _isDisabled() { - return !this.env.pos.get_order().isProgramsResettable(); + return !this.pos.globalState.get_order().isProgramsResettable(); } click() { - this.env.pos.get_order()._resetPrograms(); + this.pos.globalState.get_order()._resetPrograms(); } } ProductScreen.addControlButton({ component: ResetProgramsButton, condition: function () { - return this.env.pos.programs.some((p) => ["coupons", "promotion"].includes(p.program_type)); + return this.pos.globalState.programs.some((p) => + ["coupons", "promotion"].includes(p.program_type) + ); }, }); diff --git a/addons/pos_loyalty/static/src/js/ControlButtons/RewardButton.js b/addons/pos_loyalty/static/src/js/ControlButtons/RewardButton.js index a9a8c15f34f..70faf91e5e6 100644 --- a/addons/pos_loyalty/static/src/js/ControlButtons/RewardButton.js +++ b/addons/pos_loyalty/static/src/js/ControlButtons/RewardButton.js @@ -10,7 +10,6 @@ export class RewardButton extends Component { static template = "RewardButton"; setup() { - super.setup(); this.popup = useService("popup"); this.pos = usePos(); this.notification = useService("pos_notification"); @@ -31,7 +30,7 @@ export class RewardButton extends Component { } _getPotentialRewards() { - const order = this.env.pos.get_order(); + const order = this.pos.globalState.get_order(); // Claimable rewards excluding those from eWallet programs. // eWallet rewards are handled in the eWalletButton. let rewards = []; @@ -62,14 +61,14 @@ export class RewardButton extends Component { * @param {Integer} coupon_id */ async _applyReward(reward, coupon_id, potentialQty) { - const order = this.env.pos.get_order(); + const order = this.pos.globalState.get_order(); order.disabledRewards.delete(reward.id); const args = {}; if (reward.reward_type === "product" && reward.multi_product) { const productsList = reward.reward_product_ids.map((product_id) => ({ id: product_id, - label: this.env.pos.db.get_product_by_id(product_id).display_name, + label: this.pos.globalState.db.get_product_by_id(product_id).display_name, item: product_id, })); const { confirmed, payload: selectedProduct } = await this.popup.add(SelectionPopup, { @@ -126,6 +125,6 @@ export class RewardButton extends Component { ProductScreen.addControlButton({ component: RewardButton, condition: function () { - return this.env.pos.programs.length > 0; + return this.pos.globalState.programs.length > 0; }, }); diff --git a/addons/pos_loyalty/static/src/js/ControlButtons/eWalletButton.js b/addons/pos_loyalty/static/src/js/ControlButtons/eWalletButton.js index 9925ae7549f..2e2e823bc3d 100644 --- a/addons/pos_loyalty/static/src/js/ControlButtons/eWalletButton.js +++ b/addons/pos_loyalty/static/src/js/ControlButtons/eWalletButton.js @@ -11,7 +11,6 @@ export class eWalletButton extends Component { static template = "point_of_sale.eWalletButton"; setup() { - super.setup(...arguments); this.popup = useService("popup"); this.pos = usePos(); } @@ -24,11 +23,13 @@ export class eWalletButton extends Component { return eWalletRewards; } _getEWalletPrograms() { - return this.env.pos.programs.filter((p) => p.program_type == "ewallet"); + return this.pos.globalState.programs.filter((p) => p.program_type == "ewallet"); } async _onClickWalletButton() { - const order = this.env.pos.get_order(); - const eWalletPrograms = this.env.pos.programs.filter((p) => p.program_type == "ewallet"); + const order = this.pos.globalState.get_order(); + const eWalletPrograms = this.pos.globalState.programs.filter( + (p) => p.program_type == "ewallet" + ); const orderTotal = order.get_total_with_tax(); const eWalletRewards = this._getEWalletRewards(order); if (orderTotal < 0 && eWalletPrograms.length >= 1) { @@ -49,7 +50,7 @@ export class eWalletButton extends Component { } } if (selectedProgram) { - const eWalletProduct = this.env.pos.db.get_product_by_id( + const eWalletProduct = this.pos.globalState.db.get_product_by_id( selectedProgram.trigger_product_ids[0] ); this.pos.addProductFromUi(eWalletProduct, { @@ -109,6 +110,6 @@ export class eWalletButton extends Component { ProductScreen.addControlButton({ component: eWalletButton, condition: function () { - return this.env.pos.programs.filter((p) => p.program_type == "ewallet").length > 0; + return this.pos.globalState.programs.filter((p) => p.program_type == "ewallet").length > 0; }, }); diff --git a/addons/pos_loyalty/static/src/js/OrderSummary.js b/addons/pos_loyalty/static/src/js/OrderSummary.js index 78084e72760..eaca8e3685b 100644 --- a/addons/pos_loyalty/static/src/js/OrderSummary.js +++ b/addons/pos_loyalty/static/src/js/OrderSummary.js @@ -5,7 +5,7 @@ import { patch } from "@web/core/utils/patch"; patch(OrderSummary.prototype, "pos_loyalty.OrderSummary", { getLoyaltyPoints() { - const order = this.env.pos.get_order(); + const order = this.pos.globalState.get_order(); return order.getLoyaltyPoints(); }, }); diff --git a/addons/pos_loyalty/static/src/js/Orderline.js b/addons/pos_loyalty/static/src/js/Orderline.js index 3653a8a84a0..6bac2acbd3f 100644 --- a/addons/pos_loyalty/static/src/js/Orderline.js +++ b/addons/pos_loyalty/static/src/js/Orderline.js @@ -11,9 +11,9 @@ patch(Orderline.prototype, "pos_loyalty.Orderline", { ); }, _isGiftCardOrEWalletReward() { - const coupon = this.env.pos.couponCache[this.props.line.coupon_id]; + const coupon = this.pos.globalState.couponCache[this.props.line.coupon_id]; if (coupon) { - const program = this.env.pos.program_by_id[coupon.program_id]; + const program = this.pos.globalState.program_by_id[coupon.program_id]; return ( ["ewallet", "gift_card"].includes(program.program_type) && this.props.line.is_reward_line @@ -22,7 +22,7 @@ patch(Orderline.prototype, "pos_loyalty.Orderline", { return false; }, _getGiftCardOrEWalletBalance() { - const coupon = this.env.pos.couponCache[this.props.line.coupon_id]; + const coupon = this.pos.globalState.couponCache[this.props.line.coupon_id]; if (coupon) { return this.env.utils.formatCurrency(coupon.balance); } diff --git a/addons/pos_loyalty/static/src/js/PartnerLine.js b/addons/pos_loyalty/static/src/js/PartnerLine.js index a9d5a6cb957..5f27d8edde8 100644 --- a/addons/pos_loyalty/static/src/js/PartnerLine.js +++ b/addons/pos_loyalty/static/src/js/PartnerLine.js @@ -1,13 +1,18 @@ /** @odoo-module */ +import { usePos } from "@point_of_sale/app/pos_hook"; import { PartnerLine } from "@point_of_sale/js/Screens/PartnerListScreen/PartnerLine"; import { patch } from "@web/core/utils/patch"; import { sprintf } from "@web/core/utils/strings"; import { formatFloat } from "@web/views/fields/formatters"; patch(PartnerLine.prototype, "pos_loyalty.PartnerLine", { + setup() { + this._super(...arguments); + this.pos = usePos(); + }, _getLoyaltyPointsRepr(loyaltyCard) { - const program = this.env.pos.program_by_id[loyaltyCard.program_id]; + const program = this.pos.globalState.program_by_id[loyaltyCard.program_id]; if (program.program_type === "ewallet") { return `${program.name}: ${this.env.utils.formatCurrency(loyaltyCard.balance)}`; } diff --git a/addons/pos_loyalty/static/src/js/PaymentScreen.js b/addons/pos_loyalty/static/src/js/PaymentScreen.js index 0801a0c72f0..17e9d353e05 100644 --- a/addons/pos_loyalty/static/src/js/PaymentScreen.js +++ b/addons/pos_loyalty/static/src/js/PaymentScreen.js @@ -41,17 +41,18 @@ patch(PaymentScreen.prototype, "pos_loyalty.PaymentScreen", { [[], pointChanges, newCodes] ); // Payload may contain the points of the concerned coupons to be updated in case of error. (So that rewards can be corrected) + const { couponCache } = this.pos.globalState; if (payload && payload.updated_points) { for (const pointChange of Object.entries(payload.updated_points)) { - if (this.env.pos.couponCache[pointChange[0]]) { - this.env.pos.couponCache[pointChange[0]].balance = pointChange[1]; + if (couponCache[pointChange[0]]) { + couponCache[pointChange[0]].balance = pointChange[1]; } } } if (payload && payload.removed_coupons) { for (const couponId of payload.removed_coupons) { - if (this.env.pos.couponCache[couponId]) { - delete this.env.pos.couponCache[couponId]; + if (couponCache[couponId]) { + delete couponCache[couponId]; } } this.currentOrder.codeActivatedCoupons = @@ -79,22 +80,21 @@ patch(PaymentScreen.prototype, "pos_loyalty.PaymentScreen", { async _postPushOrderResolve(order, server_ids) { // Compile data for our function const _super = this._super; + const { program_by_id, reward_by_id, couponCache } = this.pos.globalState; const rewardLines = order._get_reward_lines(); const partner = order.get_partner(); let couponData = Object.values(order.couponPointChanges).reduce((agg, pe) => { agg[pe.coupon_id] = Object.assign({}, pe, { - points: - pe.points - - order._getPointsCorrection(this.env.pos.program_by_id[pe.program_id]), + points: pe.points - order._getPointsCorrection(program_by_id[pe.program_id]), }); - const program = this.env.pos.program_by_id[pe.program_id]; + const program = program_by_id[pe.program_id]; if (program.is_nominative && partner) { agg[pe.coupon_id].partner_id = partner.id; } return agg; }, {}); for (const line of rewardLines) { - const reward = this.env.pos.reward_by_id[line.reward_id]; + const reward = reward_by_id[line.reward_id]; if (!couponData[line.coupon_id]) { couponData[line.coupon_id] = { points: 0, @@ -114,7 +114,7 @@ patch(PaymentScreen.prototype, "pos_loyalty.PaymentScreen", { // We actually do not care about coupons for 'current' programs that did not claim any reward, they will be lost if not validated couponData = Object.fromEntries( Object.entries(couponData).filter(([key, value]) => { - const program = this.env.pos.program_by_id[value.program_id]; + const program = program_by_id[value.program_id]; if (program.applies_on === "current") { return value.line_codes && value.line_codes.length; } @@ -128,7 +128,7 @@ patch(PaymentScreen.prototype, "pos_loyalty.PaymentScreen", { ]); if (payload.coupon_updates) { for (const couponUpdate of payload.coupon_updates) { - let dbCoupon = this.env.pos.couponCache[couponUpdate.old_id]; + let dbCoupon = couponCache[couponUpdate.old_id]; if (dbCoupon) { dbCoupon.id = couponUpdate.id; dbCoupon.balance = couponUpdate.points; @@ -142,14 +142,14 @@ patch(PaymentScreen.prototype, "pos_loyalty.PaymentScreen", { couponUpdate.points ); } - delete this.env.pos.couponCache[couponUpdate.old_id]; - this.env.pos.couponCache[couponUpdate.id] = dbCoupon; + delete couponCache[couponUpdate.old_id]; + couponCache[couponUpdate.id] = dbCoupon; } } // Update the usage count since it is checked based on local data if (payload.program_updates) { for (const programUpdate of payload.program_updates) { - const program = this.env.pos.program_by_id[programUpdate.program_id]; + const program = program_by_id[programUpdate.program_id]; if (program) { program.total_order_count = programUpdate.usages; } diff --git a/addons/pos_loyalty/static/src/js/ProductScreen.js b/addons/pos_loyalty/static/src/js/ProductScreen.js index 8ba36e56a31..5e6c45986cf 100644 --- a/addons/pos_loyalty/static/src/js/ProductScreen.js +++ b/addons/pos_loyalty/static/src/js/ProductScreen.js @@ -41,7 +41,7 @@ patch(ProductScreen.prototype, "pos_loyalty.ProductScreen", { !selectedLine.manual_reward && (key === "Backspace" || key === "Delete") ) { - const reward = this.env.pos.reward_by_id[selectedLine.reward_id]; + const reward = this.pos.globalState.reward_by_id[selectedLine.reward_id]; const { confirmed } = await this.popup.add(ConfirmPopup, { title: this.env._t("Deactivating reward"), body: sprintf( @@ -87,13 +87,14 @@ patch(ProductScreen.prototype, "pos_loyalty.ProductScreen", { } if (selectedLine.is_reward_line && val === "remove") { this.currentOrder.disabledRewards.add(selectedLine.reward_id); - const coupon = this.env.pos.couponCache[selectedLine.coupon_id]; + const { couponCache } = this.pos.globalState; + const coupon = couponCache[selectedLine.coupon_id]; if ( coupon && coupon.id > 0 && this.currentOrder.codeActivatedCoupons.find((c) => c.code === coupon.code) ) { - delete this.env.pos.couponCache[selectedLine.coupon_id]; + delete couponCache[selectedLine.coupon_id]; this.currentOrder.codeActivatedCoupons.splice( this.currentOrder.codeActivatedCoupons.findIndex((coupon) => { return coupon.id === selectedLine.coupon_id; diff --git a/addons/pos_loyalty/static/src/js/TicketScreen.js b/addons/pos_loyalty/static/src/js/TicketScreen.js index dcd094d81db..3648ff462e8 100644 --- a/addons/pos_loyalty/static/src/js/TicketScreen.js +++ b/addons/pos_loyalty/static/src/js/TicketScreen.js @@ -43,12 +43,12 @@ patch(TicketScreen.prototype, "pos_loyalty.TicketScreen", { ); }, _isEWalletGiftCard(orderline) { - const linkedProgramIds = this.env.pos.productId2ProgramIds[orderline.product.id]; + const linkedProgramIds = this.pos.globalState.productId2ProgramIds[orderline.product.id]; if (linkedProgramIds) { return linkedProgramIds.length > 0; } if (orderline.is_reward_line) { - const reward = this.env.pos.reward_by_id[orderline.reward_id]; + const reward = this.pos.globalState.reward_by_id[orderline.reward_id]; const program = reward && reward.program_id; if (program && ["gift_card", "ewallet"].includes(program.program_type)) { return true; diff --git a/addons/pos_loyalty/static/src/xml/ControlButtons/eWalletButton.xml b/addons/pos_loyalty/static/src/xml/ControlButtons/eWalletButton.xml index 8a9574439d5..477b5b9b643 100644 --- a/addons/pos_loyalty/static/src/xml/ControlButtons/eWalletButton.xml +++ b/addons/pos_loyalty/static/src/xml/ControlButtons/eWalletButton.xml @@ -2,7 +2,7 @@ - + diff --git a/addons/pos_loyalty/static/src/xml/PartnerLine.xml b/addons/pos_loyalty/static/src/xml/PartnerLine.xml index b1618b80b51..c4e1c2b1c74 100644 --- a/addons/pos_loyalty/static/src/xml/PartnerLine.xml +++ b/addons/pos_loyalty/static/src/xml/PartnerLine.xml @@ -3,7 +3,7 @@ - +
    diff --git a/addons/pos_mercury/static/src/js/PaymentScreen.js b/addons/pos_mercury/static/src/js/PaymentScreen.js index b7927f6c193..9d364dbf7c2 100644 --- a/addons/pos_mercury/static/src/js/PaymentScreen.js +++ b/addons/pos_mercury/static/src/js/PaymentScreen.js @@ -96,7 +96,7 @@ const lookUpCodeTransaction = { patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { setup() { this._super(...arguments); - if (this.env.pos.getOnlinePaymentMethods().length !== 0) { + if (this.pos.globalState.getOnlinePaymentMethods().length !== 0) { useBarcodeReader({ credit: this.credit_code_action, }); @@ -123,7 +123,7 @@ patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { }, _get_swipe_pending_line() { var i = 0; - var lines = this.env.pos.get_order().get_paymentlines(); + var lines = this.pos.globalState.get_order().get_paymentlines(); for (i = 0; i < lines.length; i++) { if (lines[i].mercury_swipe_pending) { @@ -135,7 +135,7 @@ patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { }, _does_credit_payment_line_exist(amount, card_number, card_brand, card_owner_name) { var i = 0; - var lines = this.env.pos.get_order().get_paymentlines(); + var lines = this.pos.globalState.get_order().get_paymentlines(); for (i = 0; i < lines.length; i++) { if ( @@ -191,7 +191,8 @@ patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { }, // Handler to manage the card reader string credit_code_transaction(parsed_result, old_deferred, retry_nr) { - var order = this.env.pos.get_order(); + const { globalState } = this.pos.globalState; + const order = globalState.get_order(); if (order.get_due(order.selected_paymentline) < 0) { this.popup.add(ErrorPopup, { title: this.env._t("Refunds not supported"), @@ -202,12 +203,11 @@ patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { return; } - if (this.env.pos.getOnlinePaymentMethods().length === 0) { + if (globalState.getOnlinePaymentMethods().length === 0) { return; } - var self = this; - var decodedMagtek = self.env.pos.decodeMagtek(parsed_result.code); + var decodedMagtek = globalState.decodeMagtek(parsed_result.code); if (!decodedMagtek) { this.popup.add(ErrorPopup, { @@ -219,13 +219,13 @@ patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { return; } - var swipe_pending_line = self._get_swipe_pending_line(); + var swipe_pending_line = this._get_swipe_pending_line(); var purchase_amount = 0; if (swipe_pending_line) { purchase_amount = swipe_pending_line.get_amount(); } else { - purchase_amount = self.env.pos.get_order().get_due(); + purchase_amount = globalState.get_order().get_due(); } var transaction = { @@ -233,7 +233,7 @@ patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { encrypted_block: decodedMagtek["encrypted_block"], transaction_type: "Credit", transaction_code: "Sale", - invoice_no: self.env.pos.get_order().uid.replace(/-/g, ""), + invoice_no: globalState.get_order().uid.replace(/-/g, ""), purchase: purchase_amount, payment_method_id: parsed_result.payment_method_id, }; @@ -255,15 +255,15 @@ patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { // FIXME POSREF timeout this.orm .call("pos_mercury.mercury_transaction", "do_payment", [transaction]) - .then(function (data) { + .then((data) => { // if not receiving a response from Vantiv, we should retry if (data === "timeout") { - self.retry_mercury_transaction( + this.retry_mercury_transaction( def, null, retry_nr, true, - self.credit_code_transaction, + this.credit_code_transaction, [parsed_result, def, retry_nr + 1] ); return; @@ -271,26 +271,26 @@ patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { if (data === "not setup") { def.resolve({ - message: self.env._t("Please setup your Vantiv merchant account."), + message: this.env._t("Please setup your Vantiv merchant account."), }); return; } if (data === "internal error") { def.resolve({ - message: self.env._t("Odoo error while processing transaction."), + message: this.env._t("Odoo error while processing transaction."), }); return; } - var response = self.env.pos.decodeMercuryResponse(data); + var response = globalState.decodeMercuryResponse(data); response.payment_method_id = parsed_result.payment_method_id; if (response.status === "Approved") { // AP* indicates a duplicate request, so don't add anything for those if ( response.message === "AP*" && - self._does_credit_payment_line_exist( + this._does_credit_payment_line_exist( response.authorize, decodedMagtek["number"], response.card_type, @@ -303,13 +303,13 @@ patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { }); } else { // If the payment is approved, add a payment line - var order = self.env.pos.get_order(); + var order = globalState.get_order(); if (swipe_pending_line) { order.select_paymentline(swipe_pending_line); } else { order.add_paymentline( - self.payment_methods_by_id[parsed_result.payment_method_id] + this.payment_methods_by_id[parsed_result.payment_method_id] ); } @@ -331,7 +331,7 @@ patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { if (response.message === "PARTIAL AP") { def.resolve({ - message: self.env._t("Partially approved"), + message: this.env._t("Partially approved"), auto_close: false, }); } else { @@ -347,12 +347,12 @@ patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { else { if (lookUpCodeTransaction["TimeoutError"][response.error]) { // recoverable error - self.retry_mercury_transaction( + this.retry_mercury_transaction( def, response, retry_nr, true, - self.credit_code_transaction, + this.credit_code_transaction, [parsed_result, def, retry_nr + 1] ); } else { @@ -364,13 +364,13 @@ patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { } } }) - .catch(function () { - self.retry_mercury_transaction( + .catch(() => { + this.retry_mercury_transaction( def, null, retry_nr, false, - self.credit_code_transaction, + this.credit_code_transaction, [parsed_result, def, retry_nr + 1] ); }); @@ -379,7 +379,7 @@ patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { return; }, credit_code_action(parsed_result) { - var online_payment_methods = this.env.pos.getOnlinePaymentMethods(); + var online_payment_methods = this.pos.globalState.getOnlinePaymentMethods(); if (online_payment_methods.length === 1) { parsed_result.payment_method_id = online_payment_methods[0].item; @@ -408,7 +408,7 @@ patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { } }, remove_paymentline_by_ref(line) { - this.env.pos.get_order().remove_paymentline(line); + this.pos.globalState.get_order().remove_paymentline(line); this.numberBuffer.reset(); }, do_reversal(line, is_voidsale, old_deferred, retry_nr) { @@ -467,7 +467,7 @@ patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { return; } - var response = self.env.pos.decodeMercuryResponse(data); + var response = self.pos.globalState.decodeMercuryResponse(data); if (!is_voidsale) { if (response.status != "Approved" || response.message != "REVERSED") { @@ -520,7 +520,7 @@ patch(PaymentScreen.prototype, "pos_mercury.PaymentScreen", { * @override */ addNewPaymentLine(paymentMethod) { - const order = this.env.pos.get_order(); + const order = this.pos.globalState.get_order(); const res = this._super(...arguments); if (res && paymentMethod.pos_mercury_config_id) { order.selected_paymentline.mercury_swipe_pending = true; diff --git a/addons/pos_restaurant/static/src/app/floor_screen/editable_table.js b/addons/pos_restaurant/static/src/app/floor_screen/editable_table.js index 0be5da3525b..fd3dded8c86 100644 --- a/addons/pos_restaurant/static/src/app/floor_screen/editable_table.js +++ b/addons/pos_restaurant/static/src/app/floor_screen/editable_table.js @@ -3,6 +3,7 @@ import { getLimits, useMovable, constrain } from "@point_of_sale/app/movable_hook"; import { onWillUnmount, useEffect, useRef, Component } from "@odoo/owl"; import { Table } from "./table"; +import { usePos } from "@point_of_sale/app/pos_hook"; const MIN_TABLE_SIZE = 30; // px @@ -16,7 +17,7 @@ export class EditableTable extends Component { }; setup() { - super.setup(); + this.pos = usePos(); useEffect(this._setElementStyle.bind(this)); this.root = useRef("root"); this.handles = { @@ -43,7 +44,7 @@ export class EditableTable extends Component { } onMoveStart() { - if (this.env.pos.floorPlanStyle == 'kanban') { + if (this.pos.globalState.floorPlanStyle == "kanban") { return; } this.startTable = { ...this.props.table }; @@ -59,7 +60,7 @@ export class EditableTable extends Component { } onMove({ dx, dy }) { - if (this.env.pos.floorPlanStyle == 'kanban') { + if (this.pos.globalState.floorPlanStyle == "kanban") { return; } const { minX, minY, maxX, maxY } = getLimits(this.root.el, this.props.limit.el); @@ -70,12 +71,12 @@ export class EditableTable extends Component { this.props.selectedTables[index].position_h = constrain(position_h + dx, minX, maxX); this.props.selectedTables[index].position_v = constrain(position_v + dy, minY, maxY); } - + this._setElementStyle(); } onResizeHandleMove([moveX, moveY], { dx, dy }) { - if (this.env.pos.floorPlanStyle == 'kanban') { + if (this.pos.globalState.floorPlanStyle == "kanban") { return; } // Working with min/max x and y makes constraints much easier to apply uniformly @@ -127,14 +128,18 @@ export class EditableTable extends Component { _setElementStyle() { const table = this.props.table; - if (this.env.pos.floorPlanStyle == 'kanban') { + if (this.pos.globalState.floorPlanStyle == "kanban") { const floor = table.floor; const index = floor.tables.indexOf(table); const minWidth = 100 + 20; const nbrHorizontal = Math.floor(window.innerWidth / minWidth); - const widthTable = (window.innerWidth - nbrHorizontal*10) / nbrHorizontal; - const position_h = widthTable * (index % nbrHorizontal) + 5 + (index % nbrHorizontal) * 10; - const position_v = widthTable * Math.floor(index / nbrHorizontal) + 5 + Math.floor(index / nbrHorizontal) * 10; + const widthTable = (window.innerWidth - nbrHorizontal * 10) / nbrHorizontal; + const position_h = + widthTable * (index % nbrHorizontal) + 5 + (index % nbrHorizontal) * 10; + const position_v = + widthTable * Math.floor(index / nbrHorizontal) + + 5 + + Math.floor(index / nbrHorizontal) * 10; Object.assign(this.root.el.style, { left: `${position_h}px`, @@ -145,7 +150,7 @@ export class EditableTable extends Component { "line-height": `${widthTable}px`, "border-radius": table.shape === "round" ? "1000px" : "3px", "font-size": widthTable >= 150 ? "32px" : "16px", - "opacity": "0.7", + opacity: "0.7", }); return; } diff --git a/addons/pos_restaurant/static/src/app/floor_screen/editable_table.xml b/addons/pos_restaurant/static/src/app/floor_screen/editable_table.xml index 6c38ba00c77..779b2ec4b3a 100644 --- a/addons/pos_restaurant/static/src/app/floor_screen/editable_table.xml +++ b/addons/pos_restaurant/static/src/app/floor_screen/editable_table.xml @@ -9,7 +9,7 @@ - +
    diff --git a/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.js b/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.js index 51a692a8a34..d65bf59e261 100644 --- a/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.js +++ b/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.js @@ -28,7 +28,7 @@ export class FloorScreen extends Component { this.pos = usePos(); this.popup = useService("popup"); this.orm = useService("orm"); - const floor = this.props.floor ? this.props.floor : this.env.pos.floors[0]; + const floor = this.props.floor || this.pos.globalState.floors[0]; this.state = useState({ selectedFloorId: floor ? floor.id : null, selectedTableIds: [], @@ -36,11 +36,11 @@ export class FloorScreen extends Component { floorMapScrollTop: 0, isColorPicker: false, }); - if (!this.env.pos.floorPlanStyle) { + if (!this.pos.globalState.floorPlanStyle) { if (this.env.isMobile) { - this.env.pos.floorPlanStyle = "kanban"; + this.pos.globalState.floorPlanStyle = "kanban"; } else { - this.env.pos.floorPlanStyle = "default"; + this.pos.globalState.floorPlanStyle = "default"; } } this.floorMapRef = useRef("floor-map-ref"); @@ -53,7 +53,7 @@ export class FloorScreen extends Component { onPatched() { this.floorMapRef.el.style.background = this.state.floorBackground; this.addFloorRef.el.style.background = this.state.floorBackground; - if (!this.env.pos.isEditMode && this.env.pos.floors.length > 0) { + if (!this.pos.globalState.isEditMode && this.pos.globalState.floors.length > 0) { this.addFloorRef.el.style.display = "none"; } else { this.addFloorRef.el.style.display = "initial"; @@ -64,7 +64,7 @@ export class FloorScreen extends Component { this.pos.openCashControl(); this.floorMapRef.el.style.background = this.state.floorBackground; this.addFloorRef.el.style.background = this.state.floorBackground; - if (!this.env.pos.isEditMode && this.env.pos.floors.length > 0) { + if (!this.pos.globalState.isEditMode && this.pos.globalState.floors.length > 0) { this.addFloorRef.el.style.display = "none"; } else { this.addFloorRef.el.style.display = "initial"; @@ -249,20 +249,21 @@ export class FloorScreen extends Component { delete tableCopy.floor; const tableId = await this.orm.call("restaurant.table", "create_from_ui", [tableCopy]); table.id = tableId; - this.env.pos.tables_by_id[tableId] = table; + this.pos.globalState.tables_by_id[tableId] = table; } async _renameFloor(floorId, newName) { await this.orm.call("restaurant.floor", "rename_floor", [floorId, newName]); } async _tableLongpolling() { - if (this.env.pos.isEditMode) { + const { globalState } = this.pos; + if (globalState.isEditMode) { return; } const result = await this.orm.call("pos.config", "get_tables_order_count", [ - this.env.pos.config.id, + globalState.config.id, ]); for (const table of result) { - if (!(table.id in this.env.pos.tables_by_id)) { + if (!(table.id in globalState.tables_by_id)) { //We enter this condition if, after loading our PoS, a table is deleted on a PoS and not on another. //This will lead in receiving information on orders from a table that we do not have. //If we do not have a table in the PoS but still receive information about it, we reload the tables @@ -270,13 +271,13 @@ export class FloorScreen extends Component { const result = await this.orm.call("pos.session", "get_pos_ui_restaurant_floor", [ [odoo.pos_session_id], ]); - if (this.env.pos.config.module_pos_restaurant) { - this.env.pos.floors = result; - this.env.pos.loadRestaurantFloor(); + if (globalState.config.module_pos_restaurant) { + globalState.floors = result; + globalState.loadRestaurantFloor(); } } - const table_obj = this.env.pos.tables_by_id[table.id]; - const unsynced_orders = this.env.pos.getTableOrders(table_obj.id).filter( + const table_obj = globalState.tables_by_id[table.id]; + const unsynced_orders = globalState.getTableOrders(table_obj.id).filter( (o) => o.server_id === undefined && (o.orderlines.length !== 0 || o.paymentlines.length !== 0) && @@ -288,7 +289,7 @@ export class FloorScreen extends Component { } get activeFloor() { return this.state.selectedFloorId - ? this.env.pos.floors_by_id[this.state.selectedFloorId] + ? this.pos.globalState.floors_by_id[this.state.selectedFloorId] : null; } get activeTables() { @@ -300,12 +301,12 @@ export class FloorScreen extends Component { get selectedTables() { const tables = []; this.state.selectedTableIds.forEach((id) => { - tables.push(this.env.pos.tables_by_id[id]); + tables.push(this.pos.globalState.tables_by_id[id]); }); return tables; } get nbrFloors() { - return this.env.pos.floors.length; + return this.pos.globalState.floors.length; } movePinch(hypot) { const delta = hypot / this.scalehypot; @@ -333,8 +334,8 @@ export class FloorScreen extends Component { this.state.selectedTableIds = []; } toggleEditMode() { - this.env.pos.toggleEditMode(); - if (!this.env.pos.isEditMode && this.env.pos.floors.length > 0) { + this.pos.globalState.toggleEditMode(); + if (!this.pos.globalState.isEditMode && this.pos.globalState.floors.length > 0) { this.addFloorRef.el.style.display = "none"; } else { this.addFloorRef.el.style.display = "initial"; @@ -342,7 +343,8 @@ export class FloorScreen extends Component { this.state.selectedTableIds = []; } async onSelectTable(table, ev) { - if (this.env.pos.isEditMode) { + const { globalState } = this.pos; + if (globalState.isEditMode) { if (ev.ctrlKey || ev.metaKey) { this.state.selectedTableIds.push(table.id); } else { @@ -350,11 +352,11 @@ export class FloorScreen extends Component { this.state.selectedTableIds.push(table.id); } } else { - if (this.env.pos.orderToTransfer) { - await this.env.pos.transferTable(table); + if (globalState.orderToTransfer) { + await globalState.transferTable(table); } else { try { - await this.env.pos.setTable(table); + await globalState.setTable(table); } catch (e) { if (!(e.message instanceof ConnectionLostError)) { throw e; @@ -363,7 +365,7 @@ export class FloorScreen extends Component { Promise.reject(e); } } - const order = this.env.pos.get_order(); + const order = globalState.get_order(); this.pos.showScreen(order.get_screen_data().name); } } @@ -377,15 +379,16 @@ export class FloorScreen extends Component { if (!confirmed) { return; } + const { globalState } = this.pos; const floor = await this.orm.call("restaurant.floor", "create_from_ui", [ newName, "#ACADAD", - this.env.pos.config.id, + globalState.config.id, ]); - this.env.pos.floors_by_id[floor.id] = floor; - this.env.pos.floors.push(floor); + globalState.floors_by_id[floor.id] = floor; + globalState.floors.push(floor); this.selectFloor(floor); - this.env.pos.isEditMode = true; + globalState.isEditMode = true; } async createTable() { const newTable = await this._createTableHelper(); @@ -396,16 +399,17 @@ export class FloorScreen extends Component { } async duplicateTableOrFloor() { if (this.selectedTables.length == 0) { + const { globalState } = this.pos; const floor = this.activeFloor; const tables = this.activeFloor.tables; const newFloorName = floor.name + " (copy)"; const newFloor = await this.orm.call("restaurant.floor", "create_from_ui", [ newFloorName, floor.background_color, - this.env.pos.config.id, + globalState.config.id, ]); - this.env.pos.floors_by_id[newFloor.id] = newFloor; - this.env.pos.floors.push(newFloor); + globalState.floors_by_id[newFloor.id] = newFloor; + globalState.floors.push(newFloor); this.selectFloor(newFloor); for (const table of tables) { await this._createTableHelper(table, true); @@ -491,7 +495,6 @@ export class FloorScreen extends Component { selectedTable.shape = form; await this._save(selectedTable); }); - this.render(); } async setTableColor(color) { const selectedTables = this.selectedTables; @@ -499,7 +502,6 @@ export class FloorScreen extends Component { selectedTable.color = color; await this._save(selectedTable); }); - this.render(); this.state.isColorPicker = false; } async setFloorColor(color) { @@ -514,6 +516,7 @@ export class FloorScreen extends Component { this.state.isColorPicker = !this.state.isColorPicker; } async deleteFloorOrTable() { + const { globalState } = this.pos; if (this.selectedTables.length == 0) { const { confirmed } = await this.popup.add(ConfirmPopup, { title: `Removing floor ${this.activeFloor.name}`, @@ -528,28 +531,28 @@ export class FloorScreen extends Component { const originalSelectedFloorId = this.activeFloor.id; await this.orm.call("restaurant.floor", "deactivate_floor", [ originalSelectedFloorId, - this.env.pos.pos_session.id, + globalState.pos_session.id, ]); - const floor = this.env.pos.floors_by_id[originalSelectedFloorId]; - const orderList = [...this.env.pos.get_order_list()]; + const floor = globalState.floors_by_id[originalSelectedFloorId]; + const orderList = [...globalState.get_order_list()]; for (const order of orderList) { if (floor.table_ids.includes(order.tableId)) { - this.env.pos.removeOrder(order, false); + globalState.removeOrder(order, false); } } floor.table_ids.forEach((tableId) => { - delete this.env.pos.tables_by_id[tableId]; + delete globalState.tables_by_id[tableId]; }); - delete this.env.pos.floors_by_id[originalSelectedFloorId]; - this.env.pos.floors = this.env.pos.floors.filter( + delete globalState.floors_by_id[originalSelectedFloorId]; + globalState.floors = globalState.floors.filter( (floor) => floor.id != originalSelectedFloorId ); - this.env.pos.TICKET_SCREEN_STATE.syncedOrders.cache = {}; - if (this.env.pos.floors.length > 0) { - this.selectFloor(this.env.pos.floors[0]); + globalState.TICKET_SCREEN_STATE.syncedOrders.cache = {}; + if (globalState.floors.length > 0) { + this.selectFloor(globalState.floors[0]); } else { - this.env.pos.isEditMode = false; - this.env.pos.floorPlanStyle = "default"; + globalState.isEditMode = false; + globalState.floorPlanStyle = "default"; this.state.floorBackground = null; } return; @@ -568,17 +571,17 @@ export class FloorScreen extends Component { ]); if (!response) { //remove order not send to server - for (const order of this.env.pos.get_order_list()) { + for (const order of globalState.get_order_list()) { if (order.tableId == id) { - this.env.pos.removeOrder(order, false); + globalState.removeOrder(order, false); } } - this.env.pos.tables_by_id[id].active = false; + globalState.tables_by_id[id].active = false; await this.orm.call("restaurant.table", "create_from_ui", [ { active: false, id: id }, ]); this.activeFloor.tables = this.activeTables.filter((table) => table.id !== id); - delete this.env.pos.tables_by_id[id]; + delete globalState.tables_by_id[id]; } else { await this.popup.add(ErrorPopup, { title: this.env._t("Delete Error"), @@ -600,7 +603,7 @@ export class FloorScreen extends Component { if (equalsCheck(this.state.selectedTableIds, originalSelectedTableIds)) { this.state.selectedTableIds = []; } - this.env.pos.TICKET_SCREEN_STATE.syncedOrders.cache = {}; + globalState.TICKET_SCREEN_STATE.syncedOrders.cache = {}; } } diff --git a/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.xml b/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.xml index 5823efc6c2e..4a9130b477a 100644 --- a/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.xml +++ b/addons/pos_restaurant/static/src/app/floor_screen/floor_screen.xml @@ -3,7 +3,7 @@
    -
    - + @@ -29,7 +29,7 @@ class="floor-map" t-ref="floor-map-ref" > - +
    No tables available,
    ADD your first table
    diff --git a/addons/pos_restaurant/static/src/app/floor_screen/table.js b/addons/pos_restaurant/static/src/app/floor_screen/table.js index 9d3f0298ff2..4ea3d3a9644 100644 --- a/addons/pos_restaurant/static/src/app/floor_screen/table.js +++ b/addons/pos_restaurant/static/src/app/floor_screen/table.js @@ -1,6 +1,7 @@ /** @odoo-module */ import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; export class Table extends Component { static template = "pos_restaurant.Table"; @@ -22,17 +23,24 @@ export class Table extends Component { }, }; + setup() { + this.pos = usePos(); + } get style() { const table = this.props.table; - if (this.env.pos.floorPlanStyle == "kanban") { + if (this.pos.globalState.floorPlanStyle == "kanban") { const floor = table.floor; const index = floor.tables.indexOf(table); const minWidth = 100 + 20; const nbrHorizontal = Math.floor(window.innerWidth / minWidth); - const widthTable = (window.innerWidth - nbrHorizontal*10) / nbrHorizontal; - const position_h = widthTable * (index % nbrHorizontal) + 5 + (index % nbrHorizontal) * 10; - const position_v = widthTable * Math.floor(index / nbrHorizontal) + 5 + Math.floor(index / nbrHorizontal) * 10; + const widthTable = (window.innerWidth - nbrHorizontal * 10) / nbrHorizontal; + const position_h = + widthTable * (index % nbrHorizontal) + 5 + (index % nbrHorizontal) * 10; + const position_v = + widthTable * Math.floor(index / nbrHorizontal) + + 5 + + Math.floor(index / nbrHorizontal) * 10; return ` width: ${widthTable}px; height: ${widthTable}px; @@ -57,20 +65,20 @@ export class Table extends Component { } } get fill() { - const customerCount = this.env.pos.getCustomerCount(this.props.table.id); + const customerCount = this.pos.globalState.getCustomerCount(this.props.table.id); return Math.min(1, Math.max(0, customerCount / this.props.table.seats)); } get orderCount() { const table = this.props.table; return table.order_count !== undefined ? table.order_count - : this.env.pos + : this.pos.globalState .getTableOrders(table.id) .filter((o) => o.orderlines.length !== 0 || o.paymentlines.length !== 0).length; } get orderCountClass() { const countClass = { "order-count": true }; - if (this.env.pos.orderPreparationCategories.size) { + if (this.pos.globalState.orderPreparationCategories.size) { const notifications = this._getNotifications(); countClass["notify-printing"] = notifications.printing; countClass["notify-skipped"] = notifications.skipped; @@ -78,10 +86,12 @@ export class Table extends Component { return countClass; } get customerCountDisplay() { - return `${this.env.pos.getCustomerCount(this.props.table.id)}/${this.props.table.seats}`; + return `${this.pos.globalState.getCustomerCount(this.props.table.id)}/${ + this.props.table.seats + }`; } _getNotifications() { - const orders = this.env.pos.getTableOrders(this.props.table.id); + const orders = this.pos.globalState.getTableOrders(this.props.table.id); let hasChangesCount = 0; let hasSkippedCount = 0; diff --git a/addons/pos_restaurant/static/src/app/navbar/BackToFloorButton.js b/addons/pos_restaurant/static/src/app/navbar/BackToFloorButton.js index 85d93ae11ff..27e0d4f97a1 100644 --- a/addons/pos_restaurant/static/src/app/navbar/BackToFloorButton.js +++ b/addons/pos_restaurant/static/src/app/navbar/BackToFloorButton.js @@ -11,7 +11,7 @@ export class BackToFloorButton extends Component { this.pos = usePos(); } get table() { - return this.env.pos.table; + return this.pos.globalState.table; } get floor() { return this.table ? this.table.floor : null; diff --git a/addons/pos_restaurant/static/src/app/navbar/navbar.js b/addons/pos_restaurant/static/src/app/navbar/navbar.js index 80d3810247f..08df6c27b74 100644 --- a/addons/pos_restaurant/static/src/app/navbar/navbar.js +++ b/addons/pos_restaurant/static/src/app/navbar/navbar.js @@ -11,22 +11,23 @@ patch(Navbar.prototype, "pos_restaurant.Navbar", { * is floor screen, then the order count should be based on all the orders. */ get orderCount() { - if (!this.env.pos || !this.env.pos.config) { - return 0; - } - if (this.env.pos.config.module_pos_restaurant && this.env.pos.table) { - return this.env.pos.getTableOrders(this.env.pos.table.id).length; + const { globalState } = this.pos; + if (globalState.config.module_pos_restaurant && globalState.table) { + return globalState.getTableOrders(globalState.table.id).length; } return this._super(...arguments); }, _shouldLoadOrders() { - return this._super() || (this.env.pos.config.module_pos_restaurant && !this.env.pos.table); + return ( + this._super() || + (this.pos.globalState.config.module_pos_restaurant && !this.pos.globalState.table) + ); }, onSwitchButtonClick() { - this.env.pos.floorPlanStyle = - this.env.pos.floorPlanStyle == "kanban" ? "default" : "kanban"; + this.pos.globalState.floorPlanStyle = + this.pos.globalState.floorPlanStyle == "kanban" ? "default" : "kanban"; }, toggleEditMode() { - this.env.pos.toggleEditMode(); + this.pos.globalState.toggleEditMode(); }, }); diff --git a/addons/pos_restaurant/static/src/js/Screens/PaymentScreen.js b/addons/pos_restaurant/static/src/js/Screens/PaymentScreen.js index 91388055ab6..abcf22510af 100644 --- a/addons/pos_restaurant/static/src/js/Screens/PaymentScreen.js +++ b/addons/pos_restaurant/static/src/js/Screens/PaymentScreen.js @@ -13,7 +13,7 @@ patch(PaymentScreen.prototype, "pos_restaurant.PaymentScreen", { }, get nextScreen() { const order = this.currentOrder; - if (!this.env.pos.config.set_tip_after_payment || order.is_tipped) { + if (!this.pos.globalState.config.set_tip_after_payment || order.is_tipped) { return this._super(...arguments); } // Take the first payment method as the main payment. diff --git a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/OrderlineNoteButton.js b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/OrderlineNoteButton.js index 0409f576dfe..64f9bb7bcf3 100644 --- a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/OrderlineNoteButton.js +++ b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/OrderlineNoteButton.js @@ -4,16 +4,17 @@ import { ProductScreen } from "@point_of_sale/js/Screens/ProductScreen/ProductSc import { useService } from "@web/core/utils/hooks"; import { TextAreaPopup } from "@point_of_sale/js/Popups/TextAreaPopup"; import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; export class OrderlineNoteButton extends Component { static template = "OrderlineNoteButton"; setup() { - super.setup(); + this.pos = usePos(); this.popup = useService("popup"); } get selectedOrderline() { - return this.env.pos.get_order().get_selected_orderline(); + return this.pos.globalState.get_order().get_selected_orderline(); } async click() { if (!this.selectedOrderline) { @@ -34,6 +35,6 @@ export class OrderlineNoteButton extends Component { ProductScreen.addControlButton({ component: OrderlineNoteButton, condition: function () { - return this.env.pos.config.iface_orderline_notes; + return this.pos.globalState.config.iface_orderline_notes; }, }); diff --git a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/PrintBillButton.js b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/PrintBillButton.js index 1c84e45b4f3..3ab74a31efe 100644 --- a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/PrintBillButton.js +++ b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/PrintBillButton.js @@ -12,7 +12,7 @@ export class PrintBillButton extends Component { this.pos = usePos(); } _isDisabled() { - const order = this.env.pos.get_order(); + const order = this.pos.globalState.get_order(); return order.get_orderlines().length === 0; } click() { @@ -23,6 +23,6 @@ export class PrintBillButton extends Component { ProductScreen.addControlButton({ component: PrintBillButton, condition: function () { - return this.env.pos.config.iface_printbill; + return this.pos.globalState.config.iface_printbill; }, }); diff --git a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/SplitBillButton.js b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/SplitBillButton.js index 177b85f34f6..90bdb93b9f4 100644 --- a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/SplitBillButton.js +++ b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/SplitBillButton.js @@ -8,11 +8,10 @@ export class SplitBillButton extends Component { static template = "SplitBillButton"; setup() { - super.setup(); this.pos = usePos(); } _isDisabled() { - const order = this.env.pos.get_order(); + const order = this.pos.globalState.get_order(); return ( order .get_orderlines() @@ -27,6 +26,6 @@ export class SplitBillButton extends Component { ProductScreen.addControlButton({ component: SplitBillButton, condition: function () { - return this.env.pos.config.iface_splitbill; + return this.pos.globalState.config.iface_splitbill; }, }); diff --git a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/TableGuestsButton.js b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/TableGuestsButton.js index e93ef0de357..cf4279cc258 100644 --- a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/TableGuestsButton.js +++ b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/TableGuestsButton.js @@ -6,16 +6,17 @@ import { NumberPopup } from "@point_of_sale/js/Popups/NumberPopup"; import { ErrorPopup } from "@point_of_sale/js/Popups/ErrorPopup"; import { Component } from "@odoo/owl"; import { sprintf } from "@web/core/utils/strings"; +import { usePos } from "@point_of_sale/app/pos_hook"; export class TableGuestsButton extends Component { static template = "TableGuestsButton"; setup() { - super.setup(); + this.pos = usePos(); this.popup = useService("popup"); } get currentOrder() { - return this.env.pos.get_order(); + return this.pos.globalState.get_order(); } get nGuests() { return this.currentOrder ? this.currentOrder.getCustomerCount() : 0; @@ -42,7 +43,7 @@ export class TableGuestsButton extends Component { }); return; } - this.env.pos.get_order().setCustomerCount(guestCount); + this.currentOrder.setCustomerCount(guestCount); } } } @@ -50,6 +51,6 @@ export class TableGuestsButton extends Component { ProductScreen.addControlButton({ component: TableGuestsButton, condition: function () { - return this.env.pos.config.module_pos_restaurant; + return this.pos.globalState.config.module_pos_restaurant; }, }); diff --git a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/TransferOrderButton.js b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/TransferOrderButton.js index 204837a4b23..960896763a7 100644 --- a/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/TransferOrderButton.js +++ b/addons/pos_restaurant/static/src/js/Screens/ProductScreen/ControlButtons/TransferOrderButton.js @@ -8,11 +8,10 @@ export class TransferOrderButton extends Component { static template = "TransferOrderButton"; setup() { - super.setup(); this.pos = usePos(); } async click() { - this.env.pos.setCurrentOrderToTransfer(); + this.pos.globalState.setCurrentOrderToTransfer(); this.pos.showScreen("FloorScreen"); } } @@ -20,6 +19,6 @@ export class TransferOrderButton extends Component { ProductScreen.addControlButton({ component: TransferOrderButton, condition: function () { - return this.env.pos.config.module_pos_restaurant; + return this.pos.globalState.config.module_pos_restaurant; }, }); diff --git a/addons/pos_restaurant/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js b/addons/pos_restaurant/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js index 2b0164e2831..7399f461fc6 100644 --- a/addons/pos_restaurant/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js +++ b/addons/pos_restaurant/static/src/js/Screens/ReceiptScreen/ReceiptScreen.js @@ -1,7 +1,6 @@ /** @odoo-module */ import { ReceiptScreen } from "@point_of_sale/js/Screens/ReceiptScreen/ReceiptScreen"; -import { usePos } from "@point_of_sale/app/pos_hook"; import { patch } from "@web/core/utils/patch"; import { onWillUnmount } from "@odoo/owl"; import { FloorScreen } from "@pos_restaurant/app/floor_screen/floor_screen"; @@ -13,30 +12,29 @@ patch(ReceiptScreen, "pos_restaurant.ReceiptScreen", { patch(ReceiptScreen.prototype, "pos_restaurant.ReceiptScreen", { setup() { this._super(...arguments); - this.pos = usePos(); onWillUnmount(() => { // When leaving the receipt screen to the floor screen the order is paid and can be removed if (this.pos.mainScreen.component === FloorScreen) { - this.env.pos.removeOrder(this.currentOrder); + this.pos.globalState.removeOrder(this.currentOrder); } }); }, //@override _addNewOrder() { - if (!this.env.pos.config.module_pos_restaurant) { + if (!this.pos.globalState.config.module_pos_restaurant) { this._super(...arguments); } }, isResumeVisible() { - if (this.env.pos.config.module_pos_restaurant && this.env.pos.table) { - return this.env.pos.getTableOrders(this.env.pos.table.id).length > 1; + if (this.pos.globalState.config.module_pos_restaurant && this.pos.globalState.table) { + return this.pos.globalState.getTableOrders(this.pos.globalState.table.id).length > 1; } return this._super(...arguments); }, //@override get nextScreen() { - if (this.env.pos.config.module_pos_restaurant) { - const table = this.env.pos.table; + if (this.pos.globalState.config.module_pos_restaurant) { + const table = this.pos.globalState.table; return { name: "FloorScreen", props: { floor: table ? table.floor : null } }; } else { return this._super(...arguments); diff --git a/addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js b/addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js index 41997eb4592..cba35736b4c 100644 --- a/addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js +++ b/addons/pos_restaurant/static/src/js/Screens/SplitBillScreen/SplitBillScreen.js @@ -5,35 +5,28 @@ import { Order } from "@point_of_sale/js/models"; import { SplitOrderline } from "./SplitOrderline"; import { registry } from "@web/core/registry"; import { usePos } from "@point_of_sale/app/pos_hook"; -import { Component, useState, onMounted } from "@odoo/owl"; +import { Component, useState } from "@odoo/owl"; export class SplitBillScreen extends Component { static template = "SplitBillScreen"; static components = { SplitOrderline }; setup() { - super.setup(); this.pos = usePos(); - this.splitlines = useState(this._initSplitLines(this.env.pos.get_order())); + this.splitlines = useState(this._initSplitLines(this.pos.globalState.get_order())); this.newOrderLines = {}; this.newOrder = undefined; this._isFinal = false; - onMounted(() => { - // Should create the new order outside of the constructor because - // sequence_number of pos_session is modified. which will trigger - // rerendering which will rerender this screen and will be infinite loop. - this.newOrder = new Order( - {}, - { - pos: this.env.pos, - temporary: true, - } - ); - this.render(); - }); + this.newOrder = new Order( + {}, + { + pos: this.pos.globalState, + temporary: true, + } + ); } get currentOrder() { - return this.env.pos.get_order(); + return this.pos.globalState.get_order(); } get orderlines() { return this.currentOrder.get_orderlines(); @@ -59,13 +52,14 @@ export class SplitBillScreen extends Component { this.newOrder.set_screen_data({ name: "PaymentScreen" }); + const { globalState } = this.pos; // 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.env.pos.orderPreparationCategories.size) { + if (globalState.orderPreparationCategories.size) { this.currentOrder.updateLastOrderChange(); this.newOrder.updateLastOrderChange(); } @@ -75,9 +69,9 @@ export class SplitBillScreen extends Component { this.currentOrder.setCustomerCount(newCustomerCount || 1); this.currentOrder.set_screen_data({ name: "ProductScreen" }); - const reactiveNewOrder = this.env.pos.makeOrderReactive(this.newOrder); - this.env.pos.orders.add(reactiveNewOrder); - this.env.pos.selectedOrder = reactiveNewOrder; + const reactiveNewOrder = globalState.makeOrderReactive(this.newOrder); + globalState.orders.add(reactiveNewOrder); + globalState.selectedOrder = reactiveNewOrder; } this.pos.showScreen("PaymentScreen"); } @@ -97,7 +91,7 @@ export class SplitBillScreen extends Component { let totalQuantity = 0; - this.env.pos + this.pos.globalState .get_order() .get_orderlines() .forEach(function (orderLine) { @@ -143,7 +137,7 @@ export class SplitBillScreen extends Component { } } _isFullPayOrder() { - const order = this.env.pos.get_order(); + const order = this.pos.globalState.get_order(); let full = true; const splitlines = this.splitlines; const groupedLines = _.groupBy(order.get_orderlines(), (line) => line.get_product().id); @@ -167,7 +161,7 @@ export class SplitBillScreen extends Component { return full; } _setQuantityOnCurrentOrder() { - const order = this.env.pos.get_order(); + const order = this.pos.globalState.get_order(); for (var id in this.splitlines) { var split = this.splitlines[id]; var line = this.currentOrder.get_orderline(parseInt(id)); diff --git a/addons/pos_restaurant/static/src/js/Screens/TicketScreen.js b/addons/pos_restaurant/static/src/js/Screens/TicketScreen.js index 324921cbf33..f8c3d2a3ce1 100644 --- a/addons/pos_restaurant/static/src/js/Screens/TicketScreen.js +++ b/addons/pos_restaurant/static/src/js/Screens/TicketScreen.js @@ -9,7 +9,7 @@ import { Component, useState } from "@odoo/owl"; patch(TicketScreen.prototype, "pos_restaurant.TicketScreen", { _getScreenToStatusMap() { return Object.assign(this._super(...arguments), { - PaymentScreen: this.env.pos.config.set_tip_after_payment + PaymentScreen: this.pos.globalState.config.set_tip_after_payment ? "OPEN" : this._super(...arguments).PaymentScreen, TipScreen: "TIPPING", @@ -22,7 +22,7 @@ patch(TicketScreen.prototype, "pos_restaurant.TicketScreen", { }, //@override _getSearchFields() { - if (!this.env.pos.config.module_pos_restaurant) { + if (!this.pos.globalState.config.module_pos_restaurant) { return this._super(...arguments); } return Object.assign({}, this._super(...arguments), { @@ -34,23 +34,23 @@ patch(TicketScreen.prototype, "pos_restaurant.TicketScreen", { }); }, async _setOrder(order) { - if (!this.env.pos.config.module_pos_restaurant || this.env.pos.table) { - this._super(order); - } else { - // we came from the FloorScreen - const orderTable = order.getTable(); - await this.env.pos.setTable(orderTable, order.uid); - this.close(); + const { globalState } = this.pos; + if (!globalState.config.module_pos_restaurant || globalState.table) { + return this._super(...arguments); } + // we came from the FloorScreen + const orderTable = order.getTable(); + await globalState.setTable(orderTable, order.uid); + this.close(); }, get allowNewOrders() { - return this.env.pos.config.module_pos_restaurant - ? Boolean(this.env.pos.table) + return this.pos.globalState.config.module_pos_restaurant + ? Boolean(this.pos.globalState.table) : this._super(...arguments); }, _getOrderList() { - if (this.env.pos.table) { - return this.env.pos.getTableOrders(this.env.pos.table.id); + if (this.pos.globalState.table) { + return this.pos.globalState.getTableOrders(this.pos.globalState.table.id); } return this._super(...arguments); }, @@ -58,7 +58,7 @@ patch(TicketScreen.prototype, "pos_restaurant.TicketScreen", { // set tip in each order for (const order of this.getFilteredOrderList()) { const tipAmount = parseFloat(order.uiState.TipScreen.inputTipAmount || "0"); - const serverId = this.env.pos.validated_orders_name_server_id_map[order.name]; + const serverId = this.pos.globalState.validated_orders_name_server_id_map[order.name]; if (!serverId) { console.warn( `${order.name} is not yet sync. Sync it to server before setting a tip.` @@ -73,27 +73,29 @@ patch(TicketScreen.prototype, "pos_restaurant.TicketScreen", { }, //@override _selectNextOrder(currentOrder) { - if (this.env.pos.config.module_pos_restaurant && this.env.pos.table) { + if (this.pos.globalState.config.module_pos_restaurant && this.pos.globalState.table) { return this._super(...arguments); } }, //@override async onDeleteOrder(order) { const _super = this._super; - if (this.env.pos.config.module_pos_restaurant) { - this.env.pos.setOrderToRemove(order); - if (!this.env.pos.table) { - await this.env.pos._removeOrdersFromServer(); + const { globalState } = this.pos; + if (globalState.config.module_pos_restaurant) { + globalState.setOrderToRemove(order); + if (!globalState.table) { + await globalState._removeOrdersFromServer(); } } await _super(...arguments); }, async setTip(order, serverId, amount) { + const { globalState } = this.pos; try { const paymentline = order.get_paymentlines()[0]; if (paymentline.payment_method.payment_terminal) { paymentline.amount += amount; - this.env.pos.set_order(order, { silent: true }); + globalState.set_order(order, { silent: true }); await paymentline.payment_method.payment_terminal.send_payment_adjust( paymentline.cid ); @@ -108,10 +110,10 @@ patch(TicketScreen.prototype, "pos_restaurant.TicketScreen", { const tip_line = order.selected_orderline; await this.orm.call("pos.order", "set_tip", [serverId, tip_line.export_as_JSON()]); } - if (order === this.env.pos.get_order()) { + if (order === globalState.get_order()) { this._selectNextOrder(order); } - this.env.pos.removeOrder(order); + globalState.removeOrder(order); return true; } catch { const { confirmed } = await this.popup.add(ConfirmPopup, { @@ -126,7 +128,7 @@ patch(TicketScreen.prototype, "pos_restaurant.TicketScreen", { }, _getOrderStates() { const result = this._super(...arguments); - if (this.env.pos.config.set_tip_after_payment) { + if (this.pos.globalState.config.set_tip_after_payment) { result.delete("PAYMENT"); result.set("OPEN", { text: this.env._t("Open"), indented: true }); result.set("TIPPING", { text: this.env._t("Tipping"), indented: true }); @@ -135,15 +137,15 @@ patch(TicketScreen.prototype, "pos_restaurant.TicketScreen", { }, async onDoRefund() { const order = this.getSelectedSyncedOrder(); - if (this.env.pos.config.module_pos_restaurant && order) { - this.env.pos.setTable( - order.table ? order.table : Object.values(this.env.pos.tables_by_id)[0] + if (this.pos.globalState.config.module_pos_restaurant && order) { + this.pos.globalState.setTable( + order.table ? order.table : Object.values(this.pos.globalState.tables_by_id)[0] ); } this._super(...arguments); }, isDefaultOrderEmpty(order) { - if (this.env.pos.config.module_pos_restaurant) { + if (this.pos.globalState.config.module_pos_restaurant) { return false; } return this._super(...arguments); diff --git a/addons/pos_restaurant/static/src/js/Screens/TipScreen.js b/addons/pos_restaurant/static/src/js/Screens/TipScreen.js index b6316d68194..c07d83d11f3 100644 --- a/addons/pos_restaurant/static/src/js/Screens/TipScreen.js +++ b/addons/pos_restaurant/static/src/js/Screens/TipScreen.js @@ -37,7 +37,7 @@ export class TipScreen extends Component { return this._totalAmount; } get currentOrder() { - return this.env.pos.get_order(); + return this.pos.globalState.get_order(); } get percentageTips() { return [ @@ -48,8 +48,8 @@ export class TipScreen extends Component { } async validateTip() { const amount = parseFloat(this.state.inputTipAmount) || 0; - const order = this.env.pos.get_order(); - const serverId = this.env.pos.validated_orders_name_server_id_map[order.name]; + const order = this.pos.globalState.get_order(); + const serverId = this.pos.globalState.validated_orders_name_server_id_map[order.name]; if (!serverId) { this.popup.add(ErrorPopup, { @@ -84,7 +84,7 @@ export class TipScreen extends Component { order.set_tip(amount); order.finalized = true; - const paymentline = this.env.pos.get_order().get_paymentlines()[0]; + const paymentline = this.pos.globalState.get_order().get_paymentlines()[0]; if (paymentline.payment_method.payment_terminal) { paymentline.amount += amount; await paymentline.payment_method.payment_terminal.send_payment_adjust(paymentline.cid); @@ -96,16 +96,16 @@ export class TipScreen extends Component { this.goNextScreen(); } goNextScreen() { - this.env.pos.removeOrder(this.currentOrder); - if (!this.env.pos.config.module_pos_restaurant) { - this.env.pos.add_new_order(); + this.pos.globalState.removeOrder(this.currentOrder); + if (!this.pos.globalState.config.module_pos_restaurant) { + this.pos.globalState.add_new_order(); } const { name, props } = this.nextScreen; this.pos.showScreen(name, props); } get nextScreen() { - if (this.env.pos.config.module_pos_restaurant) { - const table = this.env.pos.table; + if (this.pos.globalState.config.module_pos_restaurant) { + const table = this.pos.globalState.table; return { name: "FloorScreen", props: { floor: table ? table.floor : null } }; } else { return { name: "ProductScreen" }; diff --git a/addons/pos_restaurant/static/src/xml/Screens/PaymentScreen/PaymentScreen.xml b/addons/pos_restaurant/static/src/xml/Screens/PaymentScreen/PaymentScreen.xml index 7a460e5ed9b..9e3d0d23342 100644 --- a/addons/pos_restaurant/static/src/xml/Screens/PaymentScreen/PaymentScreen.xml +++ b/addons/pos_restaurant/static/src/xml/Screens/PaymentScreen/PaymentScreen.xml @@ -3,18 +3,18 @@ - env.pos.config.set_tip_after_payment and !currentOrder.is_paid() + pos.globalState.config.set_tip_after_payment and !currentOrder.is_paid() - + Keep Open $0 - + Close Tab $0 diff --git a/addons/pos_restaurant/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml b/addons/pos_restaurant/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml index 93d8250f359..47f2ce1a25d 100644 --- a/addons/pos_restaurant/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml +++ b/addons/pos_restaurant/static/src/xml/Screens/ReceiptScreen/OrderReceipt.xml @@ -19,7 +19,7 @@ - +
    For convenience, we are providing the following gratuity calculations:
    diff --git a/addons/pos_restaurant/static/src/xml/Screens/TicketScreen.xml b/addons/pos_restaurant/static/src/xml/Screens/TicketScreen.xml index 2c4a4f1024d..bfeac51a083 100644 --- a/addons/pos_restaurant/static/src/xml/Screens/TicketScreen.xml +++ b/addons/pos_restaurant/static/src/xml/Screens/TicketScreen.xml @@ -3,11 +3,11 @@ -
    Table
    +
    Table
    Tip
    -
    +
    Table
    diff --git a/addons/pos_restaurant/static/src/xml/Screens/TipScreen.xml b/addons/pos_restaurant/static/src/xml/Screens/TipScreen.xml index f4b22b73691..c99d94e7f30 100644 --- a/addons/pos_restaurant/static/src/xml/Screens/TipScreen.xml +++ b/addons/pos_restaurant/static/src/xml/Screens/TipScreen.xml @@ -48,7 +48,7 @@
    - +
    diff --git a/addons/pos_sale/static/src/js/OrderManagementScreen/SaleOrderManagementControlPanel.js b/addons/pos_sale/static/src/js/OrderManagementScreen/SaleOrderManagementControlPanel.js index 688f301ea6c..92d08161235 100644 --- a/addons/pos_sale/static/src/js/OrderManagementScreen/SaleOrderManagementControlPanel.js +++ b/addons/pos_sale/static/src/js/OrderManagementScreen/SaleOrderManagementControlPanel.js @@ -3,6 +3,7 @@ import { useAutofocus, useService } from "@web/core/utils/hooks"; import { orderManagement } from "@point_of_sale/js/PosContext"; import { Component, useState } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; // NOTE: These are constants so that they are only instantiated once // and they can be used efficiently by the OrderManagementControlPanel. @@ -23,12 +24,12 @@ export class SaleOrderManagementControlPanel extends Component { static template = "SaleOrderManagementControlPanel"; setup() { - super.setup(); + this.pos = usePos(); this.saleOrderFetcher = useService("sale_order_fetcher"); this.orderManagementContext = useState(orderManagement); useAutofocus(); - const currentPartner = this.env.pos.get_order().get_partner(); + const currentPartner = this.pos.globalState.get_order().get_partner(); if (currentPartner) { this.orderManagementContext.searchString = currentPartner.name; } diff --git a/addons/pos_sale/static/src/js/OrderManagementScreen/SaleOrderManagementScreen.js b/addons/pos_sale/static/src/js/OrderManagementScreen/SaleOrderManagementScreen.js index cb1ce4b77e2..3ed23a814d3 100644 --- a/addons/pos_sale/static/src/js/OrderManagementScreen/SaleOrderManagementScreen.js +++ b/addons/pos_sale/static/src/js/OrderManagementScreen/SaleOrderManagementScreen.js @@ -17,6 +17,7 @@ import { NumberPopup } from "@point_of_sale/js/Popups/NumberPopup"; import { SaleOrderList } from "./SaleOrderList"; import { SaleOrderManagementControlPanel } from "./SaleOrderManagementControlPanel"; import { onMounted, useRef, useState } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; /** * ID getter to take into account falsy many2one value. @@ -33,6 +34,7 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo setup() { super.setup(); + this.pos = usePos(); this.popup = useService("popup"); this.orm = useService("orm"); this.root = useRef("root"); @@ -59,10 +61,10 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo this.saleOrderFetcher.setNPerPage(val); this.saleOrderFetcher.fetch(); } - _getSaleOrderOrigin(order) { + _getSaleOrderOrigin(order) { for (const line of order.get_orderlines()) { if (line.sale_order_origin_id) { - return line.sale_order_origin_id + return line.sale_order_origin_id; } } return false; @@ -91,6 +93,7 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo this.saleOrderFetcher.fetch(); } async onClickSaleOrder(clickedOrder) { + const { globalState } = this.pos; const { confirmed, payload: selectedOption } = await this.popup.add(SelectionPopup, { title: this.env._t("What do you want to do?"), list: [ @@ -109,7 +112,7 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo }); if (confirmed) { - let currentPOSOrder = this.env.pos.get_order(); + let currentPOSOrder = globalState.get_order(); const sale_order = await this._getSaleOrder(clickedOrder.id); clickedOrder.shipping_date = sale_order.shipping_date; @@ -123,22 +126,22 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo getId(linkedSO.partner_invoice_id) !== getId(sale_order.partner_invoice_id) || getId(linkedSO.partner_shipping_id) !== getId(sale_order.partner_shipping_id) ) { - currentPOSOrder = this.env.pos.add_new_order(); + currentPOSOrder = globalState.add_new_order(); this.notification.add(this.env._t("A new order has been created."), 4000); } } try { - await this.env.pos.load_new_partners(); + await globalState.load_new_partners(); } catch { // FIXME Universal catch seems ill advised } - const order_partner = this.env.pos.db.get_partner_by_id(sale_order.partner_id[0]); + const order_partner = globalState.db.get_partner_by_id(sale_order.partner_id[0]); if (order_partner) { currentPOSOrder.set_partner(order_partner); } else { try { - await this.env.pos._loadPartners([sale_order.partner_id[0]]); + await globalState._loadPartners([sale_order.partner_id[0]]); } catch { const title = this.env._t("Customer loading error"); const body = sprintf( @@ -148,11 +151,11 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo await this.popup.add(ErrorPopup, { title, body }); } currentPOSOrder.set_partner( - this.env.pos.db.get_partner_by_id(sale_order.partner_id[0]) + globalState.db.get_partner_by_id(sale_order.partner_id[0]) ); } const orderFiscalPos = sale_order.fiscal_position_id - ? this.env.pos.fiscal_positions.find( + ? globalState.fiscal_positions.find( (position) => position.id === sale_order.fiscal_position_id[0] ) : false; @@ -160,7 +163,7 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo currentPOSOrder.fiscal_position = orderFiscalPos; } const orderPricelist = sale_order.pricelist_id - ? this.env.pos.pricelists.find( + ? globalState.pricelists.find( (pricelist) => pricelist.id === sale_order.pricelist_id[0] ) : false; @@ -172,7 +175,7 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo // settle the order const lines = sale_order.order_line; const product_to_add_in_pos = lines - .filter((line) => !this.env.pos.db.get_product_by_id(line.product_id[0])) + .filter((line) => !globalState.db.get_product_by_id(line.product_id[0])) .map((line) => line.product_id[0]); if (product_to_add_in_pos.length) { const { confirmed } = await this.popup.add(ConfirmPopup, { @@ -184,7 +187,7 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo cancelText: this.env._t("No"), }); if (confirmed) { - await this.env.pos._addProducts(product_to_add_in_pos); + await globalState._addProducts(product_to_add_in_pos); } } @@ -202,16 +205,16 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo for (var i = 0; i < lines.length; i++) { const line = lines[i]; - if (!this.env.pos.db.get_product_by_id(line.product_id[0])) { + if (!globalState.db.get_product_by_id(line.product_id[0])) { continue; } const new_line = new Orderline( {}, { - pos: this.env.pos, - order: this.env.pos.get_order(), - product: this.env.pos.db.get_product_by_id(line.product_id[0]), + pos: globalState, + order: globalState.get_order(), + product: globalState.db.get_product_by_id(line.product_id[0]), description: line.name, price: line.price_unit, tax_ids: orderFiscalPos ? undefined : line.tax_id, @@ -224,8 +227,8 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo if ( new_line.get_product().tracking !== "none" && - (this.env.pos.picking_type.use_create_lots || - this.env.pos.picking_type.use_existing_lots) && + (globalState.picking_type.use_create_lots || + globalState.picking_type.use_existing_lots) && line.lot_names.length > 0 ) { // Ask once when `useLoadedLots` is undefined, then reuse it's value on the succeeding lines. @@ -253,39 +256,33 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo new_line.setQuantityFromSOL(line); new_line.set_unit_price(line.price_unit); new_line.set_discount(line.discount); - this.env.pos.get_order().add_orderline(new_line); + globalState.get_order().add_orderline(new_line); } } else { // apply a downpayment - if (this.env.pos.config.down_payment_product_id) { - let lines = sale_order.order_line; - const tab = []; - lines = lines.filter((line) => { - return ( - line.product_id[0] !== this.env.pos.config.down_payment_product_id[0] - ); + if (globalState.config.down_payment_product_id) { + const lines = sale_order.order_line.filter((line) => { + return line.product_id[0] !== globalState.config.down_payment_product_id[0]; }); - for (let i = 0; i < lines.length; i++) { - tab[i] = { - product_name: lines[i].product_id[1], - product_uom_qty: lines[i].product_uom_qty, - price_unit: lines[i].price_unit, - total: lines[i].price_total, - }; - } - let down_payment_product = this.env.pos.db.get_product_by_id( - this.env.pos.config.down_payment_product_id[0] + const tab = lines.map((line) => ({ + product_name: line.product_id[1], + product_uom_qty: line.product_uom_qty, + price_unit: line.price_unit, + total: line.price_total, + })); + let down_payment_product = globalState.db.get_product_by_id( + globalState.config.down_payment_product_id[0] ); if (!down_payment_product) { - await this.env.pos._addProducts([ - this.env.pos.config.down_payment_product_id[0], + await globalState._addProducts([ + globalState.config.down_payment_product_id[0], ]); - down_payment_product = this.env.pos.db.get_product_by_id( - this.env.pos.config.down_payment_product_id[0] + down_payment_product = globalState.db.get_product_by_id( + globalState.config.down_payment_product_id[0] ); } const down_payment_tax = - this.env.pos.taxes_by_id[down_payment_product.taxes_id] || false; + globalState.taxes_by_id[down_payment_product.taxes_id] || false; let down_payment; if (down_payment_tax) { down_payment = down_payment_tax.price_include @@ -302,7 +299,7 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo const popupSubtitle = this.env._t("Due balance: %s"); if (selectedOption == "dpAmount") { popupTitle = this.env._t("Down Payment"); - popupInputSuffix = this.env.pos.currency.symbol; + popupInputSuffix = globalState.currency.symbol; } else { popupTitle = this.env._t("Down Payment"); popupInputSuffix = "%"; @@ -361,8 +358,8 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo const new_line = new Orderline( {}, { - pos: this.env.pos, - order: this.env.pos.get_order(), + pos: globalState, + order: globalState.get_order(), product: down_payment_product, price: down_payment, price_automatically_set: true, @@ -371,7 +368,7 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo } ); new_line.set_unit_price(down_payment); - this.env.pos.get_order().add_orderline(new_line); + globalState.get_order().add_orderline(new_line); } else { const title = this.env._t("No down payment product"); const body = this.env._t( @@ -400,7 +397,7 @@ export class SaleOrderManagementScreen extends ControlButtonsMixin(IndependentTo "amount_unpaid", "picking_ids", "partner_shipping_id", - "partner_invoice_id" + "partner_invoice_id", ] ); diff --git a/addons/pos_six/static/app/navbar.xml b/addons/pos_six/static/app/navbar.xml index a469fb37320..5154f5682c3 100644 --- a/addons/pos_six/static/app/navbar.xml +++ b/addons/pos_six/static/app/navbar.xml @@ -3,7 +3,7 @@ - + diff --git a/addons/pos_six/static/src/js/BalanceButton.js b/addons/pos_six/static/src/js/BalanceButton.js index fb5937521ed..4949de911a2 100644 --- a/addons/pos_six/static/src/js/BalanceButton.js +++ b/addons/pos_six/static/src/js/BalanceButton.js @@ -1,12 +1,16 @@ /** @odoo-module */ import { Component } from "@odoo/owl"; +import { usePos } from "@point_of_sale/app/pos_hook"; export class BalanceButton extends Component { static template = "BalanceButton"; + setup() { + this.pos = usePos(); + } sendBalance() { - this.env.pos.payment_methods.map((pm) => { + this.pos.globalState.payment_methods.forEach((pm) => { if (pm.use_payment_terminal === "six") { pm.payment_terminal.send_balance(); }