diff --git a/__manifest__.py b/__manifest__.py index 6c84c2f..3423ade 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -24,6 +24,7 @@ Features 'assets': { 'point_of_sale._assets_pos': [ # Incremental rendering patches (existing) + 'pos_ui_optimization/static/src/app/services/pos_store_patch.js', 'pos_ui_optimization/static/src/app/components/order_display/order_display_patch.js', 'pos_ui_optimization/static/src/app/components/order_display/order_display_patch.xml', 'pos_ui_optimization/static/src/app/screens/product_screen/product_screen_patch.js', diff --git a/static/src/app/components/order_display/order_display_patch.js b/static/src/app/components/order_display/order_display_patch.js index be49fee..321fff1 100644 --- a/static/src/app/components/order_display/order_display_patch.js +++ b/static/src/app/components/order_display/order_display_patch.js @@ -4,7 +4,23 @@ import { OrderDisplay } from "@point_of_sale/app/components/order_display/order_ import { patch } from "@web/core/utils/patch"; import { useState, useEffect } from "@odoo/owl"; +OrderDisplay.props.order = { type: Object, optional: true }; + patch(OrderDisplay.prototype, { + get order() { + return this.props.order || { + lines: [], + prices: { taxDetails: { has_tax_groups: false } }, + currencyDisplayPriceExcl: "", + currencyAmountTaxes: "", + currencyDisplayPriceIncl: "", + general_customer_note: "", + internal_note: "", + config_id: {}, + currency: { id: null }, + }; + }, + setup() { super.setup(); // Use Object.assign to avoid overwriting state from other patches (e.g. pos_urban_piper) diff --git a/static/src/app/services/pos_store_patch.js b/static/src/app/services/pos_store_patch.js new file mode 100644 index 0000000..fbcca5e --- /dev/null +++ b/static/src/app/services/pos_store_patch.js @@ -0,0 +1,63 @@ +/** @odoo-module **/ + +import { PosStore } from "@point_of_sale/app/services/pos_store"; +import { patch } from "@web/core/utils/patch"; + +patch(PosStore.prototype, { + get productToDisplayByCateg() { + // We override this getter to remove Odoo's hardcoded 100-product category limit. + // Because our custom UI optimization module uses progressive rendering (lazy loading) + // on scroll, we can safely return the entire category's product list without risking + // browser freeze or UI lockups. + const sortedProducts = this.productsToDisplay; + if (!this.config.iface_group_by_categ) { + return sortedProducts.length ? [["0", sortedProducts]] : []; + } + + const results = []; + const searchWord = this.searchProductWord.trim(); + const byCateg = this.models["product.template"].toRaw().getAllBy("pos_categ_ids"); + const selectedCategoryIds = !this.selectedCategory + ? this.models["pos.category"].map((c) => c.id) + : this.selectedCategory.getAllChildren().map((c) => c.id); + + // Sorting in place the categories according to their sequence in the database + selectedCategoryIds.sort((a, b) => { + const categA = this.models["pos.category"].get(a); + const categB = this.models["pos.category"].get(b); + + // All category with a parent will be at the end + if (categA.parent_id && !categB.parent_id) { + return 1; + } else if (!categA.parent_id && categB.parent_id) { + return -1; + } + + return categA.sequence - categB.sequence; + }); + + if (!this.selectedCategory) { + // In case of no category selected, we want to display products without category in + // a "Without category" category at the end of the list. + const productWithoutCategory = sortedProducts.filter((p) => !p.pos_categ_ids.length); + byCateg["0"] = productWithoutCategory; + selectedCategoryIds.push("0"); + } + + for (const catId of selectedCategoryIds) { + const products = byCateg[catId] || []; + const filtered = searchWord + ? this.getProductsBySearchWord(searchWord, products) + : products; + + if (filtered.length) { + const sorted = this.orderProductBySequenceAndFav(filtered); + // Return the complete list instead of splicing to 100 items. + // Our lazy loading mechanism will handle rendering chunk-by-chunk. + results.push([catId, sorted]); + } + } + + return results; + } +}); diff --git a/static/src/scss/portrait.scss b/static/src/scss/portrait.scss index cc14fce..fb0d81f 100644 --- a/static/src/scss/portrait.scss +++ b/static/src/scss/portrait.scss @@ -99,6 +99,8 @@ flex-grow: 1 !important; flex-shrink: 1 !important; min-height: 0 !important; + overflow-y: auto !important; + -webkit-overflow-scrolling: touch; } }