1/* Shopping Cart (2017 version) */ 2 3Array.prototype.remove = function(from, to) { 4 var rest = this.slice((to || from) + 1 || this.length); 5 this.length = from < 0 ? this.length + from : from; 6 return this.push.apply(this, rest); 7}; 8 9if (!window.domesticCountry) { 10 window.domesticCountry = 'United States'; 11} 12 13var linkStyles = 'color: #fff !important; text-decoration:underline !important; font-family: Arial !important; font-size: 12px !important; font-weight: normal !important;'; 14var checkoutUrl = window.CheckoutUrl; 15if (checkoutUrl.indexOf('?') < 0) { 16 checkoutUrl += "?1"; 17} 18var editcartUrl = window.EditCartUrl; 19if (editcartUrl.indexOf('?') < 0) { 20 editcartUrl += "?1"; 21} 22 23//module to make cart requests synchronous 24var requestModule = (function() { 25 var instance; 26 var readyForNext = true; 27 28 var addItemToCart = function(postData) { 29 return new Promise(function (resolve) { 30 var intervalId = setInterval(function() { 31 if (readyForNext === true) { 32 var cartUuid = getCartUuidFromCookie(); 33 34 resolve(sendCartItem(cartUuid, postData)); 35 36 clearInterval(intervalId); 37 } 38 }, 100); 39 }); 40 } 41 42 var sendCartItem = function(cartUuid, postData) { 43 readyForNext = false; 44 var axios = getAxiosInstance(); 45 46 return axios.post("/api/cart/" + cartUuid + "/item", postData).then(function(response) { 47 if (response && response.data && response.data.success) { 48 if (response.data.uuid) { 49 setCartUuidCookie(response.data.uuid); 50 } 51 if (response.data.data) { 52 CreateCartArray(response.data.data); 53 ShowCart(true); 54 } 55 } else { 56 alert('There was an error adding this item to your cart.'); 57 } 58 }) 59 .catch(function (error) { 60 var errorMessage = error.response && error.response.data && error.response.data.error; 61 62 alert(errorMessage || 'There was an error adding this item to your cart.'); 63 }) 64 .finally(function() { 65 readyForNext = true; 66 }); 67 } 68 69 var createInstance = function() { 70 return { 71 addItemToCart: addItemToCart 72 } 73 } 74 75 return { 76 getInstance: function() { 77 return instance || (instance = createInstance()); 78 } 79 } 80}()); 81 82function Set_Cart_Cookie_Cookie(name, value, expires, path, domain, secure) { 83 var today = new Date(); 84 today.setTime(today.getTime()); 85 86 if (expires) { 87 expires = expires * 1000 * 60 * 60 * 24; 88 } 89 var expires_date = new Date(today.getTime() + (expires)); 90 91 if (domain == '') { 92 domain = document.domain.split('.'); 93 if (domain[domain.length - 1].toLowerCase() == 'au' || domain[domain.length - 1].toLowerCase() == 'uk' || domain[domain.length - 1].toLowerCase() == 'nz' || domain[domain.length - 1].toLowerCase() == 'za') { 94 domain = domain[domain.length - 3] + '.' + domain[domain.length - 2] + '.' + domain[domain.length - 1]; 95 } else { 96 domain = domain[domain.length - 2] + '.' + domain[domain.length - 1]; 97 } 98 } 99 100 while (value.substring(0, 4) == 'null') { 101 value = value.substring(4); 102 } 103 104 value = escape(value); 105 var count = 0; 106 var lastIndex = 0; 107 108 while (value.length > lastIndex) { 109 110 var segment = value.substring(lastIndex, lastIndex + 4000); 111 if (value.length > lastIndex + 4000) { 112 var lastPos = segment.lastIndexOf('%'); 113 if (lastPos > 0) { 114 segment = segment.substring(0, lastPos); 115 lastIndex = lastIndex + lastPos; 116 } 117 else { 118 lastIndex = lastIndex + 4000; 119 } 120 } 121 else { 122 lastIndex = lastIndex + 4000; 123 } 124 125 document.cookie = name + (count > 0 ? count : '') + "=" + segment + 126 ( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) + 127 ( ( path ) ? ";path=" + path : "" ) + 128 ( ( domain ) ? ";domain=" + domain : "" ) + 129 ( ( secure ) ? ";secure" : "" ); 130 131 count++; 132 } 133 134 if (count > 0) { 135 // Delete any leftover cookies if the amount to be stored is shrinking (they are removing items from the shopping cart) 136 document.cookie = name + (count > 0 ? count : '') + "=" + 137 ( ( path ) ? ";path=" + path : "") + 138 ( ( domain ) ? ";domain=" + domain : "" ) + 139 ";expires=Thu, 01-Jan-1970 00:00:01 GMT"; 140 } 141} 142 143function trimUuid(uuid) { 144 var trimmed = ''; 145 if(typeof uuid === 'string') { 146 trimmed = uuid.substr(0,36); 147 } 148 return trimmed; 149} 150 151function setCartUuidCookie(uuid) { 152 uuid = trimUuid(uuid); 153 var name = 'cart_id'; 154 var days = 31; 155 var expires = ""; 156 var date = new Date(); 157 date.setTime(date.getTime() + (days*24*60*60*1000)); 158 expires = "; expires=" + date.toUTCString(); 159 document.cookie = name + "=" + (uuid || "") + expires + "; path=/"; 160} 161function getCartUuidFromCookie() { 162 var name = 'cart_id'; 163 var nameEQ = name + "="; 164 var ca = document.cookie.split(';'); 165 for(var i=0;i < ca.length;i++) { 166 var c = ca[i]; 167 while (c.charAt(0)==' ') { 168 c = c.substring(1,c.length); 169 } 170 if (c.indexOf(nameEQ) == 0) { 171 var uuid = c.substring(nameEQ.length,c.length); 172 return trimUuid(uuid); 173 } 174 } 175 return null; 176} 177 178function getAxiosInstance() { 179 if (window.knobby && window.knobby.module_website_vue_use_one_lib_for_all_places) { 180 const config = {}; 181 if (this.cartJWT) { 182 config.headers = { 183 Authorization: 'Bearer ' + window.cartJWT, 184 }; 185 } 186 return axios.create(config); 187 } else { 188 let instance = axios.create(); 189 if (window.cartJWT) { 190 instance.defaults.headers.common['Authorization'] = 'Bearer ' + window.cartJWT; 191 } 192 return instance; 193 } 194} 195 196 197function addItemToCartData(data, classPackageData) { 198 var postData = { 199 'item_data': encodeURIComponent(data) 200 }; 201 202 // Pass Class packageData with the class to avoid async race conditions 203 if (classPackageData && Array.isArray(classPackageData) && classPackageData.length > 0){ 204 postData['class_package_data'] = classPackageData; 205 } 206 207 return requestModule.getInstance().addItemToCart(postData); 208} 209 210function Set_Cart_Cookie_Db(name, value, expires, path, domain, secure) { 211 var cartUuid = getCartUuidFromCookie(); // may be null, server will return one 212 213 var axios = getAxiosInstance(); 214 var data = {}; 215 data.uuid = cartUuid; 216 data.cart_contents = value; 217 218 axios.post("/api/cart/data", data).then(function(response) { 219 if(response && response.data && response.data.uuid) { 220 setCartUuidCookie(response.data.uuid); 221 } 222 }); 223 224 // TODO - handle the unhappy cases 225 // TODO - no, really do it. 226} 227 228// Cart 229function Set_Cart_Cookie(name, value, expires, path, domain, secure) { 230 if(name == 'cart') { 231 Set_Cart_Cookie_Db(name, value, expires, path, domain, secure); 232 CreateCartArray(value); 233 } else { 234 Set_Cart_Cookie_Cookie(name, value, expires, path, domain, secure); 235 } 236} 237 238function Get_Cart_Cookie_Cookie(check_name) { 239 var a_all_cookies = document.cookie.split(';'); 240 var a_temp_cookie = ''; 241 var cookie_name = ''; 242 var cookie_value = ''; 243 var b_cookie_found = false;
244 var retVal = null; 245 var count = 0; 246 247 do { 248 249 b_cookie_found = false; 250 251 for (i = 0; i < a_all_cookies.length; i++) { 252 a_temp_cookie = a_all_cookies[i].split('='); 253 254 cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, ''); 255 256 if (cookie_name == check_name + (count > 0 ? count : '')) { 257 b_cookie_found = true; 258 259 if (a_temp_cookie.length > 1) { 260 cookie_value = unescape(a_temp_cookie[1].replace(/^\s+|\s+$/g, '')); 261 } 262 263 retVal = (retVal === null ? '' : retVal) + cookie_value; 264 break; 265 } 266 a_temp_cookie = null; 267 cookie_name = ''; 268 } 269 270 count++; 271 272 } while (b_cookie_found == true); 273 274 return retVal; 275} 276 277// Cart 278function Get_Cart_Cookie(check_name) { 279 if(check_name == 'cart') { 280 return BuildCookieFromArray(); 281 } else { 282 return Get_Cart_Cookie_Cookie(check_name); 283 } 284} 285 286function Delete_Cart_Cookie(name, path, domain) { 287 var count = 0; 288 while (Get_Cart_Cookie(name + (count > 0 ? count : ''))) { 289 290 if (domain == '') { 291 domain = document.domain.split('.'); 292 if (domain[domain.length - 1].toLowerCase() == 'au' || domain[domain.length - 1].toLowerCase() == 'uk' || domain[domain.length - 1].toLowerCase() == 'nz' || domain[domain.length - 1].toLowerCase() == 'za') { 293 domain = domain[domain.length - 3] + '.' + domain[domain.length - 2] + '.' + domain[domain.length - 1]; 294 } else { 295 domain = domain[domain.length - 2] + '.' + domain[domain.length - 1]; 296 } 297 } 298 299 document.cookie = name + (count > 0 ? count : '') + "=" + 300 ( ( path ) ? ";path=" + path : "") + 301 ( ( domain ) ? ";domain=" + domain : "" ) + 302 ";expires=Thu, 01-Jan-1970 00:00:01 GMT"; 303 304 count++; 305 } 306 307} 308 309// Item Page? 310function showAddToWaitlistDialog(id, title, storeId, type) { 311 312 window.storeId = storeId; 313 314 if (type === "PSLR") { 315 316 var key = ''; 317 var titleAddOn = ' '; 318 for (var i = 0; i < window['numAttributes' + id]; i++) { 319 key += (key.length > 0 ? '-' : '') + $('#attribute_' + id + '_' + i).val(); 320 titleAddOn += (titleAddOn.length > 0 ? ' - ' : '') + window['attributeValues' + id][i][$('#attribute_' + id + '_' + i).val()]; 321 } 322 323 title += titleAddOn; 324 325 if (key == '') { 326 key = '0'; 327 } 328 329 window.currentProductId = id; 330 window.selected_wait_list_item_id = window['prices' + id][key]['pslrId']; 331 window.selected_wait_list_type_id = 1; 332 } else if (type === "EVENT") { 333 334 window.currentProductId = id; 335 window.selected_wait_list_item_id = id; 336 window.selected_wait_list_type_id = 2; 337 } else { 338 339 return; 340 } 341 342 $("#wait_list_added_span").html(""); 343 $("#overlayWaitListForm").replaceWith(''); 344 345 var markup = getWaitListDialogMarkup(title); 346 347 $(document.body).append(markup); 348 349 populateWaitListFormWithCookie(); 350 351 showWaitListSaveButton(); 352 353 $("#wait_list_contact_email").change(function() { 354 355 var email = $("#wait_list_contact_email").val(); 356 var collection = new WaitListCollection(window.storeId); 357 collection.getExistingContactInfoByEmail(window.selected_wait_list_item_id, email, function(data) { 358 359 populateWaitListFormWithData(data); 360 showWaitListSaveButton(email); 361 }); 362 }); 363 364 $("#wait_list_contact_first_name").change(function() { 365 366 showWaitListSaveButton(); 367 }); 368 369 $("#wait_list_contact_last_name").change(function() { 370 371 showWaitListSaveButton(); 372 }); 373 374 $("#overlayWaitListForm").dialog({width: 300, dialogClass: 'dlgWaitList'}); 375 376 // For some reason the close button is removed with responsive websites. We'll put it back here. 377 $(".dlgWaitList > .ui-dialog-titlebar > .ui-dialog-titlebar-close").html('<span class="ui-button-icon-primary ui-icon ui-icon-closethick"></span>'); 378} 379 380function getWaitListDialogMarkup(title) { 381 382 var appendString = ''; 383 384 appendString += '<div id="overlayWaitListForm" title="ADD TO WAIT LIST" class="wait-list-container">'; 385 386 appendString += '<div class="form-container">'; 387 appendString += '<div class="form-row">'; 388 appendString += '<div class="product-name">'; 389 appendString += title; 390 appendString += '</div>'; 391 appendString += '</div>'; 392 393 appendString += '<div class="form-row">'; 394 appendString += '<div class="form-title">'; 395 appendString += 'Email Address:'; 396 appendString += '</div><input class="form-input" placeholder="" id="wait_list_contact_email">'; 397 appendString += '</div>'; 398 399 appendString += '<div class="form-row">'; 400 appendString += '<div class="form-title">'; 401 appendString += 'First Name:'; 402 appendString += '</div><input class="form-input" placeholder="" id="wait_list_contact_first_name">'; 403 appendString += '</div>'; 404 405 appendString += '<div class="form-row">'; 406 appendString += '<div class="form-title">'; 407 appendString += 'Last Name:'; 408 appendString += '</div><input class="form-input" placeholder="" id="wait_list_contact_last_name">'; 409 appendString += '</div>'; 410 411 appendString += '<div class="form-row">'; 412 appendString += '<div class="form-title">'; 413 appendString += 'Phone:'; 414 appendString += '</div><input class="form-input" placeholder="" id="wait_list_contact_phone">'; 415 appendString += '</div>'; 416 417 appendString += '<div class="form-row">'; 418 appendString += '<div class="form-title">'; 419 appendString += 'Quantity:'; 420 appendString += '</div><input class="form-input" value="1" id="wait_list_quantity">'; 421 appendString += '</div>'; 422 423 appendString += '<button class="wait-list-btn" onClick="javascript:SaveToWaitList()" id="wait_list_save_button">Add to Wait List</button>' 424 appendString += '</div>'; 425 appendString += '</div>'; 426 return appendString; 427} 428 429function populateWaitListFormWithCookie() { 430 431 var waitlist_data = Get_Cart_Cookie('waitlist'); 432 if (waitlist_data !== null) { 433 434 var contact = JSON.parse(waitlist_data); 435 populateWaitListFormWithData(contact); 436 } 437} 438 439function populateWaitListFormWithData(contact) { 440 441 if (contact === null) { 442 443 $("#wait_list_contact_first_name").val(""); 444 $("#wait_list_contact_last_name").val(""); 445 $("#wait_list_contact_phone").val(""); 446 window.selected_wait_list_id = null; 447 window.selected_wait_list_contact_rel_id = null; 448 window.selected_pos_customer_id = null; 449 } 450 else { 451 if (contact.email !== null) { 452 453 $("#wait_list_contact_email").val(contact.email); 454 } 455 if (contact.first_name !== undefined && contact.first_name !== null) { 456 457 $("#wait_list_contact_first_name").val(contact.first_name); 458 } 459 if (contact.last_name !== undefined && contact.last_name !== null) { 460 461 $("#wait_list_contact_last_name").val(contact.last_name); 462 } 463 if (contact.phone !== undefined && contact.phone !== null) { 464 465 $("#wait_list_contact_phone").val(contact.phone); 466 } 467 if (contact.wait_list_id !== undefined && contact.wait_list_id !== null) { 468 469 window.selected_wait_list_id = contact.wait_list_id; 470 } 471 if (contact.wait_list_contact_rel_id !== undefined && contact.wait_list_contact_rel_id !== null) { 472 473 window.selected_wait_list_contact_rel_id = contact.wait_list_contact_rel_id; 474 } 475 if (contact.pos_customer_id !== undefined && contact.pos_customer_id !== null) { 476 477 window.selected_pos_customer_id = contact.pos_customer_id; 478 } 479 } 480} 481 482function showWaitListSaveButton(email) { 483 484 if (email === undefined) { 485 486 email = $("#wait_list_contact_email").val(); 487 } 488 489 var first_name = $("#wait_list_contact_first_name").val(); 490 var last_name = $("#wait_list_contact_last_name").val(); 491 492 if (isEmailValid(email) && first_name.length > 0 && last_name.length > 0) { 493 494 $("#wait_list_save_button").show(); 495 return true; 496 } 497 else { 498 499 $("#wait_list_save_button").hide(); 500 return false;
501 } 502} 503 504function isEmailValid(email) { 505 506 if (email !== undefined && email.length > 0) { 507 508 var reg = /^([A-Za-z0-9_\-\.\+])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/; 509 return (reg.test(email)); 510 } else { 511 512 return false; 513 } 514} 515 516function SaveToWaitList() { 517 518 var wait_list = new WaitList(); 519 var contact = new WaitListContact(); 520 contact.email = $("#wait_list_contact_email").val(); 521 contact.first_name = $("#wait_list_contact_first_name").val(); 522 contact.last_name = $("#wait_list_contact_last_name").val(); 523 contact.phone = $("#wait_list_contact_phone").val(); 524 contact.quantity = $("#wait_list_quantity").val(); 525 if (window.selected_pos_customer_id !== undefined) { 526 contact.pos_customer_id = window.selected_pos_customer_id; 527 } 528 if (window.selected_wait_list_contact_rel_id !== undefined) { 529 contact.wait_list_contact_rel_id = window.selected_wait_list_contact_rel_id; 530 } 531 if (window.selected_wait_list_id !== undefined) { 532 contact.wait_list_id = window.selected_wait_list_id; 533 } 534 wait_list.contacts.push(contact); 535 wait_list.store_id = window.storeId; 536 wait_list.item_id = window.selected_wait_list_item_id; 537 wait_list.item_type_id = window.selected_wait_list_type_id; 538 wait_list.save(function(response) { 539 540 if (response.contact !== undefined && response.contact !== null) { 541 542 Set_Cart_Cookie('waitlist', JSON.stringify(response.contact), '', '/', '', ''); 543 $("#wait_list_added_span_" + window.currentProductId).html(' ' + contact.quantity + ' added to wait list'); 544 } 545 }); 546 547 closeWaitListModal(); 548} 549 550// Class 551function closeWaitListModal() { 552 553 $("#overlayWaitListForm").dialog("close"); 554} 555 556// Class 557function SaveWaitListContact(contact) { 558 559 var wait_list = new WaitList(); 560 wait_list.contacts.push(contact); 561 wait_list.store_id = contact.store_id; 562 wait_list.item_id = contact.item_id; 563 wait_list.item_type_id = contact.item_type_id; 564 wait_list.save(function (response) { 565 566 if (response.contact !== undefined && response.contact !== null) { 567 568 Set_Cart_Cookie('waitlist', JSON.stringify(response.contact), '', '/', '', ''); 569 $("#wait_list_added_span_" + contact.item_id).html(' ' + contact.quantity + ' added to wait list'); 570 } 571 }); 572} 573 574// Cart 575function CreateCartArray(cart) { 576 tuples = cart.split(";;"); 577 window.cartArray = new Array(); 578 for (i = 0; i < tuples.length; i++) { 579 parts = tuples[i].split("##"); 580 window.cartArray[i] = parts; 581 } 582} 583 584// Cart - Makes cart visible and shows actual cart 585function ShowCart(forceExpand) { 586 var oldCart = window.cartVersion != 2017; 587 var cartDiv = $("#cartDiv"); 588 var cartDivMobile = $("#cartDivMobile"); 589 590 if (window.cartMode === undefined || window.cartMode == false) { 591 window.cartMode = 'normal'; 592 } 593 594 if (window.cartMode == 'hidden') { 595 cartDiv.hide(); 596 cartDivMobile.hide(); 597 } else { 598 if (oldCart) { 599 var cart = ''; 600 if (Get_Cart_Cookie('cart')) { 601 cart = Get_Cart_Cookie('cart'); 602 } 603 604 if (window.cartMode == 'wide') { 605 CreateCartArray(cart); 606 cartDiv.hide(); 607 cartDivMobile.hide(); 608 WideCart(); 609 } else if (window.cartMode == 'mobile') { 610 CreateCartArray(cart); 611 cartDiv.hide(); 612 cartDivMobile.hide(); 613 MobileCart(forceExpand); 614 } else { 615 if (cart.length > 0) { 616 CreateCartArray(cart); 617 var toShow = true; 618 if (GetCartArrayValueByKey('mode') == 'collapsed' && forceExpand != true) { 619 CollapseCart(); 620 } else { 621 toShow = ExpandCart(); 622 } 623 624 if (toShow !== false) { 625 cartDiv.fadeIn(); 626 cartDivMobile.fadeIn(); 627 } 628 629 return; 630 } else { 631 cartDiv.hide(); 632 cartDivMobile.hide(); 633 } 634 } 635 } else { 636 var cart = Get_Cart_Cookie('cart'); 637 if (cart && cart.length > 0) { 638 CreateCartArray(cart); 639 toShow = ExpandCart(); 640 if (toShow !== false) { 641 cartDiv.fadeIn(); 642 } 643 } else { 644 cartDiv.hide(); 645 cartDivMobile.hide(); 646 } 647 } 648 } 649} 650 651// Cart 652function BuildCookieFromArray() { 653 var newCart = ''; 654 for (var i = 0; i < window.cartArray.length; i++) { 655 if (i > 0) { 656 newCart += ';;'; 657 } 658 newCart += window.cartArray[i].join("##"); 659 } 660 return newCart; 661} 662 663function dataToCookieString(productId,productTitle,productPrice,productC
663ount,productWeight,productCountType,productSku,requiresDownloadEmailAddress,minQuantity,maxQuantity,notes 664 ,isTimed,holdingId,in_shipping,in_taxes,in_productType,pslrId,in_hasAttendees,isDiscountEligible,productImagePath,productImageStyle,class_attendees 665 ,deptId,categoryIdList,displayPrice,unitType,soldInIncrements,wishlistItemId, rto_items) { 666 667 //delimiter is ## so if this string ends with # we need to change it so I just add a space to the end of the string 668 669 if ( 670 isNaN(productCount) 671 || isNaN(minQuantity) 672 || isNaN(minQuantity) 673 ) { 674 return ''; 675 } 676 productCount = parseFloat(productCount); 677 minQuantity = parseFloat(minQuantity); 678 maxQuantity = parseFloat(maxQuantity); 679 680 if (productTitle.length > 0 && productTitle.charAt(productTitle.length - 1) == '#') { 681 productTitle = productTitle + " "; 682 } 683 if (productCount < minQuantity) { 684 var humanQuantity = minQuantity; 685 if (!!window.measurementUnit && window.measurementUnit == 'Yard') { 686 687 if (humanQuantity === '0.25') { 688 humanQuantity = '1/4'; 689 } else if (humanQuantity === '0.5') { 690 humanQuantity = '1/2'; 691 } else if (humanQuantity === '0.75') { 692 humanQuantity = '3/4'; 693 } 694 695 } 696 697 alert('Please select a quantity greater than ' + humanQuantity); 698 return ''; 699 } 700 if (productCount > maxQuantity) { 701 alert('Please select a quantity less than ' + maxQuantity); 702 return ''; 703 } 704 705 706 707 708 var cookieData = ';;product##' + productId + 709 '##' + productTitle + 710 '##' + productPrice + 711 '##' + productCount + 712 '##' + productWeight + 713 '##' + productCountType + 714 '##' + productSku + 715 '##' + requiresDownloadEmailAddress + 716 '##' + minQuantity + 717 '##' + maxQuantity + 718 '##' + notes + 719 '##' + isTimed + 720 '##' + holdingId + 721 '##' + in_shipping + 722 '##' + in_taxes + 723 '##' + in_productType + 724 '##' + pslrId + 725 '##' + in_hasAttendees + 726 '##' + isDiscountEligible + 727 '##' + productImagePath + 728 '##' + productImageStyle + 729 '##' + class_attendees + 730 '##' + deptId + 731 '##' + categoryIdList + 732 '##' + displayPrice + 733 '##' + unitType + 734 '##' + soldInIncrements + 735 '##' + wishlistItemId; 736 737 if (rto_items !== undefined) { 738 cookieData += '##' + rto_items; 739 } 740 return cookieData; 741 742} 743 744// Cart - This is what renders the expanded version of the cart in the upper corner 745/** @return {boolean} */ 746function ExpandCart() { 747 var oldCart = window.cartVersion != 2017; 748 var cartDiv = $("#cartDiv"); 749 var cartDivMobile = $("#cartDivMobile"); 750 751 var products = ''; 752 var subtotal = 0; 753 var subtotal_to_discount = 0; 754 var giftCardSubtotal = 0; 755 var totalItems = 0; 756 var numProducts = 0; 757 var numGiftCards = 0; 758 759 if (oldCart) { 760 UpdateCouponsInCartArrayAndCookie(); 761 } 762 763 // Item totals 764 for (var i = window.cartArray.length - 1; i >= 0; i--) { 765 var row = window.cartArray[i]; 766 if (row[0] == 'product') { 767 if (row[1].indexOf('PITEM') > -1) { 768 continue; 769 } 770 totalItems += Number(row[4]); 771 var displayPrice = 0; 772 if (row[25]) { 773 displayPrice = row[25]; 774 } else { 775 displayPrice = row[3]; 776 } 777 778 var amount = Math.round(fractionalMultiplication(parseFloat(displayPrice), row[4]) * 100) / 100; 779 780 if (row.length > 16 && row[16] == 'GC') { 781 giftCardSubtotal += amount; 782 numGiftCards++; 783 } else { 784 numProducts++; 785 subtotal += amount; 786 787 // 19 - discount_eligible 788 if (row[19] === "true") { 789 subtotal_to_discount += amount; 790 } 791 } 792 793 if (oldCart) { 794 var replaceTitle = window.cartArray[i][2].replace(/\+/g, ' '); 795 try { 796 replaceTitle = JSON.parse(replaceTitle); 797 } catch (e) {} 798 799 products += 800 '<div style="font-size: 12px !important; line-height: 20px; border-bottom: 1px solid #999; padding-bottom:5px; margin-bottom: 10px;">' + 801 '<div style="line-height: 14px; font-size: 11px !important; margin-bottom:4px;">' + 802 replaceTitle + 803 '</div>' + 804 '<div><b>' + formatCurrency(displayPrice) + '</b></div>' + 805 '<span style="font-size: 10px; color: #999;">quantity: ' + row[4] + '</span><br><br>' + 806 '</div>'; 807 } 808 } 809 } 810 811 // Don't show cart div if there are no items 812 if (numProducts == 0 && giftCardSubtotal == 0) { 813 return false;
814 } 815 816 // Calculate discounts 817 // This version of the cart should not require calculating the coupon as it only intends to show quantity of items 818 // however, I've kept it as the mobile version still shows a total amount 819 for (var i = window.cartArray.length - 1; i >= 0; i--) { 820 if (window.cartArray[i][0] == 'coupon' || window.cartArray[i][0] == 'couponV2') { 821 if (oldCart) { 822 var couponInfo = GetCouponInfo(window.cartArray[i]); 823 var discount = Math.round(CalculateDiscount(subtotal_to_discount, i) * 100) / 100; 824 if (discount > 0) { 825 subtotal -= discount; 826 products += 827 '<div style="font-size: 12px !important; line-height: 20px; border-bottom: 1px solid #999; padding-bottom:5px; margin-bottom: 10px;">' + 828 '<div style="line-height: 14px; font-size: 11px !important; margin-bottom:4px;">' + 829 couponInfo.title.replace(/\+/g, ' ') + 830 '</div>' + 831 '<div><b>- ' + formatCurrency(discount) + '</b></div>' + 832 '</div>'; 833 } 834 835 } 836 } 837 } 838 839 // Update subtotal 840 subtotal += giftCardSubtotal; 841 subtotal = Math.round(subtotal * 100) / 100; 842 843 if (oldCart) { 844 // Gift Card Payments 845 var giftCardPayments = 0; 846 for (var i = window.cartArray.length - 1; i >= 0; i--) { 847 if (window.cartArray[i][0] == 'giftcard') { 848 giftCardPayments += Math.round(window.cartArray[i][3] * 100) / 100; 849 } 850 } 851 852 var giftCardRows = ''; 853 if (giftCardPayments > 0) { 854 if (subtotal < giftCardPayments) { 855 giftCardPayments = subtotal; 856 } 857 giftCardRows = '<span style="color: #ccc; font-size: 14px;"><b>Gift Cards = ' + formatCurrency(giftCardPayments) + '</b></span><br>'; 858 subtotal -= giftCardPayments; 859 } 860 861 } 862 863 // Mobile bottom div 864 cartDivMobile.html( 865 '<div style="padding:10px;" onclick="location=\'' + editcartUrl + '\'">' + 866 '<table width="100%"><tr>' + 867 '<td style="text-align: left; cursor: pointer; color: #fff;">' + 868 '<img style="width:23px; height:18px; vertical-align:middle; margin-bottom: 4px;" src="https://images.rainpos.com/view-cart.png"> Cart - ' + (totalItems) + ' items' + 869 '</td>' + 870 '<td style="text-align: right; cursor: pointer; color: #fff;">' + formatCurrency(subtotal) + '</td>' + 871 '</tr></table></div>' 872 ); 873 874 if (!oldCart || window.ABCart == 'B') { 875 // Full page upper corner bullet 876 cartDiv.attr('style', 'display:none; top: 10px; right: 10px; padding: 0px; width: 150px; background: none;'); 877 cartDiv.html( 878 '<div class="btnViewCart" onclick="location=\'' + editcartUrl + '\'" >' + 879 '<img style="width:23px; height:18px; vertical-align:middle; margin-bottom: 4px;" src="https://images.rainpos.com/view-cart.png">' + 880 ' ' + (totalItems) + ' Item' + (totalItems != 1 ? 's' : '') + 881 '</div>' 882 ); 883 } else { 884 cartDiv.html( 885 '<div style="display:table; height:28px; text-align:right; width:100%;">' + 886 ' <span style="display:table-cell; width:20px;"></span>' + 887 ' <span style="vertical-align:middle; text-align:center; display:table-cell; color: #ccc; font-family: Arial; font-size: 12px !important;">' + 888 ' <a href="' + editcartUrl + '" style="' + linkStyles + '">View Cart</a>' + 889 ' </span>' + 890 ' <span style="vertical-align:middle; width:20px; display:table-cell; color: #ccc; font-family: Arial; font-size: 12px !important;">' + 891 ' <a href="javascript:CollapseCart();"><img border=0 width=16 height=11 src="https://images.rainpos.com/btn-collapse.png"></a>' + 892 ' </span>' + 893 '</div>' + 894 895 '<div style="width: 100%; top: 30px; right: 0px; border-top: 1px solid #888; margin-bottom:10px;"></div>' + 896 '<div class="btnViewCart" onclick="ProceedToCheckout(\'no\');" style="font-size:14px; font-family: Arial !important;">Proceed to Checkout »</div>' + 897 '<div style="text-align:left; margin-top:10px; margin-bottom:10px; padding: 10px; color: #fff; height: 200px; overflow:auto; background: url(https://images.rainpos.com/cart-bg-2a.png) repeat;">' + 898 products + 899 '</div>' + 900 giftCardRows + 901 '<div style="color: #ddd; font-size: 14px !important; padding:4px;">Subtotal = ' + formatCurrency(subtotal) + '</div>' + 902 '<div style="line-height:20px;">' + 903 '<a href="' + editcartUrl + '&enterCoupon=true" style="' + linkStyles + '">Enter Coupon</a><br>' + 904 (window.paymentProcessor === undefined || window.paymentProcessor == false || window.paymentProcessor == 'paypal' ? '' : '<a href="' + editcartUrl + '&enterGiftcard=true" style="' + linkStyles + '">Enter Gift Card</a><br>') + 905 '<a href="' + editcartUrl + '" style="' + linkStyles + '">View Cart</a>' + 906 '</div>' + 907 '<div class="btnViewCart" onclick="ProceedToCheckout(\'no\');" style="font-size:14px; font-family: Arial !important; margin-bottom: 10px; margin-top: 5px;">Proceed to Checkout »</div>' + 908 MakeCartForm() + 909 ''); 910 } 911 912 return true; 913} 914 915/** @return {string} */ 916function ProductAttributeKeyGet(in_productId, in_attributeIndex) { 917 // Get the key 918 var key = ''; 919 for (var i = 0; i < window['numAttributes' + in_productId]; i++) { 920 key += (key.length > 0 ? '-' : '') + $('#attribute_' + in_productId + '_' + i).val(); 921 } 922 923 if (key == '') { 924 key = '0'; 925 } 926 927 return key; 928} 929 930// Used by the product page - probably does not belong in this file 931function handleProductOptionChanged(in_productId, in_attributeIndex) { 932 var newPrice = ''; 933 var isSale; 934 var integer = $("#integer" + in_productId); 935 var fraction = $("#fraction" + in_productId); 936 var currentIntegerVal = parseInt(integer.val()); 937 var currentFractionVal = parseFloat(fraction.val()); 938 var minFraction = window.siteMinimumFraction; 939 940 // Get the key 941 var key = ProductAttributeKeyGet(in_productId, in_attributeIndex); 942 var pslrId = parseInt(window['prices' + in_productId][key]['pslrId']); 943 944 // Show propper Custom fields and hide others 945 $('#product-details-pricing-table .custom-fields').hide(); 946 $('#product-details-pricing-table .custom-fields-' + pslrId).show(); 947 948 // Set font colors to black for attributes that are available for the just-selected attribute, and gray for those that aren't available 949 950 var reserve = 0; 951 var outOfStock = false;
952 953 if (window['prices' + in_productId][key]) { 954 var temp = window['prices' + in_productId][key]['salePrice']; 955 // Is the selected product option on sale? 956 isSale = (parseFloat(window['prices' + in_productId][key]['salePrice']) > 0.0 ? true : false); 957 958 // Set price label 959 $('#spanPriceLabel' + in_productId).html((isSale == true ? 'SALE:' : 'Price:')); 960 961 // Set price value 962 if (isSale == true) { 963 newPrice = '<strike>' + formatCurrency(window['prices' + in_productId][key]['price']) + '</strike> <b><span style="color:#ff0000;">' + formatCurrency(window['prices' + in_productId][key]['salePrice']) + '</span></b>'; 964 } else { 965 newPrice = formatCurrency(window['prices' + in_productId][key]['finalDisplayPrice']); 966 } 967 $('#spanPrice' + in_productId).html(newPrice); 968 969 // Set quantity dropdowns 970 971 // Integer 972 var maxInteger = Math.floor(parseFloat(window['prices' + in_productId][key]['quantity'])); 973 if (currentIntegerVal > maxInteger) { 974 currentIntegerVal = maxInteger; 975 } 976 var startInteger = (window['isFabric' + in_productId] == true ? 0 : 1); 977 var soldInIncrements = window['soldInIncrements' + in_productId]; 978 integer.html(""); 979 for (var i = startInteger; i <= maxInteger; i++) { 980 if ((i === 0) && ((minFraction === 1) || (minFraction === '1'))) { 981 continue; 982 } 983 984 985 if ((i % soldInIncrements) > 0) { 986 continue; 987 } 988 integer.append("<option value=\'" + i + "\' " + (currentIntegerVal == i ? 'selected' : '') + ">" + i + "</option>"); 989 } 990 $('#maxInteger' + in_productId).val(maxInteger); 991 992 if(maxInteger <= 0 && (typeof maxFraction === 'undefined' && !window['isFabric' + in_productId])) { 993 outOfStock = true; 994 } 995 996 // Fraction 997 if (window['isFabric' + in_productId] == true) { 998 var increment = (window.measurementUnit == 'Meter' ? 10 : 25); 999 var maxFraction = Math.floor(parseFloat(window['prices' + in_productId][key]['quantity']) * 100) % 100; 1000 maxFraction = (maxFraction - (maxFraction % increment)) / 100; 1001 if (currentIntegerVal == 0 && currentFractionVal == 0) { 1002 currentFractionVal = maxFraction; 1003 } else if (currentIntegerVal == maxInteger && currentFractionVal > maxFraction) { 1004 currentFractionVal = maxFraction; 1005 } 1006 $('#maxFraction' + in_productId).val(maxFraction); 1007 1008 fraction.html(""); 1009 var startVal = 0; 1010 if (currentIntegerVal == 0) { 1011 if (minFraction && (minFraction > 0) && (minFraction < 1)) { 1012 startVal = Math.floor(window.siteMinimumFraction * 100); 1013 } else { 1014 startVal = (window.measurementUnit === 'Meter') ? 10 : 25; 1015 } 1016 1017 } 1018 for (var i = startVal; i < 100; i += increment) { 1019 var decimal = (i / 100); 1020 if (maxInteger == currentIntegerVal && maxFraction < decimal) { 1021 break; 1022 } 1023 var appendStr = ''; 1024 if (window.measurementUnit == 'Meter' && currentIntegerVal == 0 && decimal == .3 && window.siteMinimumFraction == 'fat quarter') { 1025 appendStr += "<option value=\'0.25\' " + (currentFractionVal == 0.25 ? 'selected' : '') + ">Fat Quarter</option>"; 1026 } 1027 appendStr += "<option value=\'" + decimal + "\' " + (currentFractionVal == decimal ? 'selected' : '') + ">"; 1028 if (window.measurementUnit == 'Meter') { 1029 appendStr += decimal; 1030 } else { 1031 appendStr += (decimal == 0.25 ? (currentIntegerVal == 0 && window.siteMinimumFraction == 'fat quarter' ? 'Fat Quarter' : '1/4') : (decimal == 0.5 ? '1/2' : (decimal == 0.75 ? '3/4' : decimal))); 1032 } 1033 appendStr += "</option>"; 1034 fraction.append(appendStr); 1035 } 1036 } 1037
1038 // WishList 1039 if (typeof wishlistApp != 'undefined' && wishlistApp) { 1040 1041 var qtyInteger = $("#integer" + in_productId); 1042 var qtyFraction = $("#fraction" + in_productId); 1043 var qtyIntegerVal = parseInt(qtyInteger.val()); 1044 var qtyFractionVal = parseFloat(qtyFraction.val()); 1045 1046 // Handle NaN 1047 if (!qtyIntegerVal) { 1048 qtyIntegerVal = 0; 1049 if ((minFraction === 1) || (minFraction === '1')) { 1050 qtyIntegerVal = 1; 1051 } 1052 } 1053 if (!qtyFractionVal) { 1054 qtyFractionVal = 0; 1055 } 1056 1057 wishlistApp.$root.$emit('update_pslr_qty', {pslr_id: pslrId, qty: (qtyIntegerVal + qtyFractionVal)}); 1058 } 1059 } else { 1060 outOfStock = true 1061 } 1062 1063 if (window['isFabric' + in_productId] === true && window['prices' + in_productId][key]['quantity'] < minimumQuantity) { 1064 outOfStock = true; 1065 } 1066 1067 var newPriceNumber = Number(newPrice.replace(/[^0-9\.-]+/g,"")); 1068 var freeProductNotAllowed = 1069 newPriceNumber <= 0 && 1070 (typeof window['freeProductsAllowed'] !== 'undefined' && window['freeProductsAllowed'] === false); 1071 1072 if (freeProductNotAllowed) { 1073 $('[id^=add-to-cart-btn-' + in_productId + ']').attr('disabled','disabled'); 1074 $('[id^=add-to-cart-btn-' + in_productId + ']').html('Product Unavailable'); 1075 } else { 1076 $('[id^=add-to-cart-btn-' + in_productId + ']').removeAttr("disabled"); 1077 $('[id^=add-to-cart-btn-' + in_productId + ']').html('Add to Cart'); 1078 } 1079 1080 if (outOfStock || (reserve > 0 && maxInteger == 0 && (window['isFabric' + in_productId] != true || maxFraction == 0))) { 1081 $('[id^=integer' + in_productId + ']').hide(); 1082 $('[id^=fraction' + in_productId + ']').hide(); 1083 $('[id^=add-to-cart-btn-' + in_productId + ']').hide(); 1084 $('[id^=reserve' + in_productId + ']').html('<span style="color:#f00;">Out of Stock</span>').show(); 1085 } else { 1086 $('[id^=integer' + in_productId + ']').show(); 1087 $('[id^=fraction' + in_productId + ']').show(); 1088 $('[id^=add-to-cart-btn-' + in_productId + ']').show(); 1089 $('[id^=reserve' + in_productId + ']').hide(); 1090 } 1091 1092 var conditionalSelect = $('#conditional-select'); 1093 if (!conditionalSelect) { 1094 return; 1095 } 1096 1097 var conditionOptions = window['prices' + in_productId][key]['conditional_option'] 1098 1099 if (conditionOptions) { 1100 $.each(conditionOptions, function (i, item) { 1101 conditionalSelect.append($('<option>', { 1102 value: item.value, 1103 text : item.label, 1104 selected: i === 0. 1105 })); 1106 }); 1107 conditionalSelect.attr('data-key', key); 1108 conditionalSelect.trigger('change'); 1109 } else { 1110 conditionalSelect.parent().parent().css('display','none'); 1111 } 1112} 1113 1114// Cart 1115function formatCurrency(num) { 1116 num = num.toString().replace(/\$|\,/g, ''); 1117 if (isNaN(num)) { 1118 num = "0"; 1119 } 1120 sign = (num == (num = Math.abs(num))); 1121 num = Math.floor(num * 100 + 0.50000000001); 1122 cents = num % 100; 1123 num = Math.floor(num / 100).toString(); 1124 if (cents < 10) { 1125 cents = "0" + cents; 1126 } 1127 for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++) { 1128 num = num.substring(0, num.length - (4 * i + 3)) + ',' + 1129 num.substring(num.length - (4 * i + 3)); 1130 } 1131 return (((sign) ? '' : '-') + window.displayCurrencySymbol + num + '.' + cents + ' ' + window.displayCurrency); 1132} 1133 1134// Rental Cart (Outdoor) 1135function addRentalToCart(rentalDataId, price) { 1136 if (isRentalInCart(rentalDataId)) { 1137 updateRentalPrice(rentalDataId, price); 1138 } else { 1139 AddProductToCart('', 'sale', rentalDataId, 'Rental', price, 0, 'integer', '', 'no', 1, 1, 0, '', '', 0, '', 'RENTAL', '', 'false', '', ''); 1140 } 1141} 1142 1143function isRentalInCart(rentalDataId) { 1144 var cart = Get_Cart_Cookie('cart'); 1145 if (cart && cart.length > 0 && window.cartArray) { 1146 for (var i = 0; i < window.cartArray.length; i++) { 1147 if (window.cartArray[i][1] == 'RENTAL' + rentalDataId) { 1148 return true; 1149 } 1150 } 1151 } 1152 return false;
1153} 1154 1155function updateRentalPrice(rentalDataId, price) { 1156 var cart = Get_Cart_Cookie('cart'); 1157 if (cart && cart.length > 0 && window.cartArray) { 1158 for (var i = 0; i < window.cartArray.length; i++) { 1159 if (window.cartArray[i][1] == 'RENTAL' + rentalDataId) { 1160 window.cartArray[i][3] = price; 1161 updateCart(); 1162 return; 1163 } 1164 } 1165 } 1166} 1167 1168function updateCart() { 1169 Set_Cart_Cookie('cart', BuildCookieFromArray(), '', '/', '', ''); 1170} 1171 1172function addWishlistProductToCart(item, qty, maxQty, unitType) { 1173 1174 var productId = item.product_id; 1175 var pslrId = item.item_id; 1176 1177 var prices = item.prices; 1178 var price = prices['price']; 1179 if(prices['sale_price'] > 0 && prices['sale_price'] < price) { 1180 price = prices['sale_price']; 1181 } 1182 1183 var notes = ''; 1184 console.log('add '+ qty +'product ' + productId + ' pslr ' + pslrId); 1185 1186 var min = 0; 1187 if(item.qty_on_hand > 0 || item.unlimitedWebInventory === 1) { 1188 min = 1; 1189 } 1190 var discountEligibility = item.discount_eligible; 1191 1192 // (in_businessEmail, in_paymentAction, productId, productTitle, productPrice, productWeight, productCountType, productSku, requiresDownloadEmailAddress, minQuantity, maxQuantity, isTimed, in_notes, in_shipping, in_taxes, inlineAddToCartBtn, in_productType, in_hasAttendees, isDiscountEligible, productImagePath, productImageStyle, requireClassAttendees, 1193 // pslrId, packageData, holdingId, deptId, categoryIdList, displayPrice, unitType, soldInIncrements,qty, wishlist_id 1194 AddProductToCart( 1195 '', 1196 'sale', 1197 productId, 1198 item.title, 1199 price, 1200 item.weight, 1201 item.productCountType, 1202 item.sku, 1203 'no', 1204 min, 1205 maxQty, 1206 0, 1207 notes, 1208 '', 1209 item.bitmap_tax, 1210 '', 1211 'PSLR', 1212 '', 1213 discountEligibility, 1214 item.thumbnail, 1215 '', 1216 false, 1217 pslrId, 1218 null, 1219 null, 1220 item.department_id, 1221 JSON.parse(item.category_ids), 1222 null, 1223 unitType, 1224 null, 1225 qty, 1226 item.wishlist_item_id 1227 ); 1228} 1229 1230 1231// RTO Cart (Music) 1232function addRtoToCartWithCondition(token, pslrId, conditionId, schoolDistrictId, schoolId, studentName, selectedMaintenance, selectedProtection, conditionPiiId) { 1233 conditionPiiId = (conditionPiiId === undefined) ? null : conditionPiiId; 1234 var request = { 1235 pslr_id: pslrId, 1236 condition_id: conditionId, 1237 school_district_id: schoolDistrictId, 1238 school_id: schoolId, 1239 student_name: studentName, 1240 selected_maintenance: selectedMaintenance, 1241 selected_protection: selectedProtection, 1242 condition_pii_id: conditionPiiId 1243 }; 1244 1245 $.ajax({ 1246 url: '/api/rto/online/contract', 1247 type: 'POST', 1248 dataType: 'json', 1249 contentType: 'application/json', 1250 data: JSON.stringify(request), 1251 headers: { 1252 Authorization: 'Bearer ' + token 1253 }, 1254 success: function(result) { 1255 if (result.result != 'success') { 1256 alert('There was an error adding your rental to the cart.'); 1257 } else { 1258 var notes = ''; 1259 if (result.taxable_amount) { 1260 notes = JSON.stringify({taxable_amount:result.taxable_amount}); 1261 } 1262 1263 var rto_items = null; 1264 if (result.rto_items !== undefined) { 1265 rto_items = JSON.stringify({ 1266 rto_principle_payment: result.rto_items.rto_principle_payment, 1267 rto_down_payment: result.rto_items.rto_down_payment, 1268 rto_product_tax_bitmap: result.rto_items.rto_product_tax_bitmap, 1269 rto_maintenance_payment: result.rto_items.rto_maintenance_payment, 1270 rto_maintenance_tax_bitmap: result.rto_items.rto_maintenance_tax_bitmap, 1271 rto_insurance_payment: result.rto_items.rto_insurance_payment, 1272 rto_insurance_tax_bitmap: result.rto_items.rto_insurance_tax_bitmap, 1273 rto_security_deposit: result.rto_items.rto_security_deposit, 1274 rto_initial_payments: result.rto_items.rto_initial_payments, 1275 rto_interest_rate: result.rto_items.rto_interest_rate, 1276 rto_interest_tax_bitmap: result.rto_items.rto_interest_tax_bitmap, 1277 }); 1278 } 1279 AddProductToCart('', 'sale', result.rto_id, result.title + ' - Rental', result.due, result.weight, 'integer', '', 'no', 1, 1, 0, notes, '', 0, '', 'RTO', '', 'false', '', '', false, pslrId, null, conditionId, null, null, null, null, null, null, null, rto_items); 1280 } 1281 } 1282 }); 1283} 1284 1285function createAndAddOsrToCart(token, rentalId, variationId, conditionId, maintenance, protection, student, customerInfo, image, addons) { 1286 var config = { 1287 headers: { 1288 Authorization: 'Bearer ' + token, 1289 } 1290 }; 1291 1292 var data = { 1293 rentalId: rentalId, 1294 variationId: variationId, 1295 conditionId: conditionId, 1296 maintenance: maintenance, 1297 protection: protection, 1298 student: student, 1299 customerInfo: customerInfo, 1300 addons: addons, 1301 }; 1302 1303 return axios.post('/api/online-school-rentals/cart-contract', data, config) 1304 .then(function (response) { 1305 var data = response.data; 1306 1307 if (!data || !data.rto_id) { 1308 return Promise.reject(new Error('Error on contract creation')); 1309 } 1310 1311 var rtoItems = data.rto_items ? { 1312 rto_principle_payment: data.rto_items.rto_principle_payment, 1313 rto_down_payment: data.rto_items.rto_down_payment, 1314 rto_product_tax_bitmap: data.rto_items.rto_product_tax_bitmap, 1315 rto_maintenance_payment: data.rto_items.rto_maintenance_payment, 1316 rto_maintenance_tax_bitmap: data.rto_items.rto_maintenance_tax_bitmap, 1317 rto_insurance_payment: data.rto_items.rto_insurance_payment, 1318 rto_insurance_tax_bitmap: data.rto_items.rto_insurance_tax_bitmap, 1319 rto_security_deposit: data.rto_items.rto_security_deposit, 1320 rto_initial_payments: data.rto_items.rto_initial_payments, 1321 rto_interest_rate: data.rto_items.rto_interest_rate, 1322 rto_interest_tax_bitmap: data.rto_items.rto_interest_tax_bitmap, 1323 } : null; 1324 1325 return AddOsrToCart( 1326 data.rto_id, 1327 data.title, 1328 data.due, 1329 data.weight, 1330 {taxable_amount: data.taxable_amount}, 1331 image, 1332 data.pslr_id, 1333 conditionId, 1334 rtoItems 1335 ); 1336 }); 1337} 1338 1339function AddOsrToCart(productId, productTitle, productPrice, productWeight, notes, productImagePath, pslrId, holdingId, rtoItems) { 1340 // Get custom fields & notes 1341 productId = 'RTO' + productId; 1342 notes = notes ? JSON.stringify(notes) : ''; 1343 rtoItems = rtoItems ? JSON.stringify(rtoItems) : null; 1344 1345 var cookieData = dataToCookieString(
1346 productId, productTitle, productPrice, 1, productWeight, 'integer', '', 1347 'no', 1, 1, notes, 0, holdingId, '', 1348 0, 'OSR', pslrId || '', '', 'false', productImagePath, '', 1349 '', null, JSON.stringify(null), productPrice, 'each', 1, null, rtoItems 1350 ); 1351 1352 if (cookieData === '') { 1353 return Promise.reject(new Error('Wrong cart item data')); 1354 } 1355 1356 var promise = addItemToCartData(cookieData); 1357 1358 if (window.facebookPixelId) { 1359 fbq('track', 'AddToCart', { 1360 currency: window.currency, 1361 value: productPrice, 1362 content_name: productTitle, 1363 content_ids: [productId], 1364 content_type: 'product', 1365 contents: [{ 1366 'id': productId, 1367 'quantity': 1 1368 }] 1369 }); 1370 } 1371 1372 addGAEvent(productId, productTitle, productPrice, 1); 1373 1374 return promise; 1375} 1376 1377// Cart 1378 1379 1380function yardLoop(maxFractionVal, siteMinimumFraction, fraction, currFractionVal, intVal, maxIntVal){ 1381 //we could probably be clever and do something cool like the meter loop...but not enough values to make it worth it 1382 fraction.html(""); 1383 if(currFractionVal > maxFractionVal && intVal >= maxIntVal){ 1384 currFractionVal = maxFractionVal; 1385 } 1386 if (intVal === 0) { 1387 if (window.siteMinimumFraction === 'fat quarter') { 1388 fraction.append("<option " + (currFractionVal < 0.5 ? "selected" : "") + " value=\'0.25\'>Fat Quarter</option>"); 1389 } 1390 if (window.siteMinimumFraction === '0.25' || window.siteMinimumFraction === '') { 1391 fraction.append("<option " + (currFractionVal < 0.5 ? "selected" : "") + " value=\'0.25\'>1/4</option>"); 1392 } 1393 } else { 1394 fraction.append("<option value=\'0\'>0</option>"); 1395 if (intVal < maxIntVal || maxFractionVal >= 0.25) { 1396 fraction.append("<option " + (currFractionVal === 0.25 ? "selected" : "") + " value=\'0.25\'>1/4</option>"); 1397 } 1398 } 1399 if (intVal < maxIntVal || maxFractionVal >= 0.5) { 1400 fraction.append("<option " + (currFractionVal === 0.5 ? "selected" : "") + " value=\'0.5\'>1/2</option>"); 1401 } 1402 if (intVal < maxIntVal || maxFractionVal >= 0.75) { 1403 fraction.append("<option " + (currFractionVal === 0.75 ? "selected" : "") + " value=\'0.75\'>3/4</option>"); 1404 } 1405} 1406 1407function meterLoop(startingFraction, currentFraction, fraction, maxFractionValue, intVal, maxIntVal){ 1408 1409 var i = parseFloat(startingFraction); 1410 if(intVal<maxIntVal){ 1411 maxFractionValue = .9 1412 } 1413 if(currentFraction < i ){ 1414 currentFraction = i; 1415 } 1416 if(currentFraction > maxFractionValue && intVal >= maxIntVal){ 1417 currentFraction = maxFractionValue; 1418 } 1419 if (startingFraction === .25 ){ 1420 fraction.append("<option " + (currentFraction === .25 ? "selected" : "") + " value=\'0.25\'>Fat Quarter</option>"); 1421 i = parseFloat(.3); 1422 } 1423 for(i; i <= maxFractionValue ; i += .1 ){ 1424 var count = i.toFixed(1); 1425 fraction.append("<option " + (currentFraction == count ? "selected" : "") + " value=\'"+ count +"\'>"+ count.replace(/^0+/,"")+"</option>"); 1426 if (i === .2 && intVal === 0 ){ 1427 fraction.append("<option " + (currentFraction === .25 ? "selected" : "") + " value=\'0.25\'>Fat Quarter</option>"); 1428 } 1429 } 1430 return fraction; 1431} 1432 1433// TODO - This function is a little better, but still messy, and needs additional refactoring and automated tests 1434function checkFabricMinimum(id, maxQuantity) 1435{ 1436 var minFraction = window.siteMinimumFraction; 1437 var minFractionVal = (minFraction === 'fat quarter') ? 0.25 : minFraction; 1438 1439 var intVal = parseInt($("#integer" + id).val()); 1440 var fraction = $("#fraction" + id); 1441 var currFractionVal = parseFloat(fraction.val()); 1442 1443 var maxIntVal; 1444 var maxFractionVal; 1445 1446 if (typeof maxQuantity === 'undefined') { 1447 maxIntVal = parseInt($("#maxInteger" + id).val()); 1448 maxFractionVal = parseFloat($("#maxFraction" + id).val()); 1449 } else { 1450 maxQuantity = parseFloat(maxQuantity); 1451 maxIntVal = Math.floor(maxQuantity); 1452 maxFractionVal = Math.floor((maxQuantity * 100) % 100) / 100; 1453 } 1454 1455 // WishList 1456 1457 if ((typeof wishlistApp !== 'undefined') && wishlistApp) { 1458 var key = ProductAttributeKeyGet(id, 0); 1459 var pslrId = parseInt(window['prices' + id][key]['pslrId']); 1460 1461 wishlistApp.$root.$emit('update_pslr_qty', {pslr_id: pslrId, qty: (intVal + currFractionVal)}); 1462 } 1463 1464 // Fractional handling 1465 1466 if (window.measurementUnit === 'Meter') { 1467 fraction.html(""); 1468 if (intVal === 0) { 1469 meterLoop(minFractionVal, currFractionVal, fraction, maxFractionVal, intVal, maxIntVal); 1470 } else { 1471 meterLoop('0', currFractionVal, fraction, maxFractionVal, intVal, maxIntVal); 1472 } 1473 1474 } else { 1475 yardLoop(maxFractionVal, siteMinimumFraction, fraction, currFractionVal, intVal, maxIntVal); 1476 } 1477} 1478 1479function getPslrIdFromUI(productId) 1480{ 1481 // Find which PSLR is selected 1482 var key = ''; 1483 for (var i = 0; i < window['numAttributes' + productId]; i++) { 1484 key += (key.length > 0 ? '-' : '') + $('#attribute_' + productId + '_' + i).val(); 1485 } 1486 if (key == '') { 1487 key = '0'; 1488 } 1489 pslrId = window['prices' + productId][key]['pslrId']; 1490 return pslrId; 1491} 1492 1493function getQuantityFromUI(productId) 1494{ 1495 quantity = 1; 1496 if (typeof inlineAddToCartBtn !== 'undefined') { 1497 quantity = parseInt(document.getElementById('inlineInteger' + productId).value) + parseFloat(document.getElementById('inlineFraction' + productId).value); 1498 } else { 1499 var element = document.getElementById('integer' + productId); 1500 var element2 = document.getElementById('fraction' + productId); 1501 quantity = 0; 1502 if (element) { 1503 quantity += parseInt(element.value); 1504 } 1505 if (element2) { 1506 quantity += parseFloat(element2.value); 1507 } 1508 } 1509 return quantity; 1510} 1511 1512function getNotesFromUI(productId) { 1513 var notes = ''; 1514 var noteObjects = $(".class" + productId); 1515 noteObjects.each(function(i) { 1516 if (notes === 'return') { 1517 return; 1518 } 1519 var noteName = $(this).attr('name');
1520 var noteValue = ''; 1521 1522 if ($(this).is(':checkbox')) { 1523 noteValue = ($(this).is(":checked") ? 'checked' : 'not checked'); 1524 } 1525 else { 1526 noteValue = $.trim($(this).val()); 1527 } 1528 1529 if ($(this).attr('required') == true && noteValue == '') { 1530 alert(noteName + ' is a required field.'); 1531 notes = 'return'; 1532 return; 1533 } 1534 1535 if (notes == '') { 1536 notes = {}; 1537 } 1538 notes[noteName] = noteValue; 1539 }); 1540 1541 if (notes == 'return') { 1542 return; 1543 } 1544 return notes; 1545} 1546 1547function createItem(productId, productTitle, productPrice, productWeight, productCountType, productSku, requiresDownloadEmailAddress, minQuantity, maxQuantity, isTimed, in_notes, in_shipping, in_taxes, inlineAddToCartBtn, in_productType, in_hasAttendees, isDiscountEligible, productImagePath, productImageStyle, requireClassAttendees, pslrId, packageData, holdingId, deptId, categoryIdList, displayPrice, unitType, soldInIncrements, quantity, wishlistItemId, rto_items, conditionId, conditions, addonId) { 1548 if (in_productType === 'PSLR') { 1549 if (!pslrId) { 1550 pslrId = getPslrIdFromUI(productId); 1551 } 1552 1553 // Get Quantity 1554 if (!quantity) { 1555 quantity = getQuantityFromUI(productId); 1556 } 1557 1558 var notes = in_notes; 1559 if (!notes) { 1560 notes = getNotesFromUI(productId); 1561 } 1562 1563 var pslr = { 1564 type: in_productType, 1565 pslr_id: pslrId, 1566 product_id: productId, 1567 quantity: quantity, 1568 notes: notes, 1569 wishlistItemId: wishlistItemId || 0, 1570 title: productTitle, 1571 }; 1572 1573 if (conditionId) { 1574 pslr['condition'] = conditionId; 1575 } else { 1576 var condition = getConditional(productId); 1577 if (condition) { 1578 pslr['condition'] = condition.id; 1579 } 1580 } 1581 1582 if (conditions) { 1583 pslr['conditions'] = conditions; 1584 } 1585 1586 if (window.knobby && window.knobby['module_comment_sold']) { 1587 pslr.sku = productSku; 1588 pslr.price = productPrice; 1589 } 1590 if (addonId) { 1591 pslr['addon_id'] = addonId; 1592 } 1593 1594 return pslr; 1595 } 1596 return null; 1597} 1598 1599function getConditional(productId) { 1600 if (!document.getElementById('conditional-select')) { 1601 return null; 1602 } 1603 1604 if (document.getElementById('conditional-select') === null) { 1605 return null; 1606 } 1607 1608 var key = ProductAttributeKeyGet(productId, 0); 1609 1610 var value = document.getElementById('conditional-select').value; 1611 1612 var conditional = window['prices' + productId][key]['conditional']; 1613 1614 if (!conditional) { 1615 return null; 1616 } 1617 1618 return conditional.find(function (v) { 1619 return parseInt(v.item_condition_id) === parseInt(value); 1620 }); 1621} 1622 1623function getConditionQuantity(productId, conditionId, key = null) { 1624 key = key === null ? ProductAttributeKeyGet(productId, 0) : key; 1625 1626 var conditionQuantity = window['prices' + productId][key]['conditional_quantity'].find(function (v) { 1627 return parseInt(v.condition_id) === parseInt(conditionId); 1628 }); 1629 1630 return conditionQuantity ? parseInt(conditionQuantity.quantity) : 0; 1631} 1632 1633function addClassToCart(classId, eventId, requireAttendees, packageData, class_id_str) { 1634 if (requireAttendees) { 1635 var result = verifyClassAttendees('CLASS' + eventId); 1636 if (!result) { 1637 return; 1638 } 1639 } 1640 1641 var selectedComponents = []; 1642 var packageId = null; 1643 if (packageData && packageData.available && packageData.option === 'classAndPackage') { 1644 packageId = packageData.packageId; 1645 if (packageData.components) { 1646 packageData.components.forEach(function(c) { 1647 selectedComponents.push(c.selectedItem); 1648 }); 1649 } 1650 } 1651 1652 var item = { 1653 type: 'CLASS', 1654 event_id: eventId, 1655 class_id: classId, 1656 package_id: packageId, 1657 components: selectedComponents, 1658 class_attendees: getClassAttendees('CLASS' + eventId), 1659 } 1660 addItemToCart(item); 1661} 1662 1663function addItemToCart(item, productId) { 1664 if (!isValidConditionQuantityInCart(item, productId)) { 1665 if (!item.hasOwnProperty('conditions')) { 1666 decreaseActualConditionQuantity(productId, item.condition); 1667 } 1668 1669 alert('There was an error adding this item to your cart.'); 1670 return Promise.resolve(); 1671 } 1672 1673 var promise = requestModule.getInstance().addItemToCart({ 1674 item: item, 1675 }); 1676 1677 // Google Analytics 1678 if (item.type === 'PSLR') { 1679 if (item.quantity > 0) { 1680 addGAEvent(item.product_id, item.title, item.price, item.quantity); 1681 } 1682 } 1683 1684 if (window.knobby && window.knobby['module_comment_sold']) { 1685 if (typeof item.type !== 'undefined' && item.type.toLowerCase() === 'pslr') { 1686 //we want to fire event only for pslr items 1687 var data = { 1688 product: { 1689 sku: item.pslr_id || item.sku, 1690 price: parseFloat(item.price), 1691 currency: window.currency || 'USD', 1692 quantity: item.quantity, 1693 } 1694 } 1695 try { 1696 videeoCommand('addToCart', data); 1697 } catch (e) { 1698 console.warn(e); 1699 } 1700 } 1701 } 1702 1703 return promise; 1704} 1705 1706/** 1707 * Adds a product to the cart (pre-2017 version). 1708 * When adding parameters, make sure to also add them for GetAttendees() 1709 */ 1710function AddProductToCart(in_businessEmail, in_paymentAction, productId, productTitle, productPrice, productWeight, productC
1710ountType, productSku, requiresDownloadEmailAddress, minQuantity, maxQuantity, isTimed, in_notes, in_shipping, in_taxes, inlineAddToCartBtn, in_productType, in_hasAttendees, isDiscountEligible, productImagePath, productImageStyle, requireClassAttendees, pslrId, packageData, holdingId, deptId, categoryIdList, displayPrice, unitType, soldInIncrements, quantity, wishlistItemId, rto_items, conditionId, conditions) { 1711 if (window.location.search.indexOf('ie') == -1) { // IE still can't use the new product page. 1712 if (requireClassAttendees) { 1713 var result = verifyClassAttendees(productId); 1714 if (!result) { 1715 return; 1716 } 1717 } 1718 1719 var item = createItem(productId, productTitle, productPrice, productWeight, productCountType, productSku, requiresDownloadEmailAddress, minQuantity, maxQuantity, isTimed, in_notes, in_shipping, in_taxes, inlineAddToCartBtn, in_productType, in_hasAttendees, isDiscountEligible, productImagePath, productImageStyle, requireClassAttendees, pslrId, packageData, holdingId, deptId, categoryIdList, displayPrice, unitType, soldInIncrements, quantity, wishlistItemId, rto_items, conditionId, conditions); 1720 if (item) { 1721 addItemToCart(item, productId); 1722 return; 1723 } 1724 } 1725 1726 unitType = unitType || 'each'; 1727 soldInIncrements = soldInIncrements || 1; 1728 1729 if (in_businessEmail !== null) { 1730 window.businessEmail = in_businessEmail; 1731 } 1732 1733 if(typeof deptId === 'undefined') { 1734 deptId = null; 1735 } 1736 if(typeof categoryIdList === 'undefined') { 1737 categoryIdList = []; 1738 } 1739 1740 // Class Package Items 1741 var classPackage = false; 1742 var classPackageData = []; 1743 if (productId.indexOf('CLASS') > -1) { 1744 // Overloading here - it's just too much work to add new fields and we want to redo all this anyway 1745 var classUid = new Date().getTime(); 1746 productSku = classUid; 1747 if (packageData && packageData.available) { 1748 classPackage = true; 1749 if (packageData.option == 'classAndPackage') { 1750 in_productType = 'PACKAGE'; 1751 pslrId = packageData.packageId; 1752 productWeight = packageData.class_price; 1753 if (packageData.components) { 1754 packageData.components.forEach(function(c) { 1755 var s = c.selectedItem; 1756 var packageItemData = AddProductToCart(null, null, 'PITEM' + packageData.packageId, s.title, s.price, 0, null, '', 'no', 1, 1, 0, null, 0, 0, false, 'PSLR', '', false, '', '', '', s.pslrId, null, classUid); 1757 if (packageItemData) { 1758 classPackageData.push(packageItemData); 1759 } 1760 }); 1761 } 1762 } 1763 } 1764 } 1765 1766 categoryIdList = JSON.stringify(categoryIdList); 1767 1768 var class_attendees = ""; 1769 if (requireClassAttendees) { 1770 1771 class_attendees = getClassAttendees(productId); 1772 if (class_attendees.no_value != undefined) { 1773 1774 alert("Attendee Name Required"); 1775 $("#" + class_attendees.input_id).focus(); 1776 return; 1777 } 1778 } 1779 1780 // Set defaults 1781 if (!pslrId) { 1782 pslrId = ''; 1783 } 1784 1785 if (!requiresDownloadEmailAddress || requiresDownloadEmailAddress == 'undefined') { 1786 requiresDownloadEmailAddress = "no"; 1787 } 1788 1789 if (!minQuantity || minQuantity == 'undefined') { 1790 if (productCountType == 'fraction') { 1791 minQuantity = 0.25; 1792 } else { 1793 minQuantity = 1; 1794 } 1795 } 1796 1797 if (!maxQuantity || maxQuantity == 'undefined') { 1798 maxQuantity = 100; 1799 } 1800 1801 if (!isTimed || isTimed == 'undefined') { 1802 isTimed = 0; 1803 } 1804 1805 if ((!in_shipping || in_shipping == 'undefined') && in_shipping !== 0) { 1806 in_shipping = ''; 1807 } 1808 1809 if ((!in_taxes || in_taxes == 'undefined') && in_taxes !== 0) { 1810 in_taxes = ''; 1811 } 1812 1813 // Get current cart 1814 var cart = ''; 1815 if (Get_Cart_Cookie('cart')) { 1816 cart = Get_Cart_Cookie('cart'); 1817 } 1818
1819 var productCount = null; 1820 if (quantity > 0) { 1821 productCount = quantity; 1822 } else if (productCountType !== null) { 1823 if (in_productType == 'RENTAL' || in_productType == 'RTO') { 1824 productCount = 1; 1825 } else if (inlineAddToCartBtn) { 1826 productCount = parseInt(document.getElementById('inlineInteger' + productId).value) + parseFloat(document.getElementById('inlineFraction' + productId).value); 1827 } else { 1828 var element = document.getElementById('integer' + productId); 1829 var element2 = document.getElementById('fraction' + productId); 1830 productCount = 0; 1831 if (element) { 1832 productCount += parseInt(element.value); 1833 } 1834 if (element2) { 1835 productCount += parseFloat(element2.value); 1836 } 1837 } 1838 } else { 1839 productCount = 1; 1840 } 1841 1842 // Get custom fields & notes 1843 var notes = ''; 1844 if (in_notes != 'undefined' && in_notes != '') { 1845 notes = in_notes; 1846 } else { 1847 var noteObjects = $(".class" + productId); 1848 noteObjects.each(function(i) { 1849 if (notes == 'return') { 1850 return; 1851 } 1852 var noteName = $(this).attr('name'); 1853 var noteValue = ''; 1854 1855 if ($(this).is(':checkbox')) { 1856 noteValue = ($(this).is(":checked") ? 'checked' : 'not checked'); 1857 } 1858 else { 1859 noteValue = $.trim($(this).val()); 1860 } 1861 if ($(this).attr('requiredField') == 'true' && noteValue == '') { 1862 noteName = noteName.replace(/_/g, ' '); 1863 alert(noteName + ' is a required field.'); 1864 notes = 'return'; 1865 return; 1866 } 1867 1868 1869 if (notes == '') { 1870 notes = {}; 1871 } 1872 notes[noteName] = noteValue; 1873 }); 1874 1875 if (notes == 'return') { 1876 return; 1877 } 1878 if (notes != '') { 1879 notes = JSON.stringify(notes); 1880 } 1881 } 1882 1883 // Product ID is modified here, so make sure it goes after anything that relies on the Product ID. 1884 // Handle PSLR information 1885 if (in_productType == 'PSLR') { 1886 // Find selected PSLR 1887 var key = ''; 1888 var titleAddOn = ''; 1889 for (var i = 0; i < window['numAttributes' + productId]; i++) { 1890 key += (key.length > 0 ? '-' : '') + $('#attribute_' + productId + '_' + i).val(); 1891 titleAddOn += (titleAddOn.length > 0 ? ' - ' : '') + window['attributeValues' + productId][i][$('#attribute_' + productId + '_' + i).val()]; 1892 } 1893 if (key == '') { 1894 key = '0'; 1895 } 1896 1897 // Fix data 1898 productTitle += (titleAddOn.length > 0 ? ': ' : '') + titleAddOn; 1899 if (window['prices' + productId]) { 1900 productWeight = window['prices' + productId][key]['weight']; 1901 productPrice = window['prices' + productId][key]['finalPrice']; 1902 displayPrice = window['prices' + productId][key]['finalDisplayPrice']; 1903 productSku = window['prices' + productId][key]['sku']; 1904 maxQuantity = window['prices' + productId][key]['quantity']; 1905 pslrId = window['prices' + productId][key]['pslrId']; 1906 } 1907 1908 // Get the option image if no image specified 1909 if (!productImagePath && $('#productImage' + productId).length) { 1910 var optionImage = $('#productImage' + productId).attr('src'); 1911 if (optionImage && optionImage.length > 0) { 1912 productImagePath = optionImage; 1913 } 1914 } 1915 } 1916 // Gift Cards 1917 else if (in_productType == 'GC') { 1918 productPrice = $("#GCValue").val(); 1919 displayPrice = productPrice; 1920 productId += Math.floor(Math.random() * 1000); 1921 } else if (in_productType == 'RENTAL') { 1922 productId = 'RENTAL' + productId; 1923 } else if (in_productType == 'RTO') { 1924 productId = 'RTO' + productId; 1925 } else if (in_productType == 'SUBSCRIPTION') { 1926 productId = 'SUBSCRIPTION' + productId; 1927 } 1928 1929 if (!displayPrice) { 1930 displayPrice = productPrice; 1931 } 1932 1933 // create path for timed inventory ajax calls 1934 if (isTimed == 1) { 1935 var cartUrl = '/module/product.htm?timed=1'; 1936 if (isAdminUrl(location.host)) { 1937 cartUrl = location.pathname.substring(0, location.pathname.indexOf('/', 2)) + cartUrl; 1938 } 1939 } 1940 if (!holdingId) { 1941 holdingId = ''; // timed inventory variable 1942 } 1943 1944 var cookieData = dataToCookieString(productId,productTitle,productPrice,productC
1944ount,productWeight,productCountType,productSku,requiresDownloadEmailAddress,minQuantity,maxQuantity,notes 1945 ,isTimed,holdingId,in_shipping,in_taxes,in_productType,pslrId,in_hasAttendees,isDiscountEligible,productImagePath,productImageStyle,class_attendees 1946 ,deptId,categoryIdList,displayPrice,unitType,soldInIncrements,wishlistItemId, rto_items); 1947 1948 // For packageData, we add it as part of the class 1949 if (productId.indexOf('PITEM') > -1) { 1950 return encodeURIComponent(cookieData); 1951 } 1952 1953 if (cookieData === '') { 1954 return ; 1955 } 1956 addItemToCartData(cookieData, classPackageData); 1957 1958 var contentId = productSku ? productSku : productId; 1959 if (window.facebookPixelId) { 1960 fbq('track', 'AddToCart', { 1961 currency: window.currency, 1962 value: productPrice, 1963 content_name: productTitle, 1964 content_ids: [contentId], 1965 content_type: 'product', 1966 contents: [{ 1967 'id': contentId, 1968 'quantity': productCount 1969 }] 1970 }); 1971 } 1972 1973 addGAEvent(contentId, productTitle, productPrice, productCount); 1974} 1975 1976function verifyClassAttendees(productId) { 1977 var classAttendees = getClassAttendees(productId); 1978 if (classAttendees.no_value !== undefined) { 1979 // TODO: No alerts 1980 alert("Attendee Name Required"); 1981 $("#" + classAttendees.input_id).focus(); 1982 return false; 1983 } 1984 return true; 1985} 1986 1987function getClassAttendees(class_id_str) { 1988 1989 var return_value = ""; 1990 var classToken = "CLASS"; 1991 var pos = class_id_str.indexOf(classToken); 1992 if (pos > -1) { 1993 1994 var event_id = class_id_str.substr(pos + classToken.length); 1995 return_value = getAttendeesJson(event_id); 1996 } 1997 return return_value; 1998} 1999 2000function getAttendeesJson(in_event_id) { 2001 2002 var jsn = ""; 2003 var attendees = $(".attendee"); 2004 if (attendees) { 2005 2006 var names = []; 2007 2008 for (var i = 0; i < attendees.length; i++) { 2009 2010 var ele = attendees[i]; 2011 var event_id = ele.attributes["eventid"].value; 2012 2013 if (in_event_id == event_id && ele.value.length > 0) { 2014 2015 names.push(ele.value); 2016 } 2017 } 2018 if (names.length === 0) { 2019 2020 jsn = {no_value: 1, input_id: "event_" + in_event_id + "_attendee_1", numberOfAttendees: parseInt($('#qty').val())}; 2021 } else { 2022 2023 jsn = JSON.stringify(names); 2024 } 2025 } 2026 return jsn; 2027} 2028 2029function CalculateDiscount(subtotal, i) { 2030 var discount = 0; 2031 if (window.cartArray[i][0] == 'coupon' || window.cartArray[i][0] == 'couponV2') { 2032 var couponInfo = GetCouponInfo(window.cartArray[i]); 2033 if (couponInfo.couponType == 'dollar_off') { 2034 // Calculate discount 2035 if (subtotal > couponInfo.minDollarAmount) { 2036 discount = couponInfo.dollarOffAmount; 2037 } 2038 discount = Math.round(discount * 100) / 100; 2039 } 2040 else if (couponInfo.couponType == 'percent_off') { 2041 if (subtotal > couponInfo.minDollarAmount) { 2042 discount = Number(subtotal) * (Number(couponInfo.percentOff) / 100); 2043 discount = Math.round(discount * 100) / 100; 2044 } 2045 2046 } 2047 if(couponInfo.maxDiscount && couponInfo.maxDiscount < discount) { 2048 discount = couponInfo.maxDiscount; 2049 } 2050 } 2051 2052 if (discount + 0.01 > subtotal) { 2053 discount = subtotal - 0.01; 2054 } 2055 2056 return discount; 2057} 2058 2059function GetCouponInfo(row) { 2060 if (!row) { 2061 return null; 2062 } 2063 2064 var couponInfo = {}; 2065 couponInfo['version'] = row[0]; 2066 couponInfo['couponType'] = row[1]; 2067 couponInfo['title'] = row[2]; 2068 if (couponInfo.version == 'couponV2') { 2069 couponInfo['number'] = row[3]; 2070 couponInfo['couponId'] = row[4]; 2071 if (couponInfo.couponType == 'dollar_off') { 2072 couponInfo['minDollarAmount'] = row[5]; 2073 couponInfo['dollarOffAmount'] = row[6]; 2074 } else if (couponInfo.couponType == 'percent_off') { 2075 couponInfo['percentOff'] = row[5]; 2076 } 2077 } else { 2078 if (couponInfo.couponType == 'dollar_off') { 2079 couponInfo['minDollarAmount'] = row[3]; 2080 couponInfo['dollarOffAmount'] = row[4]; 2081 couponInfo['maxDiscount'] = row[5]; 2082 } 2083 2084 if (couponInfo.couponType == 'percent_off') { 2085 couponInfo['percentOff'] = row[3]; 2086 couponInfo['minDollarAmount'] = row[4]; 2087 couponInfo['maxDiscount'] = row[5]; 2088 } 2089 2090 if (row.length >= 7) { 2091 couponInfo['number'] = row[6]; // coupon_id 2092 } 2093 if (row.length >= 8) { 2094 couponInfo['start_date'] = row[7]; 2095 } 2096 if (row.length >= 9) { 2097 couponInfo['end_date'] = row[8]; 2098 } 2099 } 2100 return couponInfo; 2101} 2102 2103function isAdminUrl(url) { 2104 if (typeof adminUrls != 'undefined') { 2105 var length = adminUrls.length; 2106 for (var i = 0; i < length; i++) { 2107 if (adminUrls[i] == url || 'www.' + adminUrls[i] == url || 'my-' + adminUrls[i] == url || 'www.my-'
2107+ adminUrls[i] == url) { 2108 return true; 2109 } 2110 } 2111 } 2112 return false; 2113} 2114 2115function onChangeConditionalSelect(productId) { 2116 changeConditional(productId); 2117 window.vueEventHub.$eventHub.$emit('product-style-variant-changed'); 2118} 2119 2120function changeConditional(productId) { 2121 var condition = getConditional(productId); 2122 2123 if (!condition) { 2124 return; 2125 } 2126 2127 if (window.knobby && window.knobby['module_improved_waitlist']) { 2128 var conditionSelect = $('#conditional-select'); 2129 conditionSelect.attr('selected-id', condition.id); 2130 conditionSelect.attr('selected-name', condition.name); 2131 } 2132 2133 var price = condition.hasOwnProperty('display_price') ? condition.display_price.price : 0; 2134 2135 var priceHtml = formatCurrency(price); 2136 2137 var sale = condition.hasOwnProperty('display_price') ? condition.display_price.sale_price : 0; 2138 2139 if (+sale > 0) { 2140 priceHtml = '<strike>' + formatCurrency(price) + '</strike> <b><span style="color: #ff0000">' + formatCurrency(sale) + '</span></b>' 2141 } 2142 2143 document.getElementById('spanPrice' + productId).innerHTML = priceHtml; 2144 changQuantity(productId, condition.id); 2145} 2146 2147function changQuantity(productId, conditionId) { 2148 var isUnlimited = +$('#maxInteger' + productId).val() === 1000; 2149 2150 var quantity = isUnlimited === true ? 1000 : getConditionQuantity(productId, conditionId); 2151 2152 var quantitySelect = $('#integer' + productId); 2153 quantitySelect.find('option').remove() 2154 2155 var reserve = $('#reserve' + productId); 2156 var addBtn = $('#add-to-cart-btn-' + productId); 2157 var addToWaitlistBtn = $('#waitlist-wrapper'); 2158 2159 if (quantity === 0) { 2160 reserve.css('display', 'block'); 2161 quantitySelect.css('display', 'none') 2162 addBtn.css('display', 'none'); 2163 addToWaitlistBtn.css('display', 'inline-block'); 2164 2165 return; 2166 } 2167 reserve.css('display', 'none'); 2168 quantitySelect.css('display', 'block'); 2169 addToWaitlistBtn.css('display', 'none'); 2170 addBtn.css('display', 'inline-block'); 2171 2172 for(var i = 0; i < quantity; i++) { 2173 quantitySelect.append($('<option>', { 2174 value: i + 1, 2175 text : i + 1, 2176 })); 2177 } 2178} 2179function findCartItemsByProductId(productId) { 2180 return window.cartArray.filter(function (item) { 2181 if (item[0] !== 'product'){ 2182 return false; 2183 } 2184 2185 return parseInt(item[1].replace('PSLR', '')) === parseInt(productId); 2186 }); 2187} 2188function isValidConditionQuantityInCart(item, currentProductId) { 2189 if (!window.cartArray.length) { 2190 return true; 2191 } 2192 2193 var cart = findCartItemsByProductId(currentProductId); 2194 2195 if (!cart.length) { 2196 return true; 2197 } 2198 2199 var isValidConditionQuantity = function (condition, inCartQuantity) { 2200 var quantity = getConditionQuantity(currentProductId, condition); 2201 2202 return quantity >= inCartQuantity; 2203 }; 2204 2205 var CONDITION_INDEX = 30; 2206 var QUANTITY_INDEX = 4; 2207 2208 for (var i = 0; i < cart.length; i++) { 2209 var cartItem = cart[i]; 2210 2211 var condition = +cartItem[CONDITION_INDEX]; 2212 var quantity = +cartItem[QUANTITY_INDEX]; 2213 2214 if (item.conditions) { 2215 for (var j = 0; j < item.conditions; j++) { 2216 if (!isValidConditionQuantity(item.conditions[j].condition, quantity) && +item.conditions[j].condition === condition) { 2217 return false; 2218 } 2219 } 2220 2221 return true; 2222 } 2223 2224 if (condition !== +item.condition) { 2225 continue; 2226 } 2227 2228 if (!isValidConditionQuantity(condition, quantity)) { 2229 return false; 2230 } 2231 } 2232 2233 return true; 2234} 2235 2236function getInCartQuantity(productId, conditionId, defaultQuantity = 1) { 2237 var cart = findCartItemsByProductId(productId); 2238 2239 if (!cart) { 2240 return defaultQuantity; 2241 } 2242 2243 var CONDITION_INDEX = 30; 2244 var QUANTITY_INDEX = 4; 2245 2246 for (var i = 0; i < cart.length; i++) { 2247 var cartItem = cart[i]; 2248 if (+cartItem[CONDITION_INDEX] === +conditionId) { 2249 return +cartItem[QUANTITY_INDEX]; 2250 } 2251 } 2252 2253 return defaultQuantity; 2254} 2255 2256function decreaseActualConditionQuantity(productId, conditionId, key = null) { 2257 key = key === null ? ProductAttributeKeyGet(productId, 0) : key; 2258 2259 var conditionQuantity = window['prices' + productId][key]['conditional_quantity'].find(function (v) { 2260 return parseInt(v.condition_id) === parseInt(conditionId); 2261 }); 2262 2263 conditionQuantity.quantity = conditionQuantity.quantity - getInCartQuantity(productId, conditionId); 2264} 2265 2266function addGAEvent(productId, productTitle, productPrice, productC
2266ount) { 2267 if (window.knobby && window.knobby['module_flag_google_analytics_v4']) { 2268 if (window.googleAnalyticsId) { 2269 gtag('event', 'add_to_cart', { 2270 currency: window.currency || 'USD', 2271 value: parseFloat(productPrice), 2272 items: [{ 2273 item_id: productId, 2274 item_name: productTitle, 2275 quantity: productCount, 2276 price: productPrice, 2277 }] 2278 }); 2279 } 2280 } else { 2281 if (window.googleAnalyticsId) { 2282 gtag('event', 'add_to_cart', { 2283 "items": [{ 2284 id: productId, 2285 name: productTitle, 2286 quantity: productCount, 2287 price: productPrice, 2288 currency: window.currency, 2289 }] 2290 }); 2291 } 2292 } 2293}
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.