Bugzilla – Attachment 191254 Details for
Bug 41592
Add an enhanced workflow for refunds against anonymous transactions
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 41592: Refactor patron account page to use shared refund modal
6d0ae35.patch (text/plain), 10.63 KB, created by
Martin Renvoize (ashimema)
on 2026-01-12 13:13:47 UTC
(
hide
)
Description:
Bug 41592: Refactor patron account page to use shared refund modal
Filename:
MIME Type:
Creator:
Martin Renvoize (ashimema)
Created:
2026-01-12 13:13:47 UTC
Size:
10.63 KB
patch
obsolete
>From 6d0ae35c80d63b858f692a14d10f184a8a48071c Mon Sep 17 00:00:00 2001 >From: Martin Renvoize <martin.renvoize@openfifth.co.uk> >Date: Sun, 11 Jan 2026 17:46:57 +0000 >Subject: [PATCH] Bug 41592: Refactor patron account page to use shared refund > modal > >This patch refactors the patron account page (boraccount.tt) to use the >new shared refund modal component created in the previous commit, removing >duplicate code and providing a consistent refund experience across both >the Point of Sale and patron account pages. > >Changes: >- Replace inline refund modal with shared refund_modal.inc component >- Update modal population JavaScript to work with new modal structure: > * Parse amount and amountoutstanding as floats for proper formatting > * Populate transaction details fields (description, original charge, amount paid) > * Hide payment method and original register rows (not applicable in this context) > * Update form field IDs to match new modal structure >- Fix focus to use #refund_amount instead of deprecated #returned field >- Update cash register validation to use #refund_registerid_select >- Add html_helpers.inc for proper formatting support > >The shared modal intelligently adapts to different contexts, showing only >relevant information based on available data. For patron account refunds, >payment method and original register information are hidden since debits >can be paid by multiple credits with different payment methods. > >Test plan: >1. Apply patch and rebuild: yarn build >2. Navigate to a patron's account page with paid charges >3. Click "Issue refund" on a debit that has been partially or fully paid >4. Verify refund modal displays: > - Transaction description (properly formatted) > - Original charge amount (properly formatted with currency) > - Amount paid (properly formatted) > - No payment method row (hidden in this context) > - No original register row (hidden in this context) >5. Enter a refund amount and complete the refund >6. Verify the refund is processed successfully >7. Verify cash register validation works when UseCashRegisters is enabled >--- > .../prog/en/modules/members/boraccount.tt | 104 ++---------------- > members/boraccount.pl | 2 +- > 2 files changed, 10 insertions(+), 96 deletions(-) > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/boraccount.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/boraccount.tt >index f185f68adad..b5e05496091 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/boraccount.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/boraccount.tt >@@ -8,6 +8,7 @@ > [% USE Price %] > [% USE Registers %] > [% PROCESS 'i18n.inc' %] >+[% PROCESS 'html_helpers.inc' %] > [% SET footerjs = 1 %] > [% SET registers = Registers.all( filters => { current_branch => 1 } ) %] > >@@ -239,6 +240,7 @@ > data-accountline="[% account.accountlines_id | html %]" > data-amount="[% account.amount | $Price on_editing => 1 %]" > data-amountoutstanding="[% account.amountoutstanding | $Price on_editing => 1 %]" >+ data-payment-type="[% AuthorisedValues.GetByCode( 'PAYMENT_TYPE', account.credits.single.payment_type ) | html %]" > data-member="[% account.borrowernumber | html %]" > ><i class="fa-solid fa-money-bill-1"></i> Issue refund</button > > >@@ -345,66 +347,7 @@ > </div> > <!-- /#issuePayoutModal --> > >-<!-- Issue refund modal --> >-<div class="modal" id="issueRefundModal" tabindex="-1" role="dialog" aria-labelledby="issueRefundLabel"> >- <form id="refund_form" action="/cgi-bin/koha/members/boraccount.pl" method="post" enctype="multipart/form-data" class="validated"> >- [% INCLUDE 'csrf-token.inc' %] >- <input type="hidden" name="accountlines_id" value="" id="refundline" /> >- <input type="hidden" name="op" value="cud-refund" /> >- <input type="hidden" name="borrowernumber" value="[% account.borrowernumber | html %]" /> >- <div class="modal-dialog"> >- <div class="modal-content"> >- <div class="modal-header"> >- <h1 class="modal-title" id="issueRefundLabel">Issue refund</h1> >- <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> >- </div> >- <div class="modal-body"> >- [% IF Koha.Preference('UseCashRegisters') && ( registers.size == 0 ) %] >- <div id="refund_error" class="alert alert-warning"> You must have at least one cash register associated with this branch before you can record cash refunds. </div> >- [% END %] >- <fieldset class="rows"> >- <ol> >- <li> <span id="refund_item" class="label">Account: </span><span></span> </li> >- <li> <span id="paid" class="label">Amount paid: </span><span></span> </li> >- <li> >- <label class="required" for="amount">Returned to patron: </label> >- <input type="text" inputmode="numeric" pattern="[0-9]*" id="returned" name="amount" required="required" /> >- <span class="required">Required</span> >- </li> >- >- [% INCLUDE 'transaction_types.inc' type="refund" %] >- >- [% IF Koha.Preference('UseCashRegisters') %] >- <li> >- <label for="registerid">Cash register: </label> >- <select name="registerid" id="refund_registerid"> >- <option id="noregister" disabled selected="selected" value="">-- Select an option--</option> >- [% PROCESS options_for_registers %] >- </select> >- </li> >- [% END %] >- <li> >- <label for="refund_note">Note: </label> >- <textarea id="refund_note" name="refund_note" rows="5" cols="30"></textarea> >- </li> >- </ol> >- </fieldset> >- <!-- /.rows --> >- </div> >- <!-- /.modal-body --> >- <div class="modal-footer"> >- <button type="submit" class="btn btn-primary" id="borr_refund_confirm">Confirm</button> >- <button type="button" class="btn btn-default" data-bs-dismiss="modal">Cancel</button> >- </div> >- <!-- /.modal-footer --> >- </div> >- <!-- /.modal-content --> >- </div> >- <!-- /.modal-dialog --> >- </form> >- <!-- /#refund_form --> >-</div> >-<!-- /#issueRefundModal --> >+[% INCLUDE 'modals/refund_modal.inc' refund_form_action = '/cgi-bin/koha/members/boraccount.pl' patron = patron registers = registers %] > > <!-- Apply discount modal --> > <div class="modal" id="applyDiscountModal" tabindex="-1" role="dialog" aria-labelledby="applyDiscountLabel"> >@@ -577,6 +520,7 @@ > [% INCLUDE 'format_price.inc' %] > [% INCLUDE 'str/members-menu.inc' %] > [% Asset.js("js/members-menu.js") | $raw %] >+ [% Asset.js("js/refund_modal.js") | $raw %] > <script> > $(document).ready(function() { > [% IF payment_id && Koha.Preference('FinePaymentAutoPopup') %] >@@ -618,43 +562,13 @@ > $("#amount, #payout_transaction_type").focus(); > }); > >- $("#issueRefundModal").on("shown.bs.modal", function(e){ >- var button = $(e.relatedTarget); >- var item = button.data('item'); >- $("#item + span").replaceWith(item); >- var accountline = button.data('accountline'); >- $('#refundline').val(accountline); >- var amount = button.data('amount'); >- var amountoutstanding = button.data('amountoutstanding') || 0; >- var paid = amount - amountoutstanding; >- $("#paid + span").text(paid.format_price()); >- $("#returned").attr({ "value": paid.format_price(), "max": paid.format_price(), "min": 0 }); >- var member = button.data('member'); >- if ( member === '' ) { >- $("#refund_type option[value='AC']").remove(); >- } else if ( $("#refund_type option[value='AC']").length == 0 ) { >- $("#refund_type").prepend('<option value="AC" selected="selected">Account credit</option>'); >- } >- $("#returned, #refund_type").focus(); >- }); >- >- // Validate cash register requirement for refunds >+ // Initialize refund modal with cash register validation > [% IF Koha.Preference('UseCashRegisters') %] >- $("#refund_form").on("submit", function(e) { >- var refund_type = $("#refund_type").val(); >- var register = $("#refund_registerid").val(); >- >- // Only require register for non-AC refunds with CASH or SIP00 payment types >- if (refund_type && refund_type !== 'AC' && (refund_type === 'CASH' || refund_type.match(/^SIP\d{2}$/))) { >- if (!register || register === '') { >- e.preventDefault(); >- alert(_("Cash register is required for cash refunds")); >- $("#refund_registerid").focus(); >- return false; >- } >- } >- return true; >+ initRefundModal({ >+ validateCashRegister: true > }); >+ [% ELSE %] >+ initRefundModal(); > [% END %] > > $("#applyDiscountModal").on("shown.bs.modal", function(e){ >diff --git a/members/boraccount.pl b/members/boraccount.pl >index 7d99a85e250..8095c40d85f 100755 >--- a/members/boraccount.pl >+++ b/members/boraccount.pl >@@ -130,7 +130,7 @@ if ( $op eq 'cud-payout' ) { > > if ( $op eq 'cud-refund' ) { > output_and_exit_if_error( $input, $cookie, $template, { check => 'csrf_token' } ); >- my $charge_id = scalar $input->param('accountlines_id'); >+ my $charge_id = scalar $input->param('accountline_id'); > my $charge = Koha::Account::Lines->find($charge_id); > my $amount = scalar $input->param('amount'); > my $refund_type = scalar $input->param('refund_type'); >-- >2.52.0 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 41592
:
191252
|
191253
| 191254 |
191255