feat: implement order pagination and reduce duration update frequency to optimize KDS performance

This commit is contained in:
Suherdy Yacob 2026-06-07 19:40:16 +07:00
parent 5e196ab48a
commit f097db007e
5 changed files with 103 additions and 0 deletions

View File

@ -87,6 +87,15 @@ Installation
3. Search for "POS KDS Stage Reset Fix" and install it.
4. No additional configuration is required.
Performance Optimization
------------------------
This module also optimizes the Preparation Display's rendering and idle CPU usage for low RAM devices:
- Order Pagination: Limits rendering to 16 order cards per page, significantly reducing DOM nodes.
- Pagination Controls: Adds Page Navigation buttons at the bottom of the main orders area.
- Timer Refresh Rate: Reduces the order age/duration update frequency from 1 second to 15 seconds.
Compatibility
-------------

View File

@ -21,6 +21,8 @@ and todo status of previously processed prep order lines.
'pos_preparation_display.assets': [
'pos_kds_fix/static/src/app/components/orderline/orderline_patch.js',
'pos_kds_fix/static/src/app/components/order/order_patch.js',
'pos_kds_fix/static/src/app/components/preparation_display/preparation_display_patch.js',
'pos_kds_fix/static/src/app/components/preparation_display/preparation_display_patch.xml',
],
},
'installable': True,

View File

@ -4,6 +4,19 @@ import { Order } from "@pos_enterprise/app/components/order/order";
import { patch } from "@web/core/utils/patch";
patch(Order.prototype, {
setup() {
super.setup();
if (this.interval) {
clearInterval(this.interval);
this.interval = setInterval(() => {
if (this.order && this.order.pos_order_id) {
this._updateDuration();
} else {
clearInterval(this.interval);
}
}, 15000); // Update every 15 seconds instead of 1 second
}
},
get pdisNotes() {
try {
return JSON.parse(this.order.pos_order_id.internal_note || "[]");

View File

@ -0,0 +1,40 @@
/** @odoo-module **/
import { PrepDisplay } from "@pos_enterprise/app/components/preparation_display/preparation_display";
import { patch } from "@web/core/utils/patch";
patch(PrepDisplay.prototype, {
setup() {
super.setup();
this.state.currentPage = 1;
this.state.pageSize = 16; // 16 orders per page
this.lastFilterState = "";
},
get totalPages() {
const orders = this.prepDisplay.filteredOrders || [];
return Math.max(1, Math.ceil(orders.length / this.state.pageSize));
},
get paginatedOrders() {
const orders = this.prepDisplay.filteredOrders || [];
const currentStageId = this.prepDisplay.selectedStageId;
const filterState = `${currentStageId}-${Array.from(this.prepDisplay.selectedCategoryIds).join(',')}-${Array.from(this.prepDisplay.selectedProductIds).join(',')}-${Array.from(this.prepDisplay.selectedTimeIds).join(',')}-${Array.from(this.prepDisplay.selectedPresetIds).join(',')}`;
if (this.lastFilterState !== filterState) {
this.lastFilterState = filterState;
this.state.currentPage = 1;
}
const totalPages = this.totalPages;
if (this.state.currentPage > totalPages) {
this.state.currentPage = totalPages;
}
const start = (this.state.currentPage - 1) * this.state.pageSize;
return orders.slice(start, start + this.state.pageSize);
},
changePage(offset) {
const targetPage = this.state.currentPage + offset;
if (targetPage >= 1 && targetPage <= this.totalPages) {
this.state.currentPage = targetPage;
}
}
});

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-inherit="pos_enterprise.PrepDisplay" t-inherit-mode="extension" owl="1">
<!-- Replace filteredOrders loop with paginatedOrders -->
<xpath expr="//t[@t-foreach='this.prepDisplay.filteredOrders']" position="attributes">
<attribute name="t-foreach">this.paginatedOrders</attribute>
</xpath>
<!-- Add d-flex flex-column to o_pdis_main_area to support pagination at the bottom -->
<xpath expr="//div[hasclass('o_pdis_main_area')]" position="attributes">
<attribute name="class">o_pdis_main_area w-100 h-100 overflow-hidden d-flex flex-column</attribute>
</xpath>
<!-- Remove h-100 from o_pdis_orders so it auto-shrinks to make space for pagination controls -->
<xpath expr="//div[hasclass('o_pdis_orders')]" position="attributes">
<attribute name="class">o_pdis_orders position-relative d-grid flex-grow-1 gap-3 text-reset p-3 overflow-auto</attribute>
</xpath>
<!-- Append pagination controls to main area -->
<xpath expr="//div[hasclass('o_pdis_main_area')]" position="inside">
<div t-if="this.totalPages > 1" class="o_pdis_pagination d-flex justify-content-between align-items-center bg-white border-top p-3 text-dark fs-4 fw-semibold shadow-sm">
<button class="btn btn-secondary btn-lg px-4"
t-att-disabled="this.state.currentPage === 1"
t-on-click="() => this.changePage(-1)">
<i class="fa fa-chevron-left me-2"/> Previous
</button>
<span class="align-self-center">
Page <t t-esc="this.state.currentPage"/> of <t t-esc="this.totalPages"/>
<span class="text-muted ms-2 fs-6">(Total <t t-esc="this.prepDisplay.filteredOrders.length"/> orders)</span>
</span>
<button class="btn btn-secondary btn-lg px-4"
t-att-disabled="this.state.currentPage === this.totalPages"
t-on-click="() => this.changePage(1)">
Next <i class="fa fa-chevron-right ms-2"/>
</button>
</div>
</xpath>
</t>
</templates>