Bugzilla – Attachment 191148 Details for
Bug 41575
Tidy kohaTable block - pos
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 41575: pos - auto tidy
fa9c00d.patch (text/plain), 29.02 KB, created by
Jonathan Druart
on 2026-01-09 14:51:23 UTC
(
hide
)
Description:
Bug 41575: pos - auto tidy
Filename:
MIME Type:
Creator:
Jonathan Druart
Created:
2026-01-09 14:51:23 UTC
Size:
29.02 KB
patch
obsolete
>From fa9c00d72e31437b2950d5beba4b9c85582b2c95 Mon Sep 17 00:00:00 2001 >From: Jonathan Druart <jonathan.druart@bugs.koha-community.org> >Date: Fri, 9 Jan 2026 13:15:28 +0100 >Subject: [PATCH] Bug 41575: pos - auto tidy > >--- > .../intranet-tmpl/prog/en/modules/pos/pay.tt | 204 +++++++++-------- > .../prog/en/modules/pos/register.tt | 207 +++++++++--------- > .../prog/en/modules/pos/registers.tt | 22 +- > 3 files changed, 219 insertions(+), 214 deletions(-) > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/pos/pay.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/pos/pay.tt >index 1a95ed9ecc7..694e845e0f8 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/pos/pay.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/pos/pay.tt >@@ -258,22 +258,20 @@ > FinePaymentAutoPopup: [% Koha.Preference('FinePaymentAutoPopup') ? 1 : 0 | html %], > }); > </script> >- > <script> > function moneyFormat(textObj) { > var newValue = textObj.value; > var decAmount = ""; > var dolAmount = ""; >- var dolFlag = false; >- var aChar = ""; >+ var dolFlag = false; >+ var aChar = ""; > >- for(var i = newValue.length; 0 < i; i--) { >- aChar = newValue.substring(i-1, i); >+ for (var i = newValue.length; 0 < i; i--) { >+ aChar = newValue.substring(i - 1, i); > if ("0" <= aChar && aChar <= "9") { >- if(dolFlag) { >+ if (dolFlag) { > dolAmount = "" + aChar + dolAmount; >- } >- else { >+ } else { > decAmount = "" + aChar + decAmount; > } > } >@@ -290,47 +288,39 @@ > if (dolAmount == "") { > dolAmount = "0"; > } >- // Strip leading 0s >+ // Strip leading 0s > if (dolAmount.length > 1) { >- while(dolAmount.length > 1 && dolAmount.substring(0,1) == "0") { >- dolAmount = dolAmount.substring(1,dolAmount.length); >+ while (dolAmount.length > 1 && dolAmount.substring(0, 1) == "0") { >+ dolAmount = dolAmount.substring(1, dolAmount.length); > } > } > if (decAmount.length > 2) { >- decAmount = decAmount.substring(0,2); >+ decAmount = decAmount.substring(0, 2); > } >- // Pad right side >+ // Pad right side > if (decAmount.length == 1) { >- decAmount = decAmount + "0"; >+ decAmount = decAmount + "0"; > } > if (decAmount.length == 0) { >- decAmount = decAmount + "00"; >+ decAmount = decAmount + "00"; > } > > textObj.value = dolAmount + "." + decAmount; > } > >- function fnClickAddRow( table, invoiceCode, invoiceTitle, invoicePrice ) { >- var defaultPrice = { value: invoicePrice }; >- moneyFormat(defaultPrice); >- 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(); >+ function fnClickAddRow(table, invoiceCode, invoiceTitle, invoicePrice) { >+ var defaultPrice = { value: invoicePrice }; >+ moneyFormat(defaultPrice); >+ 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(); > } > > function updateChangeValues() { >- var change = $('#change')[0]; >- change.innerHTML = Math.round(($('#tendered')[0].value - $('#paid')[0].value) * 100) / 100; >+ var change = $("#change")[0]; >+ change.innerHTML = Math.round(($("#tendered")[0].value - $("#paid")[0].value) * 100) / 100; > if (change.innerHTML <= 0) { >- var paid = $('#paid')[0]; >+ var paid = $("#paid")[0]; > moneyFormat(paid); >- $('#tendered').rules( "add", { min: Number(paid.value) }); >+ $("#tendered").rules("add", { min: Number(paid.value) }); > change.innerHTML = zero_formatted; > $(':input[name="change"]').val(zero_formatted); > } else { >@@ -340,42 +330,48 @@ > $(':input[name="change"]').val(change.value); > } > >- $('#modal_change').html(change.innerHTML); >+ $("#modal_change").html(change.innerHTML); > } > >- $(document).ready(function() { >- const sale_table = document.getElementById('sale'); >+ $(document).ready(function () { >+ const sale_table = document.getElementById("sale"); > const sale_kohaTable = $("#sale").kohaTable({ > paging: false, > searching: false, > info: false, >- columnDefs: [{ >- "targets": [-2], >- "orderable": false, >- "searchable": false, >- }, { >- targets: [-3], >- render: function ( data, type, full ) { >- var price = Number.parseFloat(data); >- return price.format_price(); >- } >- }, { >- targets: [-5], >- className: "editable", >- }, { >- targets: [-4], >- className: "editable_int", >- }, { >- targets: [-1], >- visible: false, >- searchable: false >- }], >- rowCallback: function( row, data ) { >+ columnDefs: [ >+ { >+ targets: [-2], >+ orderable: false, >+ searchable: false, >+ }, >+ { >+ targets: [-3], >+ render: function (data, type, full) { >+ var price = Number.parseFloat(data); >+ return price.format_price(); >+ }, >+ }, >+ { >+ targets: [-5], >+ className: "editable", >+ }, >+ { >+ targets: [-4], >+ className: "editable_int", >+ }, >+ { >+ targets: [-1], >+ visible: false, >+ searchable: false, >+ }, >+ ], >+ rowCallback: function (row, data) { > const total = data[1] * data[2]; > data[3] = total; > sale_kohaTable.api().cell(row, 3).invalidate(); > }, >- footerCallback: function(tfoot, data, start, end, display) { >+ footerCallback: function (tfoot, data, start, end, display) { > let total_price = 0; > > // Loop through the data to calculate the total >@@ -387,53 +383,53 @@ > total_price = total_price.format_price(); > > // Update the footer cell >- $(tfoot).find('td').eq(1).html(total_price); >+ $(tfoot).find("td").eq(1).html(total_price); > > // Update a related element and trigger change >- $('#paid').val(total_price).trigger('change'); >+ $("#paid").val(total_price).trigger("change"); > }, >- autoWidth: false >+ autoWidth: false, > }); > >- $("#sale").on("click", "button.drop", function(){ >- sale_kohaTable.api().row($(this).parents('tr')).remove().draw(false); >+ $("#sale").on("click", "button.drop", function () { >+ sale_kohaTable.api().row($(this).parents("tr")).remove().draw(false); > }); > > // Set up editable columns based on header classes >- const editableColumns = Array.from(sale_table.querySelectorAll('thead th')) >+ const editableColumns = Array.from(sale_table.querySelectorAll("thead th")) > .map((header, index) => { >- if (header.classList.contains('editable') || header.classList.contains('editable_int')) { >- return { index: index, type: header.classList.contains('editable_int') ? 'number' : 'text' }; >+ if (header.classList.contains("editable") || header.classList.contains("editable_int")) { >+ return { index: index, type: header.classList.contains("editable_int") ? "number" : "text" }; > } > return null; > }) > .filter(column => column !== null); // Filter out non-editable columns > >- sale_table.querySelector('tbody').addEventListener('click', function (event) { >- const cell = event.target.closest('td'); >+ sale_table.querySelector("tbody").addEventListener("click", function (event) { >+ const cell = event.target.closest("td"); > if (!cell) return; > > const cellIndex = cell.cellIndex; > const editableColumn = editableColumns.find(column => column.index === cellIndex); > if (editableColumn) { > const originalContent = cell.textContent.trim(); >- const input = document.createElement('input'); >+ const input = document.createElement("input"); > input.type = editableColumn.type; > input.value = originalContent; >- input.style.width = '8em'; >+ input.style.width = "8em"; > > // Prevent click on numeric up/down buttons from closing input >- input.addEventListener('click', (e) => e.stopPropagation()); >+ input.addEventListener("click", e => e.stopPropagation()); > > // Replace cell content with the input >- cell.textContent = ''; >+ cell.textContent = ""; > cell.appendChild(input); > input.focus(); > > // Handle blur and Enter key events >- input.addEventListener('blur', updateCell); >- input.addEventListener('keydown', function(e) { >- if (e.key === 'Enter') { >+ input.addEventListener("blur", updateCell); >+ input.addEventListener("keydown", function (e) { >+ if (e.key === "Enter") { > e.preventDefault(); > e.stopPropagation(); > updateCell(); >@@ -458,56 +454,56 @@ > false > ); > >- $("#invoices").on("click", ".add_button", function(e) { >+ $("#invoices").on("click", ".add_button", function (e) { > e.preventDefault(); >- fnClickAddRow(sale_kohaTable.api(), $( this ).data('invoiceCode'), $( this ).data('invoiceTitle'), $( this ).data('invoicePrice') ); >- if($('#invoices_filter').find('input[type=search]').val() !== ''){ >- items_table.DataTable().search('').draw(); >+ fnClickAddRow(sale_kohaTable.api(), $(this).data("invoiceCode"), $(this).data("invoiceTitle"), $(this).data("invoicePrice")); >+ if ($("#invoices_filter").find("input[type=search]").val() !== "") { >+ items_table.DataTable().search("").draw(); > } > }); > > // Change calculation and modal >- var change = $('#change')[0]; >- $("#paid, #tendered").on("change",function() { >- moneyFormat( this ); >+ var change = $("#change")[0]; >+ $("#paid, #tendered").on("change", function () { >+ moneyFormat(this); > if (change != undefined) { > updateChangeValues(); > } > }); > > var checked = false; >- $('#modal_submit').click(function() { >+ $("#modal_submit").click(function () { > checked = true; >- $('#payForm').submit(); >+ $("#payForm").submit(); > }); > >- $('#payForm').validate({ >+ $("#payForm").validate({ > rules: { > paid: { >- required: true >+ required: true, > }, > tendered: { >- required: true >+ required: true, > }, > payment_type: { >- required: true >+ required: true, > }, > registerid: { >- required: true >- } >- } >+ required: true, >+ }, >+ }, > }); > >- $('#payForm').submit(function(e){ >+ $("#payForm").submit(function (e) { > // first, clear stale sales 'rows' from the payForm >- if($('input[name="sales"]').length > 0) { >- $('input[name="sales"]').each(function() { >+ if ($('input[name="sales"]').length > 0) { >+ $('input[name="sales"]').each(function () { > $(this).remove(); > }); > } > > // now, process the current & fresh contents of the sale_kohaTable >- if (change != undefined && change.innerHTML > 0.00 && !checked) { >+ if (change != undefined && change.innerHTML > 0.0 && !checked) { > e.preventDefault(); > $("#confirm_change_form").modal("show"); > } else { >@@ -516,21 +512,23 @@ > var sale = { > code: row[5], > price: row[1], >- quantity: row[2] >+ quantity: row[2], > }; >- $('<input>').attr({ >- type: 'hidden', >- name: 'sales', >- value: JSON.stringify(sale) >- }).appendTo('#payForm'); >+ $("<input>") >+ .attr({ >+ type: "hidden", >+ name: "sales", >+ value: JSON.stringify(sale), >+ }) >+ .appendTo("#payForm"); > }); > return true; > } > }); > >- if (payment_id && prefs.FinePaymentAutoPopup){ >- $("#printReceipt").click(function() { >- var win = window.open(`/cgi-bin/koha/pos/printreceipt.pl?action=print&accountlines_id=${payment_id}&tendered=${tendered}&change=${change}`, '_blank'); >+ if (payment_id && prefs.FinePaymentAutoPopup) { >+ $("#printReceipt").click(function () { >+ var win = window.open(`/cgi-bin/koha/pos/printreceipt.pl?action=print&accountlines_id=${payment_id}&tendered=${tendered}&change=${change}`, "_blank"); > win.focus(); > }); > $("#printReceipt").click(); >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/pos/register.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/pos/register.tt >index b1f47f9dfe7..6c7ec344d6b 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/pos/register.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/pos/register.tt >@@ -451,135 +451,144 @@ > description: "[% register.description | html %]", > }; > </script> >- > <script> > var sales_table = $("#sales").kohaTable({ >- orderFixed: [ 0, 'asc'], >+ orderFixed: [0, "asc"], > ordering: false, >- columnDefs: [ { >- targets: [ 0, 1 ], >- visible: false >- }], >+ columnDefs: [ >+ { >+ targets: [0, 1], >+ visible: false, >+ }, >+ ], > rowGroup: { > dataSrc: 0, >- startRender: function ( rows, group ) { >- if ( group ) { >- var details = JSON.parse(rows.data().pluck(1).pop()); >- var identifier = details.identifier || group; >- return $('<tr class="'+details.type+'"/>') >- .append( '<td>'+details.timestamp+' ('+identifier+')</td>' ) >- .append( '<td colspan="2">'+details.description+'</td>' ) >- .append( '<td>'+details.amount+'</td>' ) >- .append( '<td><button class="printReceipt btn btn-default btn-xs" data-accountline="'+group+'"><i class="fa fa-print"></i> ' + _("Print receipt") + '</button></td>'); >+ startRender: function (rows, group) { >+ if (group) { >+ var details = JSON.parse(rows.data().pluck(1).pop()); >+ var identifier = details.identifier || group; >+ return $('<tr class="' + details.type + '"/>') >+ .append("<td>" + details.timestamp + " (" + identifier + ")</td>") >+ .append('<td colspan="2">' + details.description + "</td>") >+ .append("<td>" + details.amount + "</td>") >+ .append('<td><button class="printReceipt btn btn-default btn-xs" data-accountline="' + group + '"><i class="fa fa-print"></i> ' + _("Print receipt") + "</button></td>"); > } > }, > endRender: null, > }, >- initComplete: function() { >+ initComplete: function () { > $("#sales").show(); >- } >+ }, > }); > > var past_sales_table = $("#past_sales").kohaTable({ >- orderFixed: [ 0, 'asc'], >+ orderFixed: [0, "asc"], > ordering: false, >- columnDefs: [ { >- targets: [ 0, 1 ], >- visible: false >- }], >+ columnDefs: [ >+ { >+ targets: [0, 1], >+ visible: false, >+ }, >+ ], > rowGroup: { > dataSrc: 0, >- startRender: function ( rows, group ) { >+ startRender: function (rows, group) { > var details = JSON.parse(rows.data().pluck(1).pop()); > var identifier = details.identifier || group; >- return $('<tr class="'+details.type+'"/>') >- .append( '<td>'+details.timestamp+' ('+identifier+')</td>' ) >- .append( '<td colspan="2">'+details.description+'</td>' ) >- .append( '<td>'+details.amount+'</td>' ) >- .append( '<td><button class="printReceipt btn btn-default btn-xs" data-accountline="'+group+'"><i class="fa fa-print"></i> Print receipt</button></td>'); >+ return $('<tr class="' + details.type + '"/>') >+ .append("<td>" + details.timestamp + " (" + identifier + ")</td>") >+ .append('<td colspan="2">' + details.description + "</td>") >+ .append("<td>" + details.amount + "</td>") >+ .append('<td><button class="printReceipt btn btn-default btn-xs" data-accountline="' + group + '"><i class="fa fa-print"></i> Print receipt</button></td>'); > }, > endRender: null, >- } >+ }, > }); > >- $("#issueRefundModal").on("shown.bs.modal", function(e){ >- var button = $(e.relatedTarget); >- var item = button.data('item'); >- $("#item + span").replaceWith(item); >- var accountline = button.data('accountline'); >- $('#refundline').val(accountline); >- var amount = button.data('amount'); >- var amountoutstanding = button.data('amountoutstanding') || 0; >- var paid = amount - amountoutstanding; >- $("#paid + span").text(paid.format_price()); >- $("#returned").attr({ "value": paid.format_price(), "max": paid }); >- var member = button.data('member'); >- if ( member === '' ) { >- $("#refund_type option[value='AC']").remove(); >- } else if ( $("#refund_type option[value='AC']").length == 0 ) { >- $("#refund_type").prepend('<option value="AC" selected="selected">Account credit</option>'); >- } >- $("#returned, #refund_type").focus(); >+ $("#issueRefundModal").on("shown.bs.modal", function (e) { >+ var button = $(e.relatedTarget); >+ var item = button.data("item"); >+ $("#item + span").replaceWith(item); >+ var accountline = button.data("accountline"); >+ $("#refundline").val(accountline); >+ var amount = button.data("amount"); >+ var amountoutstanding = button.data("amountoutstanding") || 0; >+ var paid = amount - amountoutstanding; >+ $("#paid + span").text(paid.format_price()); >+ $("#returned").attr({ value: paid.format_price(), max: paid }); >+ var member = button.data("member"); >+ if (member === "") { >+ $("#refund_type option[value='AC']").remove(); >+ } else if ($("#refund_type option[value='AC']").length == 0) { >+ $("#refund_type").prepend('<option value="AC" selected="selected">Account credit</option>'); >+ } >+ $("#returned, #refund_type").focus(); > }); > >- $("body").on('click', ".printReceipt", function() { >- var accountlines_id = $(this).data('accountline'); >- var win = window.open('/cgi-bin/koha/pos/printreceipt.pl?action=print&accountlines_id=' + accountlines_id, '_blank'); >+ $("body").on("click", ".printReceipt", function () { >+ var accountlines_id = $(this).data("accountline"); >+ var win = window.open("/cgi-bin/koha/pos/printreceipt.pl?action=print&accountlines_id=" + accountlines_id, "_blank"); > win.focus(); > }); > > var cashups_table_url = `/api/v1/cash_registers/${register.id}/cashups?`; >- var cashups_table = $("#table_cashups").kohaTable({ >- ajax: { >- "url": cashups_table_url >- }, >- embed: [ >- "manager" >- ], >- order: [[ 0, "desc" ]], >- columns: [ >- { >- data: "timestamp", >- searchable: true, >- orderable: true, >- render: function(data, type, row, meta) { >- return $datetime(row.timestamp); >- } >- }, >- { >- data: "manager.firstname:manager.surname", >- searchable: true, >- orderable: true, >- render: function(data, type, row, meta) { >- var fullname; >- if ( row.manager.firstname == null ) { >- fullname = row.manager.surname; >- } >- else { >- fullname = row.manager.firstname + " " + row.manager.surname; >- } >- return escape_str(fullname); >- } >- }, >- { >- data: "amount", >- searchable: true, >- orderable: true, >- render: function(data, type, row, meta) { >- var amt = row.amount * -1; >- return escape_price(amt); >- } >+ var cashups_table = $("#table_cashups").kohaTable( >+ { >+ ajax: { >+ url: cashups_table_url, > }, >- { >- data: function( row, type, val, meta ) { >- var result = '<a class="btn btn-default btn-xs" role="button" data-bs-toggle="modal" data-cashup="'+encodeURIComponent(row.cashup_id)+'" data-register="${register.description}" href="#cashupSummaryModal"><i class="fa-solid fa-pencil" aria-hidden="true"></i> '+_("Summary")+'</a>\n'; >- return result; >+ embed: ["manager"], >+ order: [[0, "desc"]], >+ columns: [ >+ { >+ data: "timestamp", >+ searchable: true, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ return $datetime(row.timestamp); >+ }, >+ }, >+ { >+ data: "manager.firstname:manager.surname", >+ searchable: true, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ var fullname; >+ if (row.manager.firstname == null) { >+ fullname = row.manager.surname; >+ } else { >+ fullname = row.manager.firstname + " " + row.manager.surname; >+ } >+ return escape_str(fullname); >+ }, > }, >- searchable: false, >- orderable: false >- } >- ] >- }, null, 1); >+ { >+ data: "amount", >+ searchable: true, >+ orderable: true, >+ render: function (data, type, row, meta) { >+ var amt = row.amount * -1; >+ return escape_price(amt); >+ }, >+ }, >+ { >+ data: function (row, type, val, meta) { >+ var result = >+ '<a class="btn btn-default btn-xs" role="button" data-bs-toggle="modal" data-cashup="' + >+ encodeURIComponent(row.cashup_id) + >+ '" data-register="${register.description}" href="#cashupSummaryModal"><i class="fa-solid fa-pencil" aria-hidden="true"></i> ' + >+ _("Summary") + >+ "</a>\n"; >+ return result; >+ }, >+ searchable: false, >+ orderable: false, >+ }, >+ ], >+ }, >+ null, >+ 1 >+ ); > </script> > [% END %] > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/pos/registers.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/pos/registers.tt >index 17cabc760ea..929aeaa0d22 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/pos/registers.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/pos/registers.tt >@@ -224,25 +224,23 @@ > $("#outgoing").text('[% dtotal | $Price %] ([% cdtotal | $Price %])'); > }); > </script> >- > <script> > $(document).ready(function () { >- > var registers_table = $("#registers").kohaTable({ > searching: false, > paginationType: "full", > }); > >- $("#confirmCashupModal").on("shown.bs.modal", function(e){ >- var button = $(e.relatedTarget); >- var register = button.data('register'); >- $("#registerc").text(register); >- var bankable = button.data('bankable'); >- $("#cashc").text(bankable); >- var rfloat = button.data('float'); >- $('#floatc').text(rfloat); >- var rid = button.data('registerid'); >- $('#cashup_registerid').val(rid); >+ $("#confirmCashupModal").on("shown.bs.modal", function (e) { >+ var button = $(e.relatedTarget); >+ var register = button.data("register"); >+ $("#registerc").text(register); >+ var bankable = button.data("bankable"); >+ $("#cashc").text(bankable); >+ var rfloat = button.data("float"); >+ $("#floatc").text(rfloat); >+ var rid = button.data("registerid"); >+ $("#cashup_registerid").val(rid); > }); > }); > </script> >-- >2.43.0 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 41575
:
191145
|
191146
|
191147
| 191148