|
Lines 112-128
Link Here
|
| 112 |
</td> |
112 |
</td> |
| 113 |
[% IF CAN_user_cash_management_cashup %] |
113 |
[% IF CAN_user_cash_management_cashup %] |
| 114 |
<td> |
114 |
<td> |
| 115 |
<button |
115 |
[% IF register.cashup_in_progress %] |
| 116 |
type="button" |
116 |
<button |
| 117 |
class="cashup_individual btn btn-xs btn-default" |
117 |
type="button" |
| 118 |
data-bs-toggle="modal" |
118 |
class="btn btn-xs btn-primary pos_complete_cashup" |
| 119 |
data-bs-target="#confirmCashupModal" |
119 |
data-bs-toggle="modal" |
| 120 |
data-register="[% register.description | html %]" |
120 |
data-bs-target="#confirmCashupModal" |
| 121 |
data-bankable="[% rbankable | $Price %]" |
121 |
data-register="[% register.description | html %]" |
| 122 |
data-float="[% register.starting_float | $Price %]" |
122 |
data-bankable="[% rbankable | $Price %]" |
| 123 |
data-registerid="[% register.id | html %]" |
123 |
data-float="[% register.starting_float | $Price %]" |
| 124 |
><i class="fa-solid fa-money-bill-1"></i> Record cashup</button |
124 |
data-registerid="[% register.id | html %]" |
| 125 |
> |
125 |
><i class="fa-solid fa-check"></i> Complete cashup</button |
|
|
126 |
> |
| 127 |
[% ELSE %] |
| 128 |
<button |
| 129 |
type="button" |
| 130 |
class="cashup_individual btn btn-xs btn-default" |
| 131 |
data-bs-toggle="modal" |
| 132 |
data-bs-target="#triggerCashupModalRegister" |
| 133 |
data-register="[% register.description | html %]" |
| 134 |
data-bankable="[% rbankable | $Price %]" |
| 135 |
data-float="[% register.starting_float | $Price %]" |
| 136 |
data-registerid="[% register.id | html %]" |
| 137 |
><i class="fa-solid fa-money-bill-1"></i> Record cashup</button |
| 138 |
> |
| 139 |
[% END %] |
| 126 |
</td> |
140 |
</td> |
| 127 |
[% END %] |
141 |
[% END %] |
| 128 |
</tr> |
142 |
</tr> |
|
Lines 147-170
Link Here
|
| 147 |
[% END %] |
161 |
[% END %] |
| 148 |
[% END %] |
162 |
[% END %] |
| 149 |
|
163 |
|
|
|
164 |
<!-- Trigger cashup modal for individual registers --> |
| 165 |
<div class="modal" id="triggerCashupModalRegister" tabindex="-1" role="dialog" aria-labelledby="triggerCashupLabelRegister"> |
| 166 |
<form method="post" class="validated"> |
| 167 |
[% INCLUDE 'csrf-token.inc' %] |
| 168 |
<div class="modal-dialog"> |
| 169 |
<div class="modal-content"> |
| 170 |
<div class="modal-header"> |
| 171 |
<h1 class="modal-title" id="triggerCashupLabelRegister"> |
| 172 |
Cashup for <em><span id="register_desc"></span></em> |
| 173 |
</h1> |
| 174 |
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> |
| 175 |
</div> |
| 176 |
<div class="modal-body"> |
| 177 |
<p><strong>Choose how to proceed with the cashup:</strong></p> |
| 178 |
<p><strong>Start cashup</strong></p> |
| 179 |
<ul> |
| 180 |
<li>Remove cash from the register for counting</li> |
| 181 |
<li>The register can continue operating during counting</li> |
| 182 |
<li>Complete the cashup once counted</li> |
| 183 |
</ul> |
| 184 |
<p><strong>Quick cashup</strong></p> |
| 185 |
<ul> |
| 186 |
<li>Confirm you have removed <span id="expected_amount_display"></span> cash from the register to bank immediately</li> |
| 187 |
</ul> |
| 188 |
<p |
| 189 |
>Remember to leave the float amount of <strong><span id="float_amount_display"></span></strong> in the register.</p |
| 190 |
> |
| 191 |
</div> |
| 192 |
<div class="modal-footer"> |
| 193 |
<input type="hidden" name="registerid" id="register_id_field" value="" /> |
| 194 |
<input type="hidden" name="op" value="cud-cashup_start" /> |
| 195 |
<input type="hidden" name="amount" value="" /> |
| 196 |
<button type="submit" class="btn btn-primary">Start cashup</button> |
| 197 |
<button type="button" class="btn btn-success" id="quick_cashup_btn">Quick cashup</button> |
| 198 |
<button type="button" class="btn btn-default" data-bs-dismiss="modal">Cancel</button> |
| 199 |
</div> |
| 200 |
</div> |
| 201 |
</div> |
| 202 |
</form> |
| 203 |
</div> |
| 204 |
<!-- /#triggerCashupModalRegister --> |
| 205 |
|
| 150 |
<!-- Confirm cashup modal --> |
206 |
<!-- Confirm cashup modal --> |
| 151 |
<div class="modal" id="confirmCashupModal" tabindex="-1" role="dialog" aria-labelledby="confirmCashupLabel"> |
207 |
<div class="modal" id="confirmCashupModal" tabindex="-1" role="dialog" aria-labelledby="confirmCashupLabel"> |
| 152 |
<form id="cashup_individual_form" method="post" enctype="multipart/form-data"> |
208 |
<form id="cashup_individual_form" method="post" enctype="multipart/form-data" class="validated"> |
| 153 |
[% INCLUDE 'csrf-token.inc' %] |
209 |
[% INCLUDE 'csrf-token.inc' %] |
| 154 |
<div class="modal-dialog"> |
210 |
<div class="modal-dialog"> |
| 155 |
<div class="modal-content"> |
211 |
<div class="modal-content"> |
| 156 |
<div class="modal-header"> |
212 |
<div class="modal-header"> |
| 157 |
<h1 class="modal-title" id="confirmCashupLabel" |
213 |
<h1 class="modal-title" id="confirmCashupLabel"> |
| 158 |
>Confirm cashup of <em><span id="registerc"></span></em |
214 |
Confirm cashup of <em><span id="registerc"></span></em> |
| 159 |
></h1> |
215 |
</h1> |
| 160 |
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> |
216 |
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> |
| 161 |
</div> |
217 |
</div> |
| 162 |
<div class="modal-body"> Please confirm that you have removed <span id="cashc"></span> from the cash register and left a float of <span id="floatc"></span>. </div> |
218 |
<div class="modal-body"> |
|
|
219 |
<fieldset class="rows"> |
| 220 |
<ol> |
| 221 |
<li> |
| 222 |
<span class="label"> Expected cashup amount: </span> |
| 223 |
<span id="cashc" class="expected-amount"></span> |
| 224 |
</li> |
| 225 |
<li> |
| 226 |
<label class="required" for="amount"> Actual cashup amount counted: </label> |
| 227 |
<input type="text" inputmode="decimal" pattern="^\d+(\.\d{2})?$" id="amount" name="amount" required="required" /> |
| 228 |
<span class="required">Required</span> |
| 229 |
</li> |
| 230 |
<li id="reconciliation_display" style="display: none;"> |
| 231 |
<span class="label">Reconciliation:</span> |
| 232 |
<span id="reconciliation_text"></span> |
| 233 |
</li> |
| 234 |
<li id="reconciliation_note_field" style="display: none;"> |
| 235 |
<label for="reconciliation_note">Note (optional):</label> |
| 236 |
<textarea id="reconciliation_note" name="reconciliation_note" rows="3" cols="40" maxlength="1000" placeholder="Enter a note explaining the surplus or deficit..."></textarea> |
| 237 |
<div class="hint">Maximum 1000 characters</div> |
| 238 |
</li> |
| 239 |
</ol> |
| 240 |
</fieldset> |
| 241 |
</div> |
| 163 |
<!-- /.modal-body --> |
242 |
<!-- /.modal-body --> |
| 164 |
<div class="modal-footer"> |
243 |
<div class="modal-footer"> |
| 165 |
<input type="hidden" name="registerid" id="cashup_registerid" value="" /> |
244 |
<input type="hidden" name="registerid" id="cashup_registerid" value="" /> |
| 166 |
<input type="hidden" name="op" value="cud-cashup" /> |
245 |
<input type="hidden" name="op" value="cud-cashup" /> |
| 167 |
<button type="submit" class="btn btn-primary" id="cashup_confirm">Confirm</button> |
246 |
<button type="submit" class="btn btn-primary" id="cashup_confirm"> Complete cashup</button> |
| 168 |
<button type="button" class="btn btn-default" data-bs-dismiss="modal">Cancel</button> |
247 |
<button type="button" class="btn btn-default" data-bs-dismiss="modal">Cancel</button> |
| 169 |
</div> |
248 |
</div> |
| 170 |
<!-- /.modal-footer --> |
249 |
<!-- /.modal-footer --> |
|
Lines 229-234
Link Here
|
| 229 |
paginationType: "full", |
308 |
paginationType: "full", |
| 230 |
}); |
309 |
}); |
| 231 |
|
310 |
|
|
|
311 |
// Real-time reconciliation calculation for cashup modal |
| 312 |
$("#amount").on("input", function() { |
| 313 |
var actualAmount = parseFloat($(this).val()) || 0; |
| 314 |
var expectedText = $("#expected_amount").text().replace(/[£$,]/g, ''); |
| 315 |
var expectedAmount = parseFloat(expectedText) || 0; |
| 316 |
var difference = actualAmount - expectedAmount; |
| 317 |
|
| 318 |
if ($(this).val() && !isNaN(actualAmount)) { |
| 319 |
var reconciliationText = ""; |
| 320 |
var reconciliationClass = ""; |
| 321 |
var hasDiscrepancy = false; |
| 322 |
|
| 323 |
if (difference > 0) { |
| 324 |
reconciliationText = "Surplus: " + difference.format_price(); |
| 325 |
reconciliationClass = "success"; |
| 326 |
hasDiscrepancy = true; |
| 327 |
} else if (difference < 0) { |
| 328 |
reconciliationText = "Deficit: " + Math.abs(difference).format_price(); |
| 329 |
reconciliationClass = "warning"; |
| 330 |
hasDiscrepancy = true; |
| 331 |
} else { |
| 332 |
reconciliationText = "Balanced - no surplus or deficit"; |
| 333 |
reconciliationClass = "success"; |
| 334 |
hasDiscrepancy = false; |
| 335 |
} |
| 336 |
|
| 337 |
$("#reconciliation_text").text(reconciliationText) |
| 338 |
.removeClass("success warning") |
| 339 |
.addClass(reconciliationClass); |
| 340 |
$("#reconciliation_display").show(); |
| 341 |
|
| 342 |
// Show/hide note field based on whether there's a discrepancy |
| 343 |
if (hasDiscrepancy) { |
| 344 |
$("#reconciliation_note_field").show(); |
| 345 |
} else { |
| 346 |
$("#reconciliation_note_field").hide(); |
| 347 |
$("#reconciliation_note").val(''); // Clear note when balanced |
| 348 |
} |
| 349 |
} else { |
| 350 |
$("#reconciliation_display").hide(); |
| 351 |
$("#reconciliation_note_field").hide(); |
| 352 |
} |
| 353 |
}); |
| 354 |
|
| 355 |
// Reset modal when opened |
| 232 |
$("#confirmCashupModal").on("shown.bs.modal", function(e){ |
356 |
$("#confirmCashupModal").on("shown.bs.modal", function(e){ |
| 233 |
var button = $(e.relatedTarget); |
357 |
var button = $(e.relatedTarget); |
| 234 |
var register = button.data('register'); |
358 |
var register = button.data('register'); |
|
Lines 239-244
Link Here
|
| 239 |
$('#floatc').text(rfloat); |
363 |
$('#floatc').text(rfloat); |
| 240 |
var rid = button.data('registerid'); |
364 |
var rid = button.data('registerid'); |
| 241 |
$('#cashup_registerid').val(rid); |
365 |
$('#cashup_registerid').val(rid); |
|
|
366 |
$("#amount").val('').focus(); |
| 367 |
$("#reconciliation_display").hide(); |
| 368 |
$("#reconciliation_note_field").hide(); |
| 369 |
$("#reconciliation_note").val(''); |
| 370 |
}); |
| 371 |
|
| 372 |
// Handle the new trigger cashup modal for individual registers |
| 373 |
$("#triggerCashupModalRegister").on("shown.bs.modal", function(e){ |
| 374 |
var button = $(e.relatedTarget); |
| 375 |
var register = button.data('register'); |
| 376 |
$("#register_desc").text(register); |
| 377 |
var bankable = button.data('bankable'); |
| 378 |
$("#expected_amount_display").text(bankable); |
| 379 |
var rfloat = button.data('float'); |
| 380 |
$('#float_amount_display').text(rfloat); |
| 381 |
var rid = button.data('registerid'); |
| 382 |
$('#register_id_field').val(rid); |
| 383 |
|
| 384 |
// Store bankable amount for quick cashup |
| 385 |
$('#triggerCashupModalRegister').data('bankable-amount', bankable.replace(/[^0-9.-]/g, '')); |
| 386 |
}); |
| 387 |
|
| 388 |
// Handle Quick cashup button click |
| 389 |
$("#quick_cashup_btn").on("click", function(e){ |
| 390 |
e.preventDefault(); |
| 391 |
var form = $(this).closest('form'); |
| 392 |
var bankableAmount = $('#triggerCashupModalRegister').data('bankable-amount'); |
| 393 |
|
| 394 |
// Change operation to cud-cashup (quick cashup) |
| 395 |
form.find('input[name="op"]').val('cud-cashup'); |
| 396 |
|
| 397 |
// Set the amount to the expected bankable amount |
| 398 |
form.find('input[name="amount"]').val(bankableAmount); |
| 399 |
|
| 400 |
// Submit the form |
| 401 |
form.submit(); |
| 242 |
}); |
402 |
}); |
| 243 |
}); |
403 |
}); |
| 244 |
</script> |
404 |
</script> |