1let totalAmount = 0; 2ACC.invoice = { 3 _autoload: [], 4 5 initializeAutoload: function () { 6 if (document.body.classList.contains('page-invoices')) { 7 this._autoload = [ 8 "singleInvoicePay", 9 "updateSelectAllCheckboxState", 10 "toggleAllCheckboxes", 11 "toggleIndividualCheckboxes", 12 "updateSelectedDataList", 13 "updatePayButtonState", 14 "loadPayButton", 15 "loadInvoice" 16 ]; 17 } 18 }, 19 20 singleInvoicePay: function () { 21 const headerRow = document.getElementById('default-row'); 22 const selectAllCheckbox = document.getElementById("select-all"); 23 const allCheckboxes = document.querySelectorAll('.invoice-checkbox:not(:disabled)'); 24 if (!headerRow || !selectAllCheckbox) return; 25 let isChecked = headerRow.classList.contains('active'); 26 27 selectAllCheckbox.checked = isChecked; 28 allCheckboxes.forEach((checkbox) => { 29 checkbox.checked = isChecked; 30 }); 31 ACC.invoice.updateSelectedDataList(); 32 ACC.invoice.updatePayButtonState() 33 }, 34 35 updateSelectAllCheckboxState: function () { 36 const allCheckboxes = document.querySelectorAll(".invoice-checkbox"); 37 const enabledCheckboxes = document.querySelectorAll(".invoice-checkbox:not(:disabled)"); 38 const selectAllCheckbox = document.getElementById("select-all"); 39 if (!selectAllCheckbox) return; 40 if (enabledCheckboxes.length === 0) { 41 selectAllCheckbox.checked = false; 42 return; 43 } 44 const allChecked = Array.from(enabledCheckboxes).every(checkbox => checkbox.checked); 45 selectAllCheckbox.checked = allChecked; 46}, 47 48toggleAllCheckboxes: function(source) { 49 if (!source) { 50 return; 51 } 52 const enabledCheckboxes = document.querySelectorAll(".invoice-checkbox:not(:disabled)"); 53 54 if (!enabledCheckboxes.length) { 55 source.checked = false; 56 return; 57 } 58 const isChecked = source.checked; 59 60 enabledCheckboxes.forEach((checkbox) => { 61 if (checkbox) { 62 checkbox.checked = isChecked; 63 } 64 }); 65 setTimeout(() => { 66 ACC.invoice.updateSelectAllCheckboxState(); 67 ACC.invoice.updateSelectedDataList(); 68 ACC.invoice.updatePayButtonState(); 69 }, 0); 70}, 71 72 toggleIndividualCheckboxes: function(source) { 73 const allCheckboxes = document.querySelectorAll(`[data-invoiceno="${source.dataset.invoiceno}"]`); 74 75 allCheckboxes.forEach((checkbox) => { 76 checkbox.checked = source.checked; 77 if (!checkbox.checked) { 78 checkbox.removeAttribute("checked"); 79 } else { 80 checkbox.setAttribute("checked", "checked"); 81 } 82 }); 83 ACC.invoice.updateSelectAllCheckboxState(); 84 ACC.invoice.updateSelectedDataList(); 85 ACC.invoice.updatePayButtonState(); 86 }, 87 88 updateSelectedDataList: function() { 89 90 const checkboxes = document.querySelectorAll(".invoice-checkbox:not(:disabled)"); 91 const selectedDataList = document.getElementById("selectedDataList"); 92 const totalAmountDiv = document.getElementById("totalAmountDiv"); 93 94 if (!selectedDataList) { 95 return 0; 96 } 97 98 let totalAmount = 0; 99 const selectedRows = new Set(); 100 selectedDataList.innerHTML = ""; 101 102 checkboxes.forEach((checkbox) => { 103 const row = checkbox.closest("tr"); 104 const rowIndex = row.rowIndex; 105 106 if (checkbox.checked) { 107 if (!selectedRows.has(rowIndex)) { 108 const cells = row.querySelectorAll("td"); 109 const orderNo = cells[9]?.textContent.trim(); 110 const dueDate = cells[13]?.textContent.trim(); 111 const amountText = cells[19]?.textContent.trim() || "0"; 112 const amount = parseFloat(amountText.replace(/[^0-9.]/g, "")) || 0; 113 const listItem = document.createElement("li"); 114 listItem.innerHTML = ` 115 <div class="order-no">${orderNo}</div> 116 <div class="due-date">${dueDate}</div> 117 <div class="amount">$${amount.toFixed(2)}</div> 118 `; 119 selectedDataList.appendChild(listItem); 120 121 totalAmount += amount; 122 selectedRows.add(rowIndex); 123 } 124 } else if (!checkbox.checked && selectedRows.has(rowIndex)) { 125 const listItem = selectedDataList.querySelector(`li[data-row-id="${rowIndex}"]`); 126 if (listItem) { 127 const amountText = listItem.querySelector(".amount").textContent.replace(/[^0-9.]/g, ""); 128 const amount = parseFloat(amountText) || 0; 129 totalAmount -= amount; 130 listItem.remove(); 131 selectedRows.delete(rowIndex); 132 } 133 } 134 }); 135 if (totalAmount > 0) { 136 totalAmountDiv.style.display = "block"; 137 totalAmountDiv.textContent = `$${totalAmount.toFixed(2)}`; 138 } else { 139 totalAmountDiv.style.display = "none"; 140 totalAmountDiv.textContent = ""; 141 } 142 143 return totalAmount; 144 }, 145 146 updatePayButtonState: function() { 147 const checkboxes = document.querySelectorAll('.invoice-checkbox:not(:disabled)'); 148 const payButton = document.getElementById('invoicePay'); 149 const invoiceNote = document.getElementById('invoicenote'); 150 const totalAmount = ACC.invoice.updateSelectedDataList(); 151 if (!payButton) { 152 return; 153 } 154 155 const isAnyChecked = Array.from(checkboxes).some(checkbox => checkbox.checked); 156 157 if (isAnyChecked && totalAmount > 0) { 158 payButton.disabled = false;
159 payButton.style.cursor = 'pointer'; 160 payButton.style.background = '#EF7206'; 161 payButton.style.border = '1px solid #EF7206'; 162 invoiceNote.style.display = 'block'; 163 } else { 164 payButton.disabled = true; 165 payButton.style.cursor = 'not-allowed'; 166 payButton.style.background = 'grey'; 167 payButton.style.border = '1px solid grey'; 168 invoiceNote.style.display = 'none'; 169 } 170}, 171 172 173 loadInvoice: function() { 174 const checkboxes = document.querySelectorAll(".invoice-checkbox:not(:disabled)"); 175 176 checkboxes.forEach((checkbox) => { 177 checkbox.addEventListener("change", function() { 178 ACC.invoice.toggleIndividualCheckboxes(this); 179 }); 180 checkbox.addEventListener("touchend", function(e) { 181 e.preventDefault(); 182 this.checked = !this.checked; 183 this.dispatchEvent(new Event("change", { bubbles: true })); 184 }); 185 const status = checkbox.getAttribute("data-status"); 186 if (status) { 187 const [invoiceStatus, isPendingPayment] = status.split("-"); 188 if (isPendingPayment === "true" || invoiceStatus === "Closed") { 189 checkbox.disabled = true; 190 checkbox.style.pointerEvents = "none"; 191 checkbox.style.cursor = "not-allowed"; 192 } 193 } 194 }); 195 196 document.getElementById("invoicePay").addEventListener("click", function () { 197 198 const totalAmountDue = document.getElementById("totalAmountDiv").innerText.trim(); 199 const selectedDataList = []; 200 var selectInvoicesNo =""; 201 document.querySelectorAll("#selectedDataList li").forEach((item) => { 202 const itemText = item.innerText.trim(); 203 204 if (itemText) { 205 const parts = itemText.split("\n"); 206 if (parts.length === 3) { 207 const invoiceNo = parts[0].replace("Invoice #", "").trim(); 208 const dueDate = parts[1].replace("Due:", "").trim(); 209 const invoiceAmount = parseFloat(parts[2].replace("$", "").trim()); 210 if (!isNaN(invoiceAmount)) { 211 selectedDataList.push({ invoiceNo, dueDate, invoiceAmount }); 212 selectInvoicesNo += invoiceNo+","; 213 } else { 214 console.error("Invalid amount in the list item:", parts[2]); 215 } 216 } else { 217 console.error("Invalid format in list item:", itemText); 218 } 219 } else { 220 console.error("Empty itemText found in list item"); 221 } 222 }); 223 const form = document.createElement("form"); 224 form.method = "GET"; 225 form.action = `/your-account/invoice/payment`; 226 form.style.display = "none"; 227 228 const input = document.createElement("input"); 229 input.type = "hidden"; 230 input.name = "invoices"; 231 input.value = selectInvoicesNo; 232 form.appendChild(input); 233 document.body.appendChild(form); 234 form.submit(); 235 236 }); 237 238 }, 239 240 loadPayButton: function() { 241 function validateForm() { 242 const cardholderName = document.getElementById("cardholder-name"); 243 const creditCardNumber = document.getElementById("credit-card-number");
244 const month = document.getElementById("month"); 245 const year = document.getElementById("year"); 246 const cvv = document.getElementById("card-cvv"); 247 const today = new Date(); 248 const currentYear = today.getFullYear(); 249 const currentMonth = today.getMonth() + 1; 250 const selectedYear = parseInt(year.value, 10); 251 const selectedMonth = parseInt(month.value, 10); 252 253 function checkLuhn(cardNumber) { 254 let sum = 0; 255 let shouldDouble = false; 256 257 for (let i = cardNumber.length - 1; i >= 0; i--) { 258 let digit = parseInt(cardNumber.charAt(i)); 259 if (shouldDouble) { 260 digit *= 2; 261 if (digit > 9) digit -= 9; 262 } 263 sum += digit; 264 shouldDouble = !shouldDouble; 265 } 266 267 return sum % 10 === 0; 268 } 269 270 let isValid = true; 271 272 document.querySelectorAll(".error-message").forEach(function (msg) { 273 msg.remove(); 274 }); 275 276 creditCardNumber.addEventListener('input', (e) => { 277 e.target.value = e.target.value.replace(/\D/g, '') 278 }); 279 280 cvv.addEventListener('input', (e) => { 281 e.target.value = e.target.value.replace(/\D/g, ""); 282 }); 283 284 if (!cardholderName.value.trim()) { 285 showError(cardholderName, "Please enter cardName"); 286 isValid = false; 287 } 288 289 if (!creditCardNumber.value.trim() || !/^\d+$/.test(creditCardNumber.value.trim())) { 290 showError(creditCardNumber, "Please enter cardNumber"); 291 isValid = false; 292 }else if (!checkLuhn(creditCardNumber.value.trim())) { 293 showError(creditCardNumber, "Invalid card number"); 294 isValid = false; 295 } 296 297 if (!month.value) { 298 showError(month, "Please select expiration month"); 299 isValid = false; 300 } 301 302 if (selectedYear === currentYear && selectedMonth < currentMonth) { 303 showError(month, "Invalid expiration month"); 304 isValid = false; 305 } 306 307 if (!year.value) { 308 showError(year, "Please select expiration year"); 309 isValid = false; 310 } 311 312 if (!/^\d{3,4}$/.test(cvv.value.trim())) { 313 showError(cvv, "Please enter cvv number"); 314 isValid = false; 315 } 316 317 return isValid; 318 } 319 320 function showError(element, message) { 321 const errorMessage = document.createElement("div"); 322 errorMessage.classList.add("error-message"); 323 errorMessage.style.color = "#c70000"; 324 errorMessage.style.fontSize = "13px"; 325 errorMessage.textContent = message; 326 element.parentNode.appendChild(errorMessage); 327 } 328 329 document.getElementById("credit-card-form").addEventListener("submit", function (event) { 330 if (!validateForm()) { 331 event.preventDefault(); 332 } 333 }); 334 } 335 336}; 337 338document.addEventListener("DOMContentLoaded", function () { 339 const selectAllCheckbox = document.querySelector('th input#select-all'); 340 function isMobileView() { 341 return window.matchMedia("(max-width: 768px)").matches; 342 } 343 function getRelevantCheckboxes() { 344 return document.querySelectorAll( 345 isMobileView() 346 ? 'td input.invoice-checkbox.hidden-md.hidden-lg' 347 : 'td input.invoice-checkbox.hidden-sm.hidden-xs' 348 ); 349 } 350 351 function updateSelectAllCheckbox() { 352 const tbodyCheckboxes = getRelevantCheckboxes(); 353 if (!selectAllCheckbox) return; 354 355 const enabledCheckboxes = Array.from(tbodyCheckboxes).filter(checkbox => !checkbox.disabled); 356 const allDisabled = enabledCheckboxes.length === 0; 357 const allChecked = enabledCheckboxes.length > 0 && enabledCheckboxes.every(checkbox => checkbox.checked); 358 359 if (allDisabled) { 360 selectAllCheckbox.disabled = true; 361 selectAllCheckbox.setAttribute("disabled", ""); 362 selectAllCheckbox.style.pointerEvents = "none"; 363 selectAllCheckbox.style.cursor = "not-allowed"; 364 selectAllCheckbox.checked = false; 365 } else { 366 selectAllCheckbox.disabled = false; 367 selectAllCheckbox.removeAttribute("disabled"); 368 selectAllCheckbox.style.pointerEvents = ""; 369 selectAllCheckbox.style.cursor = ""; 370 selectAllCheckbox.checked = allChecked; 371 } 372 } 373 374 function handleIndividualCheckboxChange() { 375 updateSelectAllCheckbox(); 376 } 377 function addCheckboxListeners() { 378 document.querySelectorAll('td input.invoice-checkbox:not(:disabled)').forEach((checkbox) => { 379 checkbox.removeEventListener('change', handleIndividualCheckboxChange); 380 checkbox.addEventListener('change', handleIndividualCheckboxChange); 381 }); 382 } 383 function updateCheckedCheckboxes() { 384 const isChecked = selectAllCheckbox.checked;
385 getRelevantCheckboxes().forEach((checkbox) => { 386 if (!checkbox.hasAttribute("checked")&& !checkbox.disabled) { 387 checkbox.checked = isChecked; 388 } 389 checkbox.dispatchEvent(new Event('change')); 390 }); 391 } 392 393 394 function initializeSelectAllState() { 395 if (selectAllCheckbox && selectAllCheckbox.hasAttribute('checked')) { 396 selectAllCheckbox.checked = true; 397 } 398 } 399 if (selectAllCheckbox) { 400 selectAllCheckbox.addEventListener('change', updateCheckedCheckboxes); 401 } 402 403 setTimeout(function() { 404 updateCheckedCheckboxes(); 405 initializeSelectAllState(); 406 },0); 407 new MutationObserver((mutations) => { 408 let checkboxUpdated = false 409 mutations.forEach((mutation) => { 410 mutation.addedNodes.forEach((node) => { 411 if (node.nodeType === 1 && node.matches("td")) { 412 const checkbox = node.querySelector("input.invoice-checkbox[checked]"); 413 if (checkbox) { 414 checkbox.checked = checkbox.checked; 415 checkbox.dispatchEvent(new Event('change')); 416 checkboxUpdated = true; 417 } 418 } 419 }); 420 }); 421 }).observe(document.body, { childList: true, subtree: true }); 422 updateSelectAllCheckbox(); 423 addCheckboxListeners(); 424 ACC.invoice.loadInvoice(); 425 426 const rows = document.querySelectorAll("table tr"); 427 if (rows.length === 2) { 428 const checkboxes = rows[0].querySelectorAll(".invoice-checkbox"); 429 const checkboxesMobile = rows[1].querySelectorAll(".invoice-checkbox"); 430 431 if (checkboxes.length === 1) { 432 checkboxes[0].checked = true; 433 checkboxesMobile[0].checked = true; 434 ACC.invoice.updatePayButtonState(); 435 } 436 } 437}); 438document.addEventListener("touchend", function (event) { 439 if (event.target.classList.contains("invoice-checkbox")) { 440 setTimeout(() => { 441 ACC.invoice.updateSelectedDataList(); 442 ACC.invoice.updatePayButtonState(); 443 }, 100); 444 } 445});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.