1function getHourList(startHour, endHour) 2{ 3 var hours = []; 4 5 if(!isNaN(startHour) && !isNaN(endHour)) 6 { 7 for(var i = startHour; i <= endHour; i++) 8 { 9 var ampm = (i > 11 ? "pm" : "am"); 10 var hour = i.toString(); 11 if(hour > 12) 12 { 13 hour -= 12; 14 } 15 hours.push({"name":hour + ":00" + ampm}); 16 if(i !== endHour) 17 { 18 hours.push({"name":hour + ":30" + ampm}); 19 } 20 } 21 } 22 return hours; 23} 24 25function selectOption(coll, selection) 26{ 27 for(var i = 0; i < coll.length; i++) 28 { 29 if(coll[i].name === selection) 30 { 31 return coll[i]; 32 } 33 } 34 return coll[0]; 35} 36 37function checkAndParseFloat(value) 38{ 39 var result = 0; 40 if(value !== null && !isNaN(value) && value !== "") 41 { 42 result = parseFloat(value); 43 } 44 return result; 45} 46 47function validateAndParseFloat(a_number) { 48 "use strict"; 49 var return_value = 0; 50 51 if (a_number) { 52 return_value = parseFloat(a_number); 53 if ((isNaN(return_value)) || (return_value === null)) { 54 return_value = 0; 55 } 56 } 57 58 return return_value; 59} 60 61function roundAndFixNumberAsString(a_number) { 62 "use strict"; 63 var value = validateAndParseFloat(a_number); 64 65 var return_value = ''; 66 67 return_value = Number(Math.round(value + 'e' + 2) + 'e-' + 2).toFixed(2); 68 69 return return_value; 70} 71 72function roundAndFixNumberAsNumber(a_number) { 73 "use strict"; 74 var value = validateAndParseFloat(a_number); 75 76 var return_value = ''; 77 78 return_value = Number(Math.round(value + 'e' + 2) + 'e-' + 2); 79 80 return return_value; 81} 82 83// This is here because toFixed has bugs when rounding and is not reliable 84function roundNumber(value, precision) { 85 if (!value) { 86 return 0; 87 } 88 89 if (precision <= 0) { 90 precision = 0; 91 } else if (!precision) { 92 precision = 2; 93 } 94 95 var p = Math.pow(10, precision); 96 return Math.round(value * p) / p; 97} 98 99function intersect_arrays(first, second) { 100 "use strict"; 101 var common = []; 102 103 if ((first) && (second)) { 104 var sorted_a = first.concat().sort(); 105 var sorted_b = second.concat().sort(); 106 var first_i = 0; 107 var second_i = 0; 108 109 while (first_i < first.length && second_i < second.length) { 110 if ((sorted_a[first_i] === sorted_b[second_i]) || (parseInt(sorted_a[first_i]) === parseInt(sorted_b[second_i]))){ 111 common.push(sorted_a[first_i]); 112 first_i++; 113 second_i++; 114 } 115 else if (sorted_a[first_i] < sorted_b[second_i]) { 116 first_i++; 117 } 118 else { 119 second_i++; 120 } 121 } 122 } 123 124 return common; 125} 126 127function roundIt(amount) 128{ 129 var bd = new BigDecimal(amount); 130 var rounded = bd.setScale(2, BigDecimal.ROUND_HALF_UP); 131 return parseFloat(rounded.toString()); 132} 133 134function getNextDate(date, interval) 135{ 136 var parsed = dateFns.parse(date); 137 switch(interval) 138 { 139 case 'Weekly': 140 return dateFns.format(dateFns.addWeeks(parsed, 1), "M/D/YYYY"); 141 case 'Bi-Weekly': 142 return dateFns.format(dateFns.addWeeks(parsed, 2), "M/D/YYYY"); 143 case 'Monthly': 144 return dateFns.format(dateFns.addMonths(parsed, 1), "M/D/YYYY"); 145 case 'Yearly': 146 return dateFns.format(dateFns.addYears(parsed, 1), "M/D/YYYY"); 147 default: 148 break; 149 } 150} 151 152function todaysDateString() 153{ 154 var today = new Date(); 155 return (today.getMonth()+1) + "/" + today.getDate() + "/" + today.getFullYear(); 156} 157 158function formatPhone(phone_text) { 159 if (phone_text !== undefined && phone_text !== null) { 160 161 if (phone_text.charAt(0) == '+' && phone_text.length > 10) { 162 phone_text = formatPhone(phone_text.substr(1)); 163 } else if (phone_text.length >= 10) { 164 var temp_text = phone_text.replace(/[\- \(\)+]/g, ""); 165 var start = temp_text.length - 10; 166 var end = temp_text.length; 167 phone_text = temp_text.substr(start,end).replace(/(\d{3})(\d{3})(\d{4})/, "($1) $2-$3"); 168 } else if (phone_text.length >= 7) { 169 var temp_text = phone_text.replace(/[\- \(\)+]/g, ""); 170 var start = temp_text.length - 7; 171 var end = temp_text.length; 172 phone_text = temp_text.substr(start,end).replace(/(\d{3})(\d{4})/, "$1-$2"); 173 } 174 175 if (phone_text.length === 10) { 176 177 phone_text = phone_text.replace(/(\d{3})(\d{3})(\d{4})/, "($1) $2-$3"); 178 } else if (phone_text.length === 7) { 179 180 phone_text = phone_text.replace(/(\d{3})(\d{4})/, "$1-$2"); 181 } 182 } 183 return phone_text; 184} 185 186function getPaymentInfo(total, term, start_date, due_date) 187{ 188 "use strict"; 189 var info = new Object(); 190 if(start_date === null) 191 { 192 start_date = todaysDateString(); 193 } 194 195 var startDate = moment(start_date); 196 197 var dueDate = moment(due_date); 198 199 var numOfPayments = dueDate.diff(startDate, term); 200 var lastRegularPaymentDate = startDate.add(term, numOfPayments); 201 202 //console.log('Difference is ', numOfPayments, term); 203 var daysLeft = dueDate.diff(lastRegularPaymentDate, 'days'); 204 if(daysLeft > 0) 205 { 206 numOfPayments++; 207 } 208 //console.log('Days remainder ', daysLeft); 209 210 info.payment_amount = Math.round(total/numOfPayments); 211 info.final_payment_amount = total - (info.payment_amount * numOfPayments); 212 info.num_of_payments = numOfPayments-1; 213 if(daysLeft >= 0) 214 { 215 info.final_payment_amount = info.final_payment_amount + info.payment_amount; 216 } 217 //console.log('payment amount ', payment*2); 218 219 //console.log(daysLeft); 220 //console.log(lastRegularPaymentDate.format("l")); 221 return info; 222} 223 224function removeFromArray(key, myArray) 225{ 226 "use strict"; 227 for(var i = myArray.length-1; i >= 0; i--){ // STEP 1 228 if(myArray[i].key === key){ // STEP 2 229 myArray.splice(i,1); // STEP 3 230 } 231 } 232 return myArray; 233} 234 235function is_array(value) { 236 "use strict"; 237 if (value) { 238 return value && 239 typeof value === 'object' && 240 typeof value.length === 'number' && 241 typeof value.splice === 'function' && 242 !(value.propertyIsEnumerable('length')); 243 } else { 244 return false;
245 } 246}; 247 248function getCardType(cc_number) { 249 250 var card_type = ""; 251 252 if(!isNaN(cc_number)) { 253 254 var num = cc_number.substring(0, 1); 255 num = parseInt(num); 256 257 switch (num) { 258 259 case 3: 260 card_type = "AMEX"; 261 break; 262 case 4: 263 card_type = "VISA"; 264 break; 265 case 5: 266 card_type = "MC"; 267 break; 268 case 6: 269 card_type = "DISC"; 270 break; 271 default: 272 break; 273 } 274 } 275 276 return card_type; 277}; 278 279function is_set(val) { 280 281 return (val !== undefined && val !== null); 282}; 283 284function objectIsEmpty(obj) { 285 286 return !obj || Object.keys(obj).length <= 0; 287}; 288 289function is_undefined(val) { 290 291 return (typeof val === "undefined"); 292}; 293 294function toFixedNoZero(x, d) { 295 if (!d) return x.toFixed(d); // don't go wrong if no decimal 296 return x.toFixed(d).replace(/\.?0+$/, ''); 297}; 298 299function diffInMonths(date1, date2) { 300 301 var a = moment(date1); 302 var b = moment(date2); 303 return a.diff(b, 'months') 304}; 305 306function getYearsObjectsList(num_of_years, num_of_future_years_to_add) { 307 308 var now = new moment(); 309 var current_year = parseInt(now.format("YYYY")); 310 311 if(!is_set(num_of_years)) { 312 313 num_of_years = 20; 314 } 315 316 if(is_set(num_of_future_years_to_add)) { 317 318 num_of_years += num_of_future_years_to_add; 319 current_year += num_of_future_years_to_add; 320 } 321 322 var years = []; 323 for (var i = 0; i < num_of_years; i++) { 324 325 years.push({id:i, year:current_year}); 326 current_year--; 327 } 328 return years; 329}; 330 331function uppercaseFirstLetter(str) { 332 333 return str.charAt(0).toUpperCase() + str.slice(1); 334}; 335 336function getTotalAmountFromCollection(collection) { 337 338 var total = null; 339 if(collection) { 340 341 total = 0; 342 for(var i = 0; i < collection.length; i++) { 343 344 var item = collection[i]; 345 if(item.amount) { 346 347 total += parseFloat(item.amount); 348 } 349 } 350 } 351 return total; 352} 353 354function toNumeric(amount) { 355 356 if(amount) { 357 358 amount = amount.replace(/[^0-9\.]/g, ""); 359 } 360 return amount; 361} 362 363/** 364 * QTY Precision constant 365 */ 366var DEFAULT_QTY_PRECISION = 3; 367 368/** 369 * This method return amount value with 2 or 3 precision. 370 * We need this for smarty showing qty amount. 371 * If qty has 3 digits after decimal point we will show it 372 * In other case - show 2 digits 373 * */ 374function qtyAmountFormat(value, precision, hideDecimal = false) { 375 if (typeof precision === 'undefined') { 376 precision = DEFAULT_QTY_PRECISION; 377 } 378 var qtyAmount = roundNumber(value, precision); 379 if (hideDecimal) { 380 //If decimal is .00, get rid of them 381 if (qtyAmount % 1 === 0) { 382 return qtyAmount.toFixed(0); 383 } 384 } 385 if (qtyAmount.toString().indexOf('.') !== -1) { 386 var decimalPlaces = qtyAmount.toString().split('.')[1].length; 387 if (decimalPlaces < 3) { 388 qtyAmount = qtyAmount.toFixed(2); 389 } else { 390 qtyAmount = qtyAmount.toFixed(3); 391 } 392 } else { 393 qtyAmount = qtyAmount.toFixed(2); 394 } 395 396 return qtyAmount; 397} 398 399function is_string(val) { 400 return typeof val === 'string' || ((!!val && typeof val === 'object') && Object.prototype.toString.call(val) === '[object String]'); 401} 402 403function is_json(str) { 404 if (!(str && typeof str === "string")) { 405 return false; 406 } 407 408 try { 409 JSON.parse(str); 410 return true; 411 } catch(error) { 412 return false; 413 } 414} 415 416function isValidEmail(string){ 417 return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(string) 418} 419 420/** 421 * @link https://regex101.com/r/xI4jdu/5 for test list 422 * @param email 423 * @returns {boolean} 424 */ 425function isValidEmailV2(email){ 426 return /^[\w\d!#$%&'*+/=?^_`{|}~-]+(?:\.[\w\d!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w\d](?:[\w\d-]*[\w\d])?\.)+[\w\d](?:[\w\d-]*[\w\d])?$/.test(email); 427} 428 429function isSimplePhoneNumber(phoneNumber) { 430 //Can start with + must have >= 11 digits 431 //If no +, must have >= 10 digits 432 //Spaces okay 433 return /^(?:\+(\d\s?){11,}|(\d\s?){10,})$/.test(phoneNumber); 434} 435 436function isValidPostalCode(postalCode, countryIso3Code) { 437 if (!postalCode || !countryIso3Code) { 438 return false;
439 } 440 441 switch (countryIso3Code) { 442 case 'USA': 443 return /^\d{5}(?:-\d{4})?$/.test(postalCode); 444 case 'CAN': 445 return /^[A-Za-z]\d[A-Za-z][ -]?\d[A-Za-z]\d$/.test(postalCode); 446 case 'AUS': 447 case 'NZL': 448 return /^\d{4}$/.test(postalCode); 449 case 'GBR': 450 return /^[A-Za-z]{1,2}\d[A-Za-z\d]?\s?\d[A-Za-z]{2}$/.test(postalCode); 451 default: 452 return postalCode.length >= 3; 453 } 454} 455 456// This should mimic the logic of module levers 457function checkFlag(flagName) { 458 flagName = 'module_' + flagName; 459 return !is_undefined(window.knobby) && !is_undefined(window.knobby[flagName]) && window.knobby[flagName] === true; 460} 461 462function reportMarginCalculationWithoutRounding(cost, net) { 463 // Revenue = 0: undefined margin (--) : 464 // A product sold for 0.00, but the cost is greater than 0.00. We canât calculate the margin because it was given away for free. 465 if (net === 0 && cost > 0) { 466 return ' --'; 467 } 468 469 // Cost = 0, revenue > 0: 100% margin (100%): 470 // Product doesn't have a cost assigned. Or the cost assigned is $0. Therefore the entire amount of revenue collected is considered profit. 471 // roundedNet < 0 for return cases 472 if ((net > 0 || net < 0) && cost === 0) { 473 return '100.00%'; 474 } 475 476 // Revenue = Cost: zero margin (0%): 477 // Product is sold for exactly what it cost. 478 if (net === cost) { 479 return '0.00%'; 480 } 481 482 // Revenue < Cost: negative margin (-20%): 483 // Product is sold for less than it cost. You can go above a -100% margin, since items can cost significantly more than what might be collected in revenue. 484 // Revenue > Cost: positive margin (50%): 485 // Product is sold for more than it cost. This should be the most common use case, since stores would go out of business otherwise. 486 return (((net - cost)/net) * 100).toFixed(2)+'%'; 487 488} 489 490function handleDropDownMenuContentWidth() { 491 var dropDownMenus = document.querySelectorAll("ul.dropdown-menu.ng-isolate-scope"); 492 var handleContentWidth = function (el) { 493 var initialContent = el.textContent; 494 var checks = el.textContent.length; 495 var newContent = ''; 496 var newLines = []; 497 var offset = 5; 498 for (var i = 0; i < checks; i++) { 499 newContent += initialContent[i]; 500 el.innerHTML = newContent; 501 if (el.scrollWidth > el.clientWidth) { 502 newLines.push(newContent.slice(0, -offset)); 503 newContent = newContent.slice(-offset); 504 } 505 } 506 newLines.push(newContent); 507 el.innerHTML = newLines.join('<br />'); 508 } 509 510 /* Options for the observer (which mutations to observe) */ 511 var config = {childList: true}; 512 513 /* Callback function to execute when mutations are observed */ 514 var callback = function (mutationsList, observer) { 515 var menu = mutationsList.pop().target; 516 for (var child of menu.children) { 517 var ref = child.querySelector("a"); 518 if (ref.scrollWidth > ref.clientWidth) { 519 handleContentWidth(ref); 520 } 521 } 522 }; 523 524 /* Create an observer instance linked to the callback function */ 525 var observer = new MutationObserver(callback); 526 527 dropDownMenus.forEach(function (dropDownMenu) { 528 /* Start observing the target node for configured mutations */ 529 observer.observe(dropDownMenu, config); 530 }); 531} 532 533function getBrandSpecificTerm(term) { 534 var brandSpecificTerm = ''; 535 536 if (industryTerms !== undefined 537 && industryTerms[term] !== undefined) { 538 brandSpecificTerm = industryTerms[term]; 539 } else { 540 if (term === 'vendor_consignment') { 541 brandSpecificTerm = 'Vendor Consignment'; 542 } else if (term === 'vendor_consign') { 543 brandSpecificTerm = 'Vendor Consign'; 544 545 } 546 } 547 548 return brandSpecificTerm; 549} 550 551function waitForElm(selector) { 552 return new Promise(function(resolve) { 553 if (document.querySelector(selector)) { 554 return resolve(document.querySelector(selector)); 555 } 556 557 var observer = new MutationObserver(function(mutations) { 558 if (document.querySelector(selector)) { 559 resolve(document.querySelector(selector)); 560 observer.disconnect(); 561 } 562 }); 563 564 observer.observe(document.body, { 565 childList: true, 566 subtree: true 567 }); 568 }); 569} 570 571function isChromeInIos() { 572 return navigator.userAgent.toLowerCase().includes('crios'); 573} 574 575function printJSFixed(options) { 576 // print-js pdf print doesn't work in Chrome on IOS, because of a browser compatibility issue, 577 // so we do this workaround instead 578 if (checkFlag('print_ipad_fix') && (isChromeInIos() && 'pdf' === options.type && options.base64)) { 579 // Convert base64 to blob and create blob URL to avoid cross-origin restrictions 580 const base64Data = options.printable; 581 const byteCharacters = atob(base64Data); 582 const byteNumbers = new Array(byteCharacters.length); 583 584 for (let i = 0; i < byteCharacters.length; i++) {
585 byteNumbers[i] = byteCharacters.charCodeAt(i); 586 } 587 588 const byteArray = new Uint8Array(byteNumbers); 589 const blob = new Blob([byteArray], {type: 'application/pdf'}); 590 const blobUrl = URL.createObjectURL(blob); 591 592 let pdfWindow = window.open(blobUrl, '_blank'); 593 594 if (!pdfWindow) { 595 URL.revokeObjectURL(blobUrl); 596 return; 597 } 598 599 let hasPrinted = false; 600 601 // Wait for the PDF to load, then print the window directly 602 // Since the window only contains the PDF, printing the window will print the PDF 603 pdfWindow.onload = function() { 604 setTimeout(function() { 605 if (!hasPrinted) { 606 hasPrinted = true; 607 pdfWindow.print(); 608 609 setTimeout(function() { 610 URL.revokeObjectURL(blobUrl); 611 }, 1000); 612 } 613 }, 500); 614 }; 615 616 // Fallback: if onload doesn't fire, try printing after a delay 617 setTimeout(function() { 618 if (pdfWindow && !pdfWindow.closed && !hasPrinted) { 619 hasPrinted = true; 620 pdfWindow.print(); 621 622 setTimeout(function() { 623 URL.revokeObjectURL(blobUrl); 624 }, 1000); 625 } 626 }, 1000); 627 } else if (isChromeInIos() && 'pdf' === options.type && options.base64) { 628 var newWindow = window.open('', '_blank');
629 newWindow.document.write('<embed width="100%" height="100%" src="data:application/pdf;base64,' + options.printable + '" type="application/pdf"/>'); 630 newWindow.print(); 631 } else { 632 printJS(options); 633 } 634} 635 636function jqprintCheckChromeOnIOS(elements) { 637 // print doesn't work in Chrome on IOS, because of a browser compatibility issue, 638 // so we do this workaround instead 639 if (isChromeInIos()) { 640 let printWindow = window.open('', '_blank'); 641 642 printWindow.document.write($(elements).html()); 643 printWindow.document.close(); 644 printWindow.print(); 645 } else { 646 $(elements).jqprint({importCSS: true}); 647 } 648} 649 650function hasUserPermission(key) { 651 if (!window.hasOwnProperty('rain_permission')) { 652 return true; 653 } 654 655 var permission = window.rain_permission; 656 657 if (!permission.hasOwnProperty(key)) { 658 return false; 659 } 660 661 return permission[key]; 662} 663 664function arraySum(array) { 665 if (!Array.isArray(array)) { 666 return 0; 667 } 668 669 return array.reduce(function (carry, current) { 670 return carry + current; 671 }, 0); 672} 673 674function arrayUnique(array) { 675 if (!Array.isArray(array)) { 676 return []; 677 } 678 679 return array.filter(function(value, index, array) { 680 return array.indexOf(value) === index; 681 }); 682} 683 684function jsonToQueryParams(data) { 685 if (objectIsEmpty(data)) { 686 return ''; 687 } 688 689 return Object.keys(data).map(function(k) { 690 return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]) 691 }).join('&'); 692} 693 694function generateUniqueID() { 695 var d = new Date().getTime(); 696 var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 697 var r = (d + Math.random() * 16) % 16 | 0; 698 d = Math.floor(d / 16); 699 return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16); 700 }); 701 return uuid; 702} 703 704if (typeof getPartsDate === 'undefined') { 705 function getPartsDate(date) { 706 if (!date || typeof date !== 'string') { 707 return { 708 month: 0, 709 day: 0, 710 year: 0, 711 }; 712 } 713 var dateParts = date.split('/'); 714 715 return { 716 month: parseInt(dateParts[0], 10), 717 day: parseInt(dateParts[1], 10), 718 year: parseInt(dateParts[2], 10), 719 }; 720 } 721} 722 723var TBDSerialHelper = function() { 724 "use strict"; 725 this.lastGeneratedTBD = ''; 726 this.generatedTBDIndex = 0; 727}; 728 729TBDSerialHelper.prototype = { 730 lastGeneratedTBD: '', 731 generatedTBDIndex: 0, 732 isTBD: function (serial) { 733 return serial.toUpperCase().startsWith('TBD'); 734 }, 735 getTBD: function (date) { 736 if (!(date instanceof Date)) { 737 date = new Date(); 738 } 739 740 const serial = 'TBD-' + dateFns.format(date, 'YYYY-MM-DD_HH:mm:ss'); 741 742 if (serial !== this.lastGeneratedTBD) { 743 this.lastGeneratedTBD = serial; 744 this.generatedTBDIndex = 0; 745 746 return serial; 747 } 748 749 return serial + '-' + ++this.generatedTBDIndex; 750 } 751}
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.