Bug 40445: (follow-up) Show actual cash removed alongside expected on discrepancy

The cashup summary modal labelled the per-payment-type cash row "Cash
removed from register", but the value came from the session
transactions (with CASHUP_SURPLUS/DEFICIT lines excluded), so it
represented the *expected* cash, not the amount actually counted at
cashup. When a deficit or surplus existed, the reconciliation row
appeared as the difference between two figures the user could not
both see.

Render two rows when surplus_total or deficit_total is set on a
completed cashup: "Expected cash total" (from total_grouped) and
"Cash removed from register" (from cash_register_actions.amount,
already exposed as data.amount). The reconciliation row below now
visibly equals the difference. Balanced cashups and the in-progress
preview keep the original single-row display, and the negative-cashup
branch flips the labels to "Expected cash to add to register" /
"Cash added to register".

Test plan:
1. Configure a cash register and record a few cash payments.
2. Trigger a cashup, enter the exact expected amount; open the
   summary modal -- a single "Cash removed from register" row is
   shown matching the expected total.
3. Repeat with an amount lower than expected -- "Expected cash
   total" and "Cash removed from register" both appear, and the
   "Cashup deficit" row is the difference.
4. Repeat with an amount higher than expected -- the actual row
   exceeds the expected row and "Cashup surplus" matches the gap.

Sponsored-by: OpenFifth <https://openfifth.co.uk/>
Signed-off-by: Jackie Usher <jackie.usher@westsussex.gov.uk>
Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
Martin Renvoize 2026-04-30 16:42:09 +01:00 committed by Pedro Amorim
parent 86d034e628
commit 7798332412
No known key found for this signature in database
GPG Key ID: 06B75BA7F3894D55
3 changed files with 45 additions and 15 deletions

View File

@ -483,7 +483,7 @@
[% INCLUDE 'datatables.inc' %]
[% INCLUDE 'format_price.inc' %]
[% INCLUDE 'js-date-format.inc' %]
[% Asset.js("js/cashup_modal.js") | $raw %]
[% Asset.js("js/modals/cashup_summary_modal.js") | $raw %]
[% Asset.js("js/modals/cashup_modals.js") | $raw %]
[% Asset.js("js/modal_printer.js") | $raw %]
[% INCLUDE 'calendar.inc' %]

View File

@ -382,7 +382,7 @@
[% INCLUDE 'datatables.inc' %]
[% INCLUDE 'format_price.inc' %]
[% INCLUDE 'js-date-format.inc' %]
[% Asset.js("js/cashup_modal.js") | $raw %]
[% Asset.js("js/modals/cashup_summary_modal.js") | $raw %]
[% Asset.js("js/modals/cashup_modals.js") | $raw %]
[% Asset.js("js/modal_printer.js") | $raw %]
<script nonce="[% Koha.CSPNonce | $raw %]">

View File

@ -23,7 +23,6 @@ $(document).ready(function () {
headers: {
"x-koha-embed": "summary",
},
async: false,
success: function (data) {
let from_date = $datetime(data.summary.from_date);
summary_modal.find("#from_date").text(from_date);
@ -142,7 +141,10 @@ $(document).ready(function () {
"<tr class='reconciliation-separator'><td colspan='2'><hr></td></tr>"
);
// 2. Cash removed from register (positive = collected and removed at cashup)
// cashCollected = expected cash from session transactions (excludes
// CASHUP_SURPLUS/DEFICIT). actualAmount = cash recorded at cashup. When
// they differ we display both so the surplus/deficit row below is the
// visible difference.
var cashCollected = null;
for (type of data.summary.total_grouped) {
if (
@ -154,18 +156,46 @@ $(document).ready(function () {
}
}
if (cashCollected !== null) {
var cashLabel =
cashCollected >= 0
? __("Cash removed from register")
: __("Cash added to register");
var hasReconciliation = !!(surplus || deficit);
tfoot.append(
"<tr><td><strong>" +
cashLabel +
"</strong></td><td><strong>" +
cashCollected.format_price() +
"</strong></td></tr>"
);
if (hasReconciliation && !inProgress) {
var expectedLabel =
cashCollected >= 0
? __("Expected cash total")
: __("Expected cash to add to register");
tfoot.append(
"<tr><td><strong>" +
expectedLabel +
"</strong></td><td><strong>" +
cashCollected.format_price() +
"</strong></td></tr>"
);
var actualLabel =
actualAmount >= 0
? __("Cash removed from register")
: __("Cash added to register");
tfoot.append(
"<tr><td><strong>" +
actualLabel +
"</strong></td><td><strong>" +
actualAmount.format_price() +
"</strong></td></tr>"
);
} else {
var cashLabel =
cashCollected >= 0
? __("Cash removed from register")
: __("Cash added to register");
tfoot.append(
"<tr><td><strong>" +
cashLabel +
"</strong></td><td><strong>" +
cashCollected.format_price() +
"</strong></td></tr>"
);
}
}
// 3. Other payment types collected (excluding CASH)