| @@ -371,9 +371,9 @@ | ||
| 371 | 371 | if (window.easyInvoice && window.easyInvoice.showAdjustField) { |
| 372 | 372 | adjustPercentage = parseFloat($item.find('input[name*="[adjust_percentage]"]').val()) || 0; |
| 373 | 373 | } |
| 374 | 374 | var baseTotal = quantity * price; |
| 375 | - var total = baseTotal * (1 + adjustPercentage / 100); | |
| 375 | + var total = easyInvoiceRoundMoney(baseTotal * (1 + adjustPercentage / 100)); | |
| 376 | 376 | |
| 377 | 377 | // Update the total field |
| 378 | 378 | var $totalField = $item.find('input[name*="[total]"]'); |
| 379 | 379 | $totalField.val(total.toFixed(2)); |
| @@ -407,9 +407,9 @@ | ||
| 407 | 407 | if (window.easyInvoice && window.easyInvoice.showAdjustField) { |
| 408 | 408 | adjustPercentage = parseFloat($item.find('input[name*="[adjust_percentage]"]').val()) || 0; |
| 409 | 409 | } |
| 410 | 410 | var baseTotal = quantity * price; |
| 411 | - var total = baseTotal * (1 + adjustPercentage / 100); | |
| 411 | + var total = easyInvoiceRoundMoney(baseTotal * (1 + adjustPercentage / 100)); | |
| 412 | 412 | |
| 413 | 413 | $item.find('.quantity-summary').text(quantity); |
| 414 | 414 | $item.find('.price-summary').text(price.toFixed(2)); |
| 415 | 415 | $item.find('.total-summary').text(total.toFixed(2)); |
| @@ -559,9 +559,9 @@ | ||
| 559 | 559 | // Update client info fields |
| 560 | 560 | $('#client_name_display').text(client.name || ''); |
| 561 | 561 | $('#client_email_display').text(client.email || ''); |
| 562 | 562 | $('#client_phone_display').text(client.phone || ''); |
| 563 | - $('#client_address_display').html((client.address || '').replace(/\n/g, '<br>')); | |
| 563 | + $('#client_address_display').html(easyInvoiceAddressHtml(client.address)); | |
| 564 | 564 | |
| 565 | 565 | // Show client info section |
| 566 | 566 | $('#client_info').show(); |
| 567 | 567 | return; |
| @@ -583,9 +583,9 @@ | ||
| 583 | 583 | // Update client info fields |
| 584 | 584 | $('#client_name_display').text(client.name); |
| 585 | 585 | $('#client_email_display').text(client.email); |
| 586 | 586 | $('#client_phone_display').text(client.phone || ''); |
| 587 | - $('#client_address_display').html(client.address.replace(/\n/g, '<br>') || ''); | |
| 587 | + $('#client_address_display').html(easyInvoiceAddressHtml(client.address)); | |
| 588 | 588 | |
| 589 | 589 | // Show client info section |
| 590 | 590 | $('#client_info').show(); |
| 591 | 591 | } else { |
| @@ -1062,9 +1062,9 @@ | ||
| 1062 | 1062 | // Set client info if available |
| 1063 | 1063 | if (easyInvoice.clientData) { |
| 1064 | 1064 | $('#client_name_display').text(easyInvoice.clientData.name || ''); |
| 1065 | 1065 | $('#client_email_display').text(easyInvoice.clientData.email || ''); |
| 1066 | - $('#client_address_display').html((easyInvoice.clientData.address || '').replace(/\n/g, '<br>')); | |
| 1066 | + $('#client_address_display').html(easyInvoiceAddressHtml(easyInvoice.clientData.address)); | |
| 1067 | 1067 | $('#client_info').show(); |
| 1068 | 1068 | } |
| 1069 | 1069 | |
| 1070 | 1070 | // Set items |
| @@ -1383,10 +1383,22 @@ | ||
| 1383 | 1383 | this.setupClientSelection(); |
| 1384 | 1384 | } |
| 1385 | 1385 | }; |
| 1386 | 1386 | |
| 1387 | +// Address text -> HTML with line breaks, escaped: the address is what the | |
| 1388 | +// client typed into their portal profile, so it must never reach .html() raw. | |
| 1389 | +// Half-up rounding to cents, matching PHP round($x, 2) (7 x 1.005 is 7.04, not | |
| 1390 | +// the 7.03 that toFixed() gives from binary floats). | |
| 1391 | +function easyInvoiceRoundMoney(v) { | |
| 1392 | + return Number(Math.round(Number((parseFloat(v) || 0) + 'e2')) + 'e-2'); | |
| 1393 | +} | |
| 1394 | + | |
| 1395 | +function easyInvoiceAddressHtml(address) { | |
| 1396 | + return jQuery('<div>').text(address || '').html().replace(/\n/g, '<br>'); | |
| 1397 | +} | |
| 1398 | + | |
| 1387 | 1399 | // Initialize invoice builder when document is ready |
| 1388 | - jQuery(document).ready(function($) { | |
| 1400 | +jQuery(document).ready(function($) { | |
| 1389 | 1401 | // Initialize the invoice builder |
| 1390 | 1402 | if (typeof EasyInvoiceBuilder !== 'undefined') { |
| 1391 | 1403 | EasyInvoiceBuilder.init(); |
| 1392 | 1404 | } |