|
Lines 48-53
Link Here
|
| 48 |
<div id="error_message" class="alert alert-warning"> You do not have permission to perform cashup actions. </div> |
48 |
<div id="error_message" class="alert alert-warning"> You do not have permission to perform cashup actions. </div> |
| 49 |
[% END %] |
49 |
[% END %] |
| 50 |
|
50 |
|
|
|
51 |
[% IF ( error_cashup_amount ) %] |
| 52 |
<div id="error_message" class="alert alert-warning"> Invalid amount entered for cashup. Please enter a valid monetary amount. </div> |
| 53 |
[% END %] |
| 54 |
|
| 51 |
[% IF ( error_refund_permission ) %] |
55 |
[% IF ( error_refund_permission ) %] |
| 52 |
<div id="error_message" class="alert alert-warning"> You do not have permission to perform refund actions. </div> |
56 |
<div id="error_message" class="alert alert-warning"> You do not have permission to perform refund actions. </div> |
| 53 |
[% END %] |
57 |
[% END %] |
|
Lines 366-372
Link Here
|
| 366 |
|
370 |
|
| 367 |
<!-- Confirm cashup modal --> |
371 |
<!-- Confirm cashup modal --> |
| 368 |
<div class="modal" id="confirmCashupModal" tabindex="-1" role="dialog" aria-labelledby="confirmCashupLabel"> |
372 |
<div class="modal" id="confirmCashupModal" tabindex="-1" role="dialog" aria-labelledby="confirmCashupLabel"> |
| 369 |
<form id="cashup_form" method="post" enctype="multipart/form-data"> |
373 |
<form id="cashup_form" method="post" enctype="multipart/form-data" class="validated"> |
| 370 |
[% INCLUDE 'csrf-token.inc' %] |
374 |
[% INCLUDE 'csrf-token.inc' %] |
| 371 |
<div class="modal-dialog"> |
375 |
<div class="modal-dialog"> |
| 372 |
<div class="modal-content"> |
376 |
<div class="modal-content"> |
|
Lines 375-387
Link Here
|
| 375 |
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> |
379 |
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> |
| 376 |
</div> |
380 |
</div> |
| 377 |
<div class="modal-body"> |
381 |
<div class="modal-body"> |
| 378 |
Please confirm that you have removed [% accountlines.total( payment_type => [ 'CASH', 'SIP00' ]) * -1 | $Price %] from the cash register and left a float of [% register.starting_float | $Price %]. |
382 |
<fieldset class="rows"> |
|
|
383 |
<ol> |
| 384 |
<li> |
| 385 |
<span class="label">Expected amount to remove:</span> |
| 386 |
<span id="expected_amount" class="expected-amount">[% accountlines.total( payment_type => [ 'CASH', 'SIP00' ]) * -1 | $Price %]</span> |
| 387 |
</li> |
| 388 |
<li> |
| 389 |
<span class="label">Float to remain:</span> |
| 390 |
<span>[% register.starting_float | $Price %]</span> |
| 391 |
</li> |
| 392 |
<li> |
| 393 |
<label class="required" for="amount">Actual amount removed from register:</label> |
| 394 |
<input type="text" inputmode="decimal" pattern="^\d+(\.\d{2})?$" id="amount" name="amount" required="required" /> |
| 395 |
<span class="required">Required</span> |
| 396 |
</li> |
| 397 |
<li id="reconciliation_display" style="display: none;"> |
| 398 |
<span class="label">Reconciliation:</span> |
| 399 |
<span id="reconciliation_text"></span> |
| 400 |
</li> |
| 401 |
<li id="reconciliation_note_field" style="display: none;"> |
| 402 |
<label for="reconciliation_note">Note (optional):</label> |
| 403 |
<textarea id="reconciliation_note" name="reconciliation_note" rows="3" cols="40" maxlength="1000" placeholder="Enter a note explaining the surplus or deficit..."></textarea> |
| 404 |
<div class="hint">Maximum 1000 characters</div> |
| 405 |
</li> |
| 406 |
</ol> |
| 407 |
</fieldset> |
| 379 |
</div> |
408 |
</div> |
| 380 |
<!-- /.modal-body --> |
409 |
<!-- /.modal-body --> |
| 381 |
<div class="modal-footer"> |
410 |
<div class="modal-footer"> |
| 382 |
<input type="hidden" name="registerid" value="[% register.id | html %]" /> |
411 |
<input type="hidden" name="registerid" value="[% register.id | html %]" /> |
| 383 |
<input type="hidden" name="op" value="cud-cashup" /> |
412 |
<input type="hidden" name="op" value="cud-cashup" /> |
| 384 |
<button type="submit" class="btn btn-primary" id="pos_cashup_confirm">Confirm</button> |
413 |
<button type="submit" class="btn btn-primary" id="pos_cashup_confirm">Confirm cashup</button> |
| 385 |
<button type="button" class="btn btn-default" data-bs-dismiss="modal">Cancel</button> |
414 |
<button type="button" class="btn btn-default" data-bs-dismiss="modal">Cancel</button> |
| 386 |
</div> |
415 |
</div> |
| 387 |
<!-- /.modal-footer --> |
416 |
<!-- /.modal-footer --> |
|
Lines 573-578
Link Here
|
| 573 |
} |
602 |
} |
| 574 |
] |
603 |
] |
| 575 |
}, null, 1); |
604 |
}, null, 1); |
|
|
605 |
|
| 606 |
// Real-time reconciliation calculation for cashup modal |
| 607 |
$("#amount").on("input", function() { |
| 608 |
var actualAmount = parseFloat($(this).val()) || 0; |
| 609 |
var expectedText = $("#expected_amount").text().replace(/[£$,]/g, ''); |
| 610 |
var expectedAmount = parseFloat(expectedText) || 0; |
| 611 |
var difference = actualAmount - expectedAmount; |
| 612 |
|
| 613 |
if ($(this).val() && !isNaN(actualAmount)) { |
| 614 |
var reconciliationText = ""; |
| 615 |
var reconciliationClass = ""; |
| 616 |
var hasDiscrepancy = false; |
| 617 |
|
| 618 |
if (difference > 0) { |
| 619 |
reconciliationText = "Surplus: " + difference.format_price(); |
| 620 |
reconciliationClass = "success"; |
| 621 |
hasDiscrepancy = true; |
| 622 |
} else if (difference < 0) { |
| 623 |
reconciliationText = "Deficit: " + Math.abs(difference).format_price(); |
| 624 |
reconciliationClass = "warning"; |
| 625 |
hasDiscrepancy = true; |
| 626 |
} else { |
| 627 |
reconciliationText = "Balanced - no surplus or deficit"; |
| 628 |
reconciliationClass = "success"; |
| 629 |
hasDiscrepancy = false; |
| 630 |
} |
| 631 |
|
| 632 |
$("#reconciliation_text").text(reconciliationText) |
| 633 |
.removeClass("success warning") |
| 634 |
.addClass(reconciliationClass); |
| 635 |
$("#reconciliation_display").show(); |
| 636 |
|
| 637 |
// Show/hide note field based on whether there's a discrepancy |
| 638 |
if (hasDiscrepancy) { |
| 639 |
$("#reconciliation_note_field").show(); |
| 640 |
} else { |
| 641 |
$("#reconciliation_note_field").hide(); |
| 642 |
$("#reconciliation_note").val(''); // Clear note when balanced |
| 643 |
} |
| 644 |
} else { |
| 645 |
$("#reconciliation_display").hide(); |
| 646 |
$("#reconciliation_note_field").hide(); |
| 647 |
} |
| 648 |
}); |
| 649 |
|
| 650 |
// Reset modal when opened |
| 651 |
$("#confirmCashupModal").on("shown.bs.modal", function() { |
| 652 |
// Start with empty actual amount field (user must enter amount) |
| 653 |
$("#amount").val('').focus(); |
| 654 |
$("#reconciliation_display").hide(); |
| 655 |
$("#reconciliation_note_field").hide(); |
| 656 |
$("#reconciliation_note").val(''); |
| 657 |
}); |
| 576 |
</script> |
658 |
</script> |
| 577 |
[% END %] |
659 |
[% END %] |
| 578 |
|
660 |
|