From 9ee282b998c8dd9022f200ba5cc87cff0a63c502 Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Sun, 11 Jan 2026 17:46:31 +0000 Subject: [PATCH] Bug 41592: Add cross-register refund search to Point of Sale This patch adds a "Process refund" feature to the Point of Sale page, allowing staff to search for and refund transactions made at any register. Changes: - Add toolbar with "Process refund" button to pos/pay.tt - Add transaction search modal that searches by receipt number or transaction ID - Implement AJAX-based search using new /api/v1/account/credits endpoint - Display transaction details including total, date, and associated debits - Show warning when refunding transactions from different registers - Create reusable refund modal component (refund_modal.inc) with: * Transaction details summary (description, original charge, amount paid) * Payment method display (Cash/Card) * Original register information * Refund amount input with validation * Transaction type selector * Cash register selector (when applicable) * Note field for refund reason - Add JavaScript lookups to display human-readable descriptions instead of codes for both debit types and payment types - Auto-focus search input when modal opens - Filter out PAYOUT debits and already REFUNDED items The refund modal is now shared and can be reused by other pages (e.g., patron account page). It intelligently shows/hides fields based on context and available data. Requires the 'anonymous_refund' cash_management permission. Test plan: 1. Apply patch and rebuild: yarn build 2. Enable UseCashRegisters system preference 3. Create at least two cash registers for a branch 4. Make a POS sale at register A 5. Navigate to POS page 6. Click "Process refund" button 7. Search for transaction by receipt number 8. Verify transaction details are displayed correctly with proper descriptions 9. Click "Issue refund" on a debit 10. Verify refund modal shows: - Debit description (not code) - Original charge amount - Amount paid - Payment method (Cash/Card, not CASH/SIP00) - Register warning if different 11. Complete refund and verify success --- .../prog/en/includes/modals/refund_modal.inc | 90 +++++++ .../intranet-tmpl/prog/en/modules/pos/pay.tt | 236 ++++++++++++++++++ .../prog/en/modules/pos/register.tt | 6 +- .../intranet-tmpl/prog/js/refund_modal.js | 129 ++++++++++ pos/register.pl | 8 +- 5 files changed, 467 insertions(+), 2 deletions(-) create mode 100644 koha-tmpl/intranet-tmpl/prog/en/includes/modals/refund_modal.inc create mode 100644 koha-tmpl/intranet-tmpl/prog/js/refund_modal.js diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/modals/refund_modal.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/modals/refund_modal.inc new file mode 100644 index 00000000000..6bd4dfc8120 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/modals/refund_modal.inc @@ -0,0 +1,90 @@ + + + diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/pos/pay.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/pos/pay.tt index 4e0da24182c..a1fd4afd5b0 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/pos/pay.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/pos/pay.tt @@ -1,5 +1,6 @@ [% USE raw %] [% USE AdditionalContents %] +[% USE AuthorisedValues %] [% USE Asset %] [% USE Branches %] [% USE Koha %] @@ -7,6 +8,7 @@ [% USE TablesSettings %] [% USE Registers %] [% PROCESS 'i18n.inc' %] +[% PROCESS 'html_helpers.inc' %] [% SET footerjs = 1 %] [% INCLUDE 'doc-head-open.inc' %] [% SET registers = Registers.all( filters => { current_branch => 1 } ) %] @@ -33,6 +35,13 @@ [% END #/ WRAPPER sub-header.inc %] [% WRAPPER 'main-container.inc' aside='pos-menu' %] + + [% IF ( CAN_user_cash_management_anonymous_refund ) %] +
+ +
+ [% END %] +

Point of sale

[% IF ( registers.size == 0 ) %] @@ -240,6 +249,57 @@ + + + + +[% INCLUDE 'modals/refund_modal.inc' refund_form_action = '/cgi-bin/koha/pos/register.pl' registers = registers %] + [% IF payment_id && Koha.Preference('FinePaymentAutoPopup') %] @@ -247,8 +307,24 @@ [% MACRO jsinclude BLOCK %] [% INCLUDE 'format_price.inc' %] + [% INCLUDE 'js-date-format.inc' %] [% INCLUDE 'datatables.inc' %] + [% Asset.js("js/refund_modal.js") | $raw %] [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/pos/register.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/pos/register.tt index e01152f7515..2f459442ef0 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/pos/register.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/pos/register.tt @@ -52,6 +52,10 @@
You do not have permission to perform refund actions.
[% END %] + [% IF ( error_refund_not_found ) %] +
The account line you are trying to refund was not found.
+ [% END %] + [% IF ( CAN_user_cash_management_cashup ) %]
@@ -397,7 +401,7 @@