From 4b32aba9670d0de9dedd329d736c775a6c97c851 Mon Sep 17 00:00:00 2001 From: Suherdy Yacob Date: Mon, 8 Jun 2026 10:12:46 +0700 Subject: [PATCH] feat: restrict split or transfer of discount and manual adjustment lines in POS split bill screen --- README.md | 1 + static/src/app/models/pos_order_line.js | 20 +++++++++++++++++++ .../split_bill_screen/split_bill_screen.js | 13 ++++++++++++ .../split_bill_screen/split_bill_screen.xml | 8 ++++++++ 4 files changed, 42 insertions(+) create mode 100644 static/src/app/models/pos_order_line.js create mode 100644 static/src/app/screens/split_bill_screen/split_bill_screen.js create mode 100644 static/src/app/screens/split_bill_screen/split_bill_screen.xml diff --git a/README.md b/README.md index bb7448b..d9ffa8a 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ This Odoo 19 module enhances the security and auditability of the Point of Sale ## Features - **Mandatory PIN on Table Selection**: Prevents unauthorized access to tables. Every table selection triggers a PIN prompt to identify the employee taking the order. +- **Block Discount Split/Transfer**: Prevents discount lines (including reward lines, global discounts, and negative price/manual adjustment lines) from being manually split or transferred on the POS split bill screen. - **Mandatory PIN on Load Order**: Enforces PIN entry when a draft order is loaded/resumed from the Orders tab (`TicketScreen`). - **Mandatory PIN on Payment**: Requires PIN authentication before processing payments to ensure the transaction is handled by an authorized employee. - **Role-Based Payment Gating**: Cross-checks employee roles (using `pos_employee_role`) to prevent roles like 'waiter' from processing payments. diff --git a/static/src/app/models/pos_order_line.js b/static/src/app/models/pos_order_line.js new file mode 100644 index 0000000..012addd --- /dev/null +++ b/static/src/app/models/pos_order_line.js @@ -0,0 +1,20 @@ +import { PosOrderline } from "@point_of_sale/app/models/pos_order_line"; +import { patch } from "@web/core/utils/patch"; + +patch(PosOrderline.prototype, { + get isDiscountLine() { + return ( + this.is_reward_line || + (this.config.discount_product_id && this.product_id.id === this.config.discount_product_id.id) || + this.price_unit < 0 || + this.prices?.total_included < 0 + ); + }, + + isGlobalDiscountApplicable() { + if (this.isDiscountLine) { + return false; + } + return super.isGlobalDiscountApplicable(); + }, +}); diff --git a/static/src/app/screens/split_bill_screen/split_bill_screen.js b/static/src/app/screens/split_bill_screen/split_bill_screen.js new file mode 100644 index 0000000..e576632 --- /dev/null +++ b/static/src/app/screens/split_bill_screen/split_bill_screen.js @@ -0,0 +1,13 @@ +/** @odoo-module */ + +import { patch } from "@web/core/utils/patch"; +import { SplitBillScreen } from "@pos_restaurant/app/screens/split_bill_screen/split_bill_screen"; + +patch(SplitBillScreen.prototype, { + onClickLine(line) { + if (line.isDiscountLine) { + return; + } + super.onClickLine(...arguments); + } +}); diff --git a/static/src/app/screens/split_bill_screen/split_bill_screen.xml b/static/src/app/screens/split_bill_screen/split_bill_screen.xml new file mode 100644 index 0000000..726154f --- /dev/null +++ b/static/src/app/screens/split_bill_screen/split_bill_screen.xml @@ -0,0 +1,8 @@ + + + + + !line.isDiscountLine + + +