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 |
|