|
Lines 258-279
Link Here
|
| 258 |
FinePaymentAutoPopup: [% Koha.Preference('FinePaymentAutoPopup') ? 1 : 0 | html %], |
258 |
FinePaymentAutoPopup: [% Koha.Preference('FinePaymentAutoPopup') ? 1 : 0 | html %], |
| 259 |
}); |
259 |
}); |
| 260 |
</script> |
260 |
</script> |
| 261 |
|
|
|
| 262 |
<script> |
261 |
<script> |
| 263 |
function moneyFormat(textObj) { |
262 |
function moneyFormat(textObj) { |
| 264 |
var newValue = textObj.value; |
263 |
var newValue = textObj.value; |
| 265 |
var decAmount = ""; |
264 |
var decAmount = ""; |
| 266 |
var dolAmount = ""; |
265 |
var dolAmount = ""; |
| 267 |
var dolFlag = false; |
266 |
var dolFlag = false; |
| 268 |
var aChar = ""; |
267 |
var aChar = ""; |
| 269 |
|
268 |
|
| 270 |
for(var i = newValue.length; 0 < i; i--) { |
269 |
for (var i = newValue.length; 0 < i; i--) { |
| 271 |
aChar = newValue.substring(i-1, i); |
270 |
aChar = newValue.substring(i - 1, i); |
| 272 |
if ("0" <= aChar && aChar <= "9") { |
271 |
if ("0" <= aChar && aChar <= "9") { |
| 273 |
if(dolFlag) { |
272 |
if (dolFlag) { |
| 274 |
dolAmount = "" + aChar + dolAmount; |
273 |
dolAmount = "" + aChar + dolAmount; |
| 275 |
} |
274 |
} else { |
| 276 |
else { |
|
|
| 277 |
decAmount = "" + aChar + decAmount; |
275 |
decAmount = "" + aChar + decAmount; |
| 278 |
} |
276 |
} |
| 279 |
} |
277 |
} |
|
Lines 290-336
Link Here
|
| 290 |
if (dolAmount == "") { |
288 |
if (dolAmount == "") { |
| 291 |
dolAmount = "0"; |
289 |
dolAmount = "0"; |
| 292 |
} |
290 |
} |
| 293 |
// Strip leading 0s |
291 |
// Strip leading 0s |
| 294 |
if (dolAmount.length > 1) { |
292 |
if (dolAmount.length > 1) { |
| 295 |
while(dolAmount.length > 1 && dolAmount.substring(0,1) == "0") { |
293 |
while (dolAmount.length > 1 && dolAmount.substring(0, 1) == "0") { |
| 296 |
dolAmount = dolAmount.substring(1,dolAmount.length); |
294 |
dolAmount = dolAmount.substring(1, dolAmount.length); |
| 297 |
} |
295 |
} |
| 298 |
} |
296 |
} |
| 299 |
if (decAmount.length > 2) { |
297 |
if (decAmount.length > 2) { |
| 300 |
decAmount = decAmount.substring(0,2); |
298 |
decAmount = decAmount.substring(0, 2); |
| 301 |
} |
299 |
} |
| 302 |
// Pad right side |
300 |
// Pad right side |
| 303 |
if (decAmount.length == 1) { |
301 |
if (decAmount.length == 1) { |
| 304 |
decAmount = decAmount + "0"; |
302 |
decAmount = decAmount + "0"; |
| 305 |
} |
303 |
} |
| 306 |
if (decAmount.length == 0) { |
304 |
if (decAmount.length == 0) { |
| 307 |
decAmount = decAmount + "00"; |
305 |
decAmount = decAmount + "00"; |
| 308 |
} |
306 |
} |
| 309 |
|
307 |
|
| 310 |
textObj.value = dolAmount + "." + decAmount; |
308 |
textObj.value = dolAmount + "." + decAmount; |
| 311 |
} |
309 |
} |
| 312 |
|
310 |
|
| 313 |
function fnClickAddRow( table, invoiceCode, invoiceTitle, invoicePrice ) { |
311 |
function fnClickAddRow(table, invoiceCode, invoiceTitle, invoicePrice) { |
| 314 |
var defaultPrice = { value: invoicePrice }; |
312 |
var defaultPrice = { value: invoicePrice }; |
| 315 |
moneyFormat(defaultPrice); |
313 |
moneyFormat(defaultPrice); |
| 316 |
table.row.add( [ |
314 |
table.row.add([invoiceTitle, defaultPrice.value, 1, null, '<button class="btn btn-default btn-xs drop" type="button"><i class="fa fa-trash-can"></i> ' + _("Remove") + "</button>", invoiceCode]).draw(); |
| 317 |
invoiceTitle, |
|
|
| 318 |
defaultPrice.value, |
| 319 |
1, |
| 320 |
null, |
| 321 |
'<button class="btn btn-default btn-xs drop" type="button"><i class="fa fa-trash-can"></i> ' + _("Remove") + '</button>', |
| 322 |
invoiceCode |
| 323 |
] |
| 324 |
).draw(); |
| 325 |
} |
315 |
} |
| 326 |
|
316 |
|
| 327 |
function updateChangeValues() { |
317 |
function updateChangeValues() { |
| 328 |
var change = $('#change')[0]; |
318 |
var change = $("#change")[0]; |
| 329 |
change.innerHTML = Math.round(($('#tendered')[0].value - $('#paid')[0].value) * 100) / 100; |
319 |
change.innerHTML = Math.round(($("#tendered")[0].value - $("#paid")[0].value) * 100) / 100; |
| 330 |
if (change.innerHTML <= 0) { |
320 |
if (change.innerHTML <= 0) { |
| 331 |
var paid = $('#paid')[0]; |
321 |
var paid = $("#paid")[0]; |
| 332 |
moneyFormat(paid); |
322 |
moneyFormat(paid); |
| 333 |
$('#tendered').rules( "add", { min: Number(paid.value) }); |
323 |
$("#tendered").rules("add", { min: Number(paid.value) }); |
| 334 |
change.innerHTML = zero_formatted; |
324 |
change.innerHTML = zero_formatted; |
| 335 |
$(':input[name="change"]').val(zero_formatted); |
325 |
$(':input[name="change"]').val(zero_formatted); |
| 336 |
} else { |
326 |
} else { |
|
Lines 340-381
Link Here
|
| 340 |
$(':input[name="change"]').val(change.value); |
330 |
$(':input[name="change"]').val(change.value); |
| 341 |
} |
331 |
} |
| 342 |
|
332 |
|
| 343 |
$('#modal_change').html(change.innerHTML); |
333 |
$("#modal_change").html(change.innerHTML); |
| 344 |
} |
334 |
} |
| 345 |
|
335 |
|
| 346 |
$(document).ready(function() { |
336 |
$(document).ready(function () { |
| 347 |
const sale_table = document.getElementById('sale'); |
337 |
const sale_table = document.getElementById("sale"); |
| 348 |
const sale_kohaTable = $("#sale").kohaTable({ |
338 |
const sale_kohaTable = $("#sale").kohaTable({ |
| 349 |
paging: false, |
339 |
paging: false, |
| 350 |
searching: false, |
340 |
searching: false, |
| 351 |
info: false, |
341 |
info: false, |
| 352 |
columnDefs: [{ |
342 |
columnDefs: [ |
| 353 |
"targets": [-2], |
343 |
{ |
| 354 |
"orderable": false, |
344 |
targets: [-2], |
| 355 |
"searchable": false, |
345 |
orderable: false, |
| 356 |
}, { |
346 |
searchable: false, |
| 357 |
targets: [-3], |
347 |
}, |
| 358 |
render: function ( data, type, full ) { |
348 |
{ |
| 359 |
var price = Number.parseFloat(data); |
349 |
targets: [-3], |
| 360 |
return price.format_price(); |
350 |
render: function (data, type, full) { |
| 361 |
} |
351 |
var price = Number.parseFloat(data); |
| 362 |
}, { |
352 |
return price.format_price(); |
| 363 |
targets: [-5], |
353 |
}, |
| 364 |
className: "editable", |
354 |
}, |
| 365 |
}, { |
355 |
{ |
| 366 |
targets: [-4], |
356 |
targets: [-5], |
| 367 |
className: "editable_int", |
357 |
className: "editable", |
| 368 |
}, { |
358 |
}, |
| 369 |
targets: [-1], |
359 |
{ |
| 370 |
visible: false, |
360 |
targets: [-4], |
| 371 |
searchable: false |
361 |
className: "editable_int", |
| 372 |
}], |
362 |
}, |
| 373 |
rowCallback: function( row, data ) { |
363 |
{ |
|
|
364 |
targets: [-1], |
| 365 |
visible: false, |
| 366 |
searchable: false, |
| 367 |
}, |
| 368 |
], |
| 369 |
rowCallback: function (row, data) { |
| 374 |
const total = data[1] * data[2]; |
370 |
const total = data[1] * data[2]; |
| 375 |
data[3] = total; |
371 |
data[3] = total; |
| 376 |
sale_kohaTable.api().cell(row, 3).invalidate(); |
372 |
sale_kohaTable.api().cell(row, 3).invalidate(); |
| 377 |
}, |
373 |
}, |
| 378 |
footerCallback: function(tfoot, data, start, end, display) { |
374 |
footerCallback: function (tfoot, data, start, end, display) { |
| 379 |
let total_price = 0; |
375 |
let total_price = 0; |
| 380 |
|
376 |
|
| 381 |
// Loop through the data to calculate the total |
377 |
// Loop through the data to calculate the total |
|
Lines 387-439
Link Here
|
| 387 |
total_price = total_price.format_price(); |
383 |
total_price = total_price.format_price(); |
| 388 |
|
384 |
|
| 389 |
// Update the footer cell |
385 |
// Update the footer cell |
| 390 |
$(tfoot).find('td').eq(1).html(total_price); |
386 |
$(tfoot).find("td").eq(1).html(total_price); |
| 391 |
|
387 |
|
| 392 |
// Update a related element and trigger change |
388 |
// Update a related element and trigger change |
| 393 |
$('#paid').val(total_price).trigger('change'); |
389 |
$("#paid").val(total_price).trigger("change"); |
| 394 |
}, |
390 |
}, |
| 395 |
autoWidth: false |
391 |
autoWidth: false, |
| 396 |
}); |
392 |
}); |
| 397 |
|
393 |
|
| 398 |
$("#sale").on("click", "button.drop", function(){ |
394 |
$("#sale").on("click", "button.drop", function () { |
| 399 |
sale_kohaTable.api().row($(this).parents('tr')).remove().draw(false); |
395 |
sale_kohaTable.api().row($(this).parents("tr")).remove().draw(false); |
| 400 |
}); |
396 |
}); |
| 401 |
|
397 |
|
| 402 |
// Set up editable columns based on header classes |
398 |
// Set up editable columns based on header classes |
| 403 |
const editableColumns = Array.from(sale_table.querySelectorAll('thead th')) |
399 |
const editableColumns = Array.from(sale_table.querySelectorAll("thead th")) |
| 404 |
.map((header, index) => { |
400 |
.map((header, index) => { |
| 405 |
if (header.classList.contains('editable') || header.classList.contains('editable_int')) { |
401 |
if (header.classList.contains("editable") || header.classList.contains("editable_int")) { |
| 406 |
return { index: index, type: header.classList.contains('editable_int') ? 'number' : 'text' }; |
402 |
return { index: index, type: header.classList.contains("editable_int") ? "number" : "text" }; |
| 407 |
} |
403 |
} |
| 408 |
return null; |
404 |
return null; |
| 409 |
}) |
405 |
}) |
| 410 |
.filter(column => column !== null); // Filter out non-editable columns |
406 |
.filter(column => column !== null); // Filter out non-editable columns |
| 411 |
|
407 |
|
| 412 |
sale_table.querySelector('tbody').addEventListener('click', function (event) { |
408 |
sale_table.querySelector("tbody").addEventListener("click", function (event) { |
| 413 |
const cell = event.target.closest('td'); |
409 |
const cell = event.target.closest("td"); |
| 414 |
if (!cell) return; |
410 |
if (!cell) return; |
| 415 |
|
411 |
|
| 416 |
const cellIndex = cell.cellIndex; |
412 |
const cellIndex = cell.cellIndex; |
| 417 |
const editableColumn = editableColumns.find(column => column.index === cellIndex); |
413 |
const editableColumn = editableColumns.find(column => column.index === cellIndex); |
| 418 |
if (editableColumn) { |
414 |
if (editableColumn) { |
| 419 |
const originalContent = cell.textContent.trim(); |
415 |
const originalContent = cell.textContent.trim(); |
| 420 |
const input = document.createElement('input'); |
416 |
const input = document.createElement("input"); |
| 421 |
input.type = editableColumn.type; |
417 |
input.type = editableColumn.type; |
| 422 |
input.value = originalContent; |
418 |
input.value = originalContent; |
| 423 |
input.style.width = '8em'; |
419 |
input.style.width = "8em"; |
| 424 |
|
420 |
|
| 425 |
// Prevent click on numeric up/down buttons from closing input |
421 |
// Prevent click on numeric up/down buttons from closing input |
| 426 |
input.addEventListener('click', (e) => e.stopPropagation()); |
422 |
input.addEventListener("click", e => e.stopPropagation()); |
| 427 |
|
423 |
|
| 428 |
// Replace cell content with the input |
424 |
// Replace cell content with the input |
| 429 |
cell.textContent = ''; |
425 |
cell.textContent = ""; |
| 430 |
cell.appendChild(input); |
426 |
cell.appendChild(input); |
| 431 |
input.focus(); |
427 |
input.focus(); |
| 432 |
|
428 |
|
| 433 |
// Handle blur and Enter key events |
429 |
// Handle blur and Enter key events |
| 434 |
input.addEventListener('blur', updateCell); |
430 |
input.addEventListener("blur", updateCell); |
| 435 |
input.addEventListener('keydown', function(e) { |
431 |
input.addEventListener("keydown", function (e) { |
| 436 |
if (e.key === 'Enter') { |
432 |
if (e.key === "Enter") { |
| 437 |
e.preventDefault(); |
433 |
e.preventDefault(); |
| 438 |
e.stopPropagation(); |
434 |
e.stopPropagation(); |
| 439 |
updateCell(); |
435 |
updateCell(); |
|
Lines 458-513
Link Here
|
| 458 |
false |
454 |
false |
| 459 |
); |
455 |
); |
| 460 |
|
456 |
|
| 461 |
$("#invoices").on("click", ".add_button", function(e) { |
457 |
$("#invoices").on("click", ".add_button", function (e) { |
| 462 |
e.preventDefault(); |
458 |
e.preventDefault(); |
| 463 |
fnClickAddRow(sale_kohaTable.api(), $( this ).data('invoiceCode'), $( this ).data('invoiceTitle'), $( this ).data('invoicePrice') ); |
459 |
fnClickAddRow(sale_kohaTable.api(), $(this).data("invoiceCode"), $(this).data("invoiceTitle"), $(this).data("invoicePrice")); |
| 464 |
if($('#invoices_filter').find('input[type=search]').val() !== ''){ |
460 |
if ($("#invoices_filter").find("input[type=search]").val() !== "") { |
| 465 |
items_table.DataTable().search('').draw(); |
461 |
items_table.DataTable().search("").draw(); |
| 466 |
} |
462 |
} |
| 467 |
}); |
463 |
}); |
| 468 |
|
464 |
|
| 469 |
// Change calculation and modal |
465 |
// Change calculation and modal |
| 470 |
var change = $('#change')[0]; |
466 |
var change = $("#change")[0]; |
| 471 |
$("#paid, #tendered").on("change",function() { |
467 |
$("#paid, #tendered").on("change", function () { |
| 472 |
moneyFormat( this ); |
468 |
moneyFormat(this); |
| 473 |
if (change != undefined) { |
469 |
if (change != undefined) { |
| 474 |
updateChangeValues(); |
470 |
updateChangeValues(); |
| 475 |
} |
471 |
} |
| 476 |
}); |
472 |
}); |
| 477 |
|
473 |
|
| 478 |
var checked = false; |
474 |
var checked = false; |
| 479 |
$('#modal_submit').click(function() { |
475 |
$("#modal_submit").click(function () { |
| 480 |
checked = true; |
476 |
checked = true; |
| 481 |
$('#payForm').submit(); |
477 |
$("#payForm").submit(); |
| 482 |
}); |
478 |
}); |
| 483 |
|
479 |
|
| 484 |
$('#payForm').validate({ |
480 |
$("#payForm").validate({ |
| 485 |
rules: { |
481 |
rules: { |
| 486 |
paid: { |
482 |
paid: { |
| 487 |
required: true |
483 |
required: true, |
| 488 |
}, |
484 |
}, |
| 489 |
tendered: { |
485 |
tendered: { |
| 490 |
required: true |
486 |
required: true, |
| 491 |
}, |
487 |
}, |
| 492 |
payment_type: { |
488 |
payment_type: { |
| 493 |
required: true |
489 |
required: true, |
| 494 |
}, |
490 |
}, |
| 495 |
registerid: { |
491 |
registerid: { |
| 496 |
required: true |
492 |
required: true, |
| 497 |
} |
493 |
}, |
| 498 |
} |
494 |
}, |
| 499 |
}); |
495 |
}); |
| 500 |
|
496 |
|
| 501 |
$('#payForm').submit(function(e){ |
497 |
$("#payForm").submit(function (e) { |
| 502 |
// first, clear stale sales 'rows' from the payForm |
498 |
// first, clear stale sales 'rows' from the payForm |
| 503 |
if($('input[name="sales"]').length > 0) { |
499 |
if ($('input[name="sales"]').length > 0) { |
| 504 |
$('input[name="sales"]').each(function() { |
500 |
$('input[name="sales"]').each(function () { |
| 505 |
$(this).remove(); |
501 |
$(this).remove(); |
| 506 |
}); |
502 |
}); |
| 507 |
} |
503 |
} |
| 508 |
|
504 |
|
| 509 |
// now, process the current & fresh contents of the sale_kohaTable |
505 |
// now, process the current & fresh contents of the sale_kohaTable |
| 510 |
if (change != undefined && change.innerHTML > 0.00 && !checked) { |
506 |
if (change != undefined && change.innerHTML > 0.0 && !checked) { |
| 511 |
e.preventDefault(); |
507 |
e.preventDefault(); |
| 512 |
$("#confirm_change_form").modal("show"); |
508 |
$("#confirm_change_form").modal("show"); |
| 513 |
} else { |
509 |
} else { |
|
Lines 516-536
Link Here
|
| 516 |
var sale = { |
512 |
var sale = { |
| 517 |
code: row[5], |
513 |
code: row[5], |
| 518 |
price: row[1], |
514 |
price: row[1], |
| 519 |
quantity: row[2] |
515 |
quantity: row[2], |
| 520 |
}; |
516 |
}; |
| 521 |
$('<input>').attr({ |
517 |
$("<input>") |
| 522 |
type: 'hidden', |
518 |
.attr({ |
| 523 |
name: 'sales', |
519 |
type: "hidden", |
| 524 |
value: JSON.stringify(sale) |
520 |
name: "sales", |
| 525 |
}).appendTo('#payForm'); |
521 |
value: JSON.stringify(sale), |
|
|
522 |
}) |
| 523 |
.appendTo("#payForm"); |
| 526 |
}); |
524 |
}); |
| 527 |
return true; |
525 |
return true; |
| 528 |
} |
526 |
} |
| 529 |
}); |
527 |
}); |
| 530 |
|
528 |
|
| 531 |
if (payment_id && prefs.FinePaymentAutoPopup){ |
529 |
if (payment_id && prefs.FinePaymentAutoPopup) { |
| 532 |
$("#printReceipt").click(function() { |
530 |
$("#printReceipt").click(function () { |
| 533 |
var win = window.open(`/cgi-bin/koha/pos/printreceipt.pl?action=print&accountlines_id=${payment_id}&tendered=${tendered}&change=${change}`, '_blank'); |
531 |
var win = window.open(`/cgi-bin/koha/pos/printreceipt.pl?action=print&accountlines_id=${payment_id}&tendered=${tendered}&change=${change}`, "_blank"); |
| 534 |
win.focus(); |
532 |
win.focus(); |
| 535 |
}); |
533 |
}); |
| 536 |
$("#printReceipt").click(); |
534 |
$("#printReceipt").click(); |