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