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 584function isCartWidgetHideWhenEmptyEnabled() { 585 return !!(window.knobby && window.knobby.module_website_cart_widget_hide_when_empty); 586} 587 588function cartTotalItems() { 589 var totalItems = 0; 590 for (var i = 0; i < window.cartArray.length; i++) { 591 var row = window.cartArray[i]; 592 if (row[0] == 'product' && row[1].indexOf('PITEM') == -1) { 593 totalItems += Number(row[4]); 594 } 595 } 596 return totalItems; 597} 598 599// Cart - Makes cart visible and shows actual cart 600function ShowCart(forceExpand) { 601 var oldCart = window.cartVersion != 2017; 602 var cartDiv = $("#cartDiv"); 603 var cartDivMobile = $("#cartDivMobile"); 604 605 if (window.cartMode === undefined || window.cartMode == false) { 606 window.cartMode = 'normal'; 607 } 608 609 if (window.cartMode == 'hidden') { 610 cartDiv.hide(); 611 cartDivMobile.hide(); 612 } else { 613 if (oldCart) { 614 var cart = ''; 615 if (Get_Cart_Cookie('cart')) { 616 cart = Get_Cart_Cookie('cart'); 617 } 618 619 if (window.cartMode == 'wide') { 620 CreateCartArray(cart); 621 cartDiv.hide(); 622 cartDivMobile.hide(); 623 WideCart(); 624 } else if (window.cartMode == 'mobile') { 625 CreateCartArray(cart); 626 cartDiv.hide(); 627 cartDivMobile.hide(); 628 MobileCart(forceExpand); 629 } else { 630 CreateCartArray(cart); 631 var hasItems = isCartWidgetHideWhenEmptyEnabled() ? cartTotalItems() > 0 : cart.length > 0; 632 if (hasItems) { 633 var toShow = true; 634 if (GetCartArrayValueByKey('mode') == 'collapsed' && forceExpand != true) { 635 CollapseCart(); 636 } else { 637 toShow = ExpandCart(); 638 } 639 640 if (toShow !== false) { 641 cartDiv.fadeIn(); 642 cartDivMobile.fadeIn(); 643 } 644 645 return; 646 } else { 647 cartDiv.hide(); 648 cartDivMobile.hide(); 649 } 650 } 651 } else { 652 var cart = Get_Cart_Cookie('cart'); 653 if (cart && cart.length > 0) { 654 CreateCartArray(cart); 655 toShow = ExpandCart(); 656 if (toShow !== false) { 657 cartDiv.fadeIn(); 658 } 659 } else { 660 cartDiv.hide(); 661 cartDivMobile.hide(); 662 } 663 } 664 } 665} 666 667// Cart 668function BuildCookieFromArray() { 669 var newCart = ''; 670 for (var i = 0; i < window.cartArray.length; i++) { 671 if (i > 0) { 672 newCart += ';;'; 673 } 674 newCart += window.cartArray[i].join("##"); 675 } 676 return newCart; 677} 678 679function dataToCookieString(productId,productTitle,productPrice,productC
679ount,productWeight,productCountType,productSku,requiresDownloadEmailAddress,minQuantity,maxQuantity,notes 680 ,isTimed,holdingId,in_shipping,in_taxes,in_productType,pslrId,in_hasAttendees,isDiscountEligible,productImagePath,productImageStyle,class_attendees 681 ,deptId,categoryIdList,displayPrice,unitType,soldInIncrements,wishlistItemId, rto_items) { 682 683 //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 684 685 if ( 686 isNaN(productCount) 687 || isNaN(minQuantity) 688 || isNaN(minQuantity) 689 ) { 690 return ''; 691 } 692 productCount = parseFloat(productCount); 693 minQuantity = parseFloat(minQuantity); 694 maxQuantity = parseFloat(maxQuantity); 695 696 if (productTitle.length > 0 && productTitle.charAt(productTitle.length - 1) == '#') { 697 productTitle = productTitle + " "; 698 } 699 if (productCount < minQuantity) { 700 var humanQuantity = minQuantity; 701 if (!!window.measurementUnit && window.measurementUnit == 'Yard') { 702 703 if (humanQuantity === '0.25') { 704 humanQuantity = '1/4'; 705 } else if (humanQuantity === '0.5') { 706 humanQuantity = '1/2'; 707 } else if (humanQuantity === '0.75') { 708 humanQuantity = '3/4'; 709 } 710 711 } 712 713 alert('Please select a quantity greater than ' + humanQuantity); 714 return ''; 715 } 716 if (productCount > maxQuantity) { 717 alert('Please select a quantity less than ' + maxQuantity); 718 return ''; 719 } 720 721 722 723 724 var cookieData = ';;product##' + productId + 725 '##' + productTitle + 726 '##' + productPrice + 727 '##' + productCount + 728 '##' + productWeight + 729 '##' + productCountType + 730 '##' + productSku + 731 '##' + requiresDownloadEmailAddress + 732 '##' + minQuantity + 733 '##' + maxQuantity + 734 '##' + notes + 735 '##' + isTimed + 736 '##' + holdingId + 737 '##' + in_shipping + 738 '##' + in_taxes + 739 '##' + in_productType + 740 '##' + pslrId + 741 '##' + in_hasAttendees + 742 '##' + isDiscountEligible + 743 '##' + productImagePath + 744 '##' + productImageStyle + 745 '##' + class_attendees + 746 '##' + deptId + 747 '##' + categoryIdList + 748 '##' + displayPrice + 749 '##' + unitType + 750 '##' + soldInIncrements + 751 '##' + wishlistItemId; 752 753 if (rto_items !== undefined) { 754 cookieData += '##' + rto_items; 755 } 756 return cookieData; 757 758} 759 760// Cart - This is what renders the expanded version of the cart in the upper corner 761/** @return {boolean} */ 762function ExpandCart() { 763 var oldCart = window.cartVersion != 2017; 764 var cartDiv = $("#cartDiv"); 765 var cartDivMobile = $("#cartDivMobile"); 766 767 var products = ''; 768 var subtotal = 0; 769 var subtotal_to_discount = 0; 770 var giftCardSubtotal = 0; 771 var totalItems = 0; 772 var numProducts = 0; 773 var numGiftCards = 0; 774 775 if (oldCart) { 776 UpdateCouponsInCartArrayAndCookie(); 777 } 778 779 // Item totals 780 for (var i = window.cartArray.length - 1; i >= 0; i--) { 781 var row = window.cartArray[i]; 782 if (row[0] == 'product') { 783 if (row[1].indexOf('PITEM') > -1) { 784 continue; 785 } 786 totalItems += Number(row[4]); 787 var displayPrice = 0; 788 if (row[25]) { 789 displayPrice = row[25]; 790 } else { 791 displayPrice = row[3]; 792 } 793 794 var amount = Math.round(fractionalMultiplication(parseFloat(displayPrice), row[4]) * 100) / 100; 795 796 if (row.length > 16 && row[16] == 'GC') { 797 giftCardSubtotal += amount; 798 numGiftCards++; 799 } else { 800 numProducts++; 801 subtotal += amount; 802 803 // 19 - discount_eligible 804 if (row[19] === "true") { 805 subtotal_to_discount += amount; 806 } 807 } 808 809 if (oldCart) { 810 var replaceTitle = window.cartArray[i][2].replace(/\+/g, ' '); 811 try { 812 replaceTitle = JSON.parse(replaceTitle); 813 } catch (e) {} 814 815 products += 816 '<div style="font-size: 12px !important; line-height: 20px; border-bottom: 1px solid #999; padding-bottom:5px; margin-bottom: 10px;">' + 817 '<div style="line-height: 14px; font-size: 11px !important; margin-bottom:4px;">' + 818 replaceTitle + 819 '</div>' + 820 '<div><b>' + formatCurrency(displayPrice) + '</b></div>' + 821 '<span style="font-size: 10px; color: #999;">quantity: ' + row[4] + '</span><br><br>' + 822 '</div>'; 823 } 824 } 825 } 826 827 // Don't show cart div if there are no items 828 if (numProducts == 0 && giftCardSubtotal == 0) { 829 return false;
830 } 831 832 // Calculate discounts 833 // This version of the cart should not require calculating the coupon as it only intends to show quantity of items 834 // however, I've kept it as the mobile version still shows a total amount 835 for (var i = window.cartArray.length - 1; i >= 0; i--) { 836 if (window.cartArray[i][0] == 'coupon' || window.cartArray[i][0] == 'couponV2') { 837 if (oldCart) { 838 var couponInfo = GetCouponInfo(window.cartArray[i]); 839 var discount = Math.round(CalculateDiscount(subtotal_to_discount, i) * 100) / 100; 840 if (discount > 0) { 841 subtotal -= discount; 842 products += 843 '<div style="font-size: 12px !important; line-height: 20px; border-bottom: 1px solid #999; padding-bottom:5px; margin-bottom: 10px;">' + 844 '<div style="line-height: 14px; font-size: 11px !important; margin-bottom:4px;">' + 845 couponInfo.title.replace(/\+/g, ' ') + 846 '</div>' + 847 '<div><b>- ' + formatCurrency(discount) + '</b></div>' + 848 '</div>'; 849 } 850 851 } 852 } 853 } 854 855 // Update subtotal 856 subtotal += giftCardSubtotal; 857 subtotal = Math.round(subtotal * 100) / 100; 858 859 if (oldCart) { 860 // Gift Card Payments 861 var giftCardPayments = 0; 862 for (var i = window.cartArray.length - 1; i >= 0; i--) { 863 if (window.cartArray[i][0] == 'giftcard') { 864 giftCardPayments += Math.round(window.cartArray[i][3] * 100) / 100; 865 } 866 } 867 868 var giftCardRows = ''; 869 if (giftCardPayments > 0) { 870 if (subtotal < giftCardPayments) { 871 giftCardPayments = subtotal; 872 } 873 giftCardRows = '<span style="color: #ccc; font-size: 14px;"><b>Gift Cards = ' + formatCurrency(giftCardPayments) + '</b></span><br>'; 874 subtotal -= giftCardPayments; 875 } 876 877 } 878 879 // Mobile bottom div 880 cartDivMobile.html( 881 '<div style="padding:10px;" onclick="location=\'' + editcartUrl + '\'">' + 882 '<table width="100%"><tr>' + 883 '<td style="text-align: left; cursor: pointer; color: #fff;">' + 884 '<img style="width:23px; height:18px; vertical-align:middle; margin-bottom: 4px;" src="https://images.rainpos.com/view-cart.png"> Cart - ' + (totalItems) + ' items' + 885 '</td>' + 886 '<td style="text-align: right; cursor: pointer; color: #fff;">' + formatCurrency(subtotal) + '</td>' + 887 '</tr></table></div>' 888 ); 889 890 if (!oldCart || window.ABCart == 'B') { 891 // Full page upper corner bullet 892 cartDiv.attr('style', 'display:none; top: 10px; right: 10px; padding: 0px; width: 150px; background: none;'); 893 cartDiv.html( 894 '<div class="btnViewCart" onclick="location=\'' + editcartUrl + '\'" >' + 895 '<img style="width:23px; height:18px; vertical-align:middle; margin-bottom: 4px;" src="https://images.rainpos.com/view-cart.png">' + 896 ' ' + (totalItems) + ' Item' + (totalItems != 1 ? 's' : '') + 897 '</div>' 898 ); 899 } else { 900 cartDiv.html( 901 '<div style="display:table; height:28px; text-align:right; width:100%;">' + 902 ' <span style="display:table-cell; width:20px;"></span>' + 903 ' <span style="vertical-align:middle; text-align:center; display:table-cell; color: #ccc; font-family: Arial; font-size: 12px !important;">' + 904 ' <a href="' + editcartUrl + '" style="' + linkStyles + '">View Cart</a>' + 905 ' </span>' + 906 ' <span style="vertical-align:middle; width:20px; display:table-cell; color: #ccc; font-family: Arial; font-size: 12px !important;">' + 907 ' <a href="javascript:CollapseCart();"><img border=0 width=16 height=11 src="https://images.rainpos.com/btn-collapse.png"></a>' + 908 ' </span>' + 909 '</div>' + 910 911 '<div style="width: 100%; top: 30px; right: 0px; border-top: 1px solid #888; margin-bottom:10px;"></div>' + 912 '<div class="btnViewCart" onclick="ProceedToCheckout(\'no\');" style="font-size:14px; font-family: Arial !important;">Proceed to Checkout »</div>' + 913 '<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;">' + 914 products + 915 '</div>' + 916 giftCardRows + 917 '<div style="color: #ddd; font-size: 14px !important; padding:4px;">Subtotal = ' + formatCurrency(subtotal) + '</div>' + 918 '<div style="line-height:20px;">' + 919 '<a href="' + editcartUrl + '&enterCoupon=true" style="' + linkStyles + '">Enter Coupon</a><br>' + 920 (window.paymentProcessor === undefined || window.paymentProcessor == false || window.paymentProcessor == 'paypal' ? '' : '<a href="' + editcartUrl + '&enterGiftcard=true" style="' + linkStyles + '">Enter Gift Card</a><br>') + 921 '<a href="' + editcartUrl + '" style="' + linkStyles + '">View Cart</a>' + 922 '</div>' + 923 '<div class="btnViewCart" onclick="ProceedToCheckout(\'no\');" style="font-size:14px; font-family: Arial !important; margin-bottom: 10px; margin-top: 5px;">Proceed to Checkout »</div>' + 924 MakeCartForm() + 925 ''); 926 } 927 928 return true; 929} 930 931/** @return {string} */ 932function ProductAttributeKeyGet(in_productId, in_attributeIndex) { 933 // Get the key 934 var key = ''; 935 for (var i = 0; i < window['numAttributes' + in_productId]; i++) { 936 key += (key.length > 0 ? '-' : '') + $('#attribute_' + in_productId + '_' + i).val(); 937 } 938 939 if (key == '') { 940 key = '0'; 941 } 942 943 return key; 944} 945 946// Used by the product page - probably does not belong in this file 947function handleProductOptionChanged(in_productId, in_attributeIndex) { 948 var newPrice = ''; 949 var isSale; 950 var integer = $("#integer" + in_productId); 951 var fraction = $("#fraction" + in_productId); 952 var currentIntegerVal = parseInt(integer.val()); 953 var currentFractionVal = parseFloat(fraction.val()); 954 var minFraction = window.siteMinimumFraction; 955 956 // Get the key 957 var key = ProductAttributeKeyGet(in_productId, in_attributeIndex); 958 var pslrId = parseInt(window['prices' + in_productId][key]['pslrId']); 959 960 // Show propper Custom fields and hide others 961 $('#product-details-pricing-table .custom-fields').hide(); 962 $('#product-details-pricing-table .custom-fields-' + pslrId).show(); 963 964 // Set font colors to black for attributes that are available for the just-selected attribute, and gray for those that aren't available 965 966 var reserve = 0; 967 var outOfStock = false;
968 969 if (window['prices' + in_productId][key]) { 970 var temp = window['prices' + in_productId][key]['salePrice']; 971 // Is the selected product option on sale? 972 isSale = (parseFloat(window['prices' + in_productId][key]['salePrice']) > 0.0 ? true : false); 973 974 // Set price label 975 $('#spanPriceLabel' + in_productId).html((isSale == true ? 'SALE:' : 'Price:')); 976 977 // Set price value 978 if (isSale == true) { 979 newPrice = '<strike>' + formatCurrency(window['prices' + in_productId][key]['price']) + '</strike> <b><span style="color:#ff0000;">' + formatCurrency(window['prices' + in_productId][key]['salePrice']) + '</span></b>'; 980 } else { 981 newPrice = formatCurrency(window['prices' + in_productId][key]['finalDisplayPrice']); 982 } 983 $('#spanPrice' + in_productId).html(newPrice); 984 985 // Set quantity dropdowns 986 987 // Integer 988 var maxInteger = Math.floor(parseFloat(window['prices' + in_productId][key]['quantity'])); 989 if (currentIntegerVal > maxInteger) { 990 currentIntegerVal = maxInteger; 991 } 992 var startInteger = (window['isFabric' + in_productId] == true ? 0 : 1); 993 var soldInIncrements = window['soldInIncrements' + in_productId]; 994 integer.html(""); 995 for (var i = startInteger; i <= maxInteger; i++) { 996 if ((i === 0) && ((minFraction === 1) || (minFraction === '1'))) { 997 continue; 998 } 999 1000 1001 if ((i % soldInIncrements) > 0) { 1002 continue; 1003 } 1004 integer.append("<option value=\'" + i + "\' " + (currentIntegerVal == i ? 'selected' : '') + ">" + i + "</option>"); 1005 } 1006 $('#maxInteger' + in_productId).val(maxInteger); 1007 1008 if(maxInteger <= 0 && (typeof maxFraction === 'undefined' && !window['isFabric' + in_productId])) { 1009 outOfStock = true; 1010 } 1011 1012 // Fraction 1013 if (window['isFabric' + in_productId] == true) { 1014 var increment = (window.measurementUnit == 'Meter' ? 10 : 25); 1015 var maxFraction = Math.floor(parseFloat(window['prices' + in_productId][key]['quantity']) * 100) % 100; 1016 maxFraction = (maxFraction - (maxFraction % increment)) / 100; 1017 if (currentIntegerVal == 0 && currentFractionVal == 0) { 1018 currentFractionVal = maxFraction; 1019 } else if (currentIntegerVal == maxInteger && currentFractionVal > maxFraction) { 1020 currentFractionVal = maxFraction; 1021 } 1022 $('#maxFraction' + in_productId).val(maxFraction); 1023 1024 fraction.html(""); 1025 var startVal = 0; 1026 if (currentIntegerVal == 0) { 1027 if (minFraction && (minFraction > 0) && (minFraction < 1)) { 1028 startVal = Math.floor(window.siteMinimumFraction * 100); 1029 } else { 1030 startVal = (window.measurementUnit === 'Meter') ? 10 : 25; 1031 } 1032 1033 } 1034 for (var i = startVal; i < 100; i += increment) { 1035 var decimal = (i / 100); 1036 if (maxInteger == currentIntegerVal && maxFraction < decimal) { 1037 break; 1038 } 1039 var appendStr = ''; 1040 if (window.measurementUnit == 'Meter' && currentIntegerVal == 0 && decimal == .3 && window.siteMinimumFraction == 'fat quarter') { 1041 appendStr += "<option value=\'0.25\' " + (currentFractionVal == 0.25 ? 'selected' : '') + ">Fat Quarter</option>"; 1042 } 1043 appendStr += "<option value=\'" + decimal + "\' " + (currentFractionVal == decimal ? 'selected' : '') + ">"; 1044 if (window.measurementUnit == 'Meter') { 1045 appendStr += decimal; 1046 } else { 1047 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))); 1048 } 1049 appendStr += "</option>"; 1050 fraction.append(appendStr); 1051 } 1052 } 1053
1054 // WishList 1055 if (typeof wishlistApp != 'undefined' && wishlistApp) { 1056 1057 var qtyInteger = $("#integer" + in_productId); 1058 var qtyFraction = $("#fraction" + in_productId); 1059 var qtyIntegerVal = parseInt(qtyInteger.val()); 1060 var qtyFractionVal = parseFloat(qtyFraction.val()); 1061 1062 // Handle NaN 1063 if (!qtyIntegerVal) { 1064 qtyIntegerVal = 0; 1065 if ((minFraction === 1) || (minFraction === '1')) { 1066 qtyIntegerVal = 1; 1067 } 1068 } 1069 if (!qtyFractionVal) { 1070 qtyFractionVal = 0; 1071 } 1072 1073 wishlistApp.$root.$emit('update_pslr_qty', {pslr_id: pslrId, qty: (qtyIntegerVal + qtyFractionVal)}); 1074 } 1075 } else { 1076 outOfStock = true 1077 } 1078 1079 if (window['isFabric' + in_productId] === true && window['prices' + in_productId][key]['quantity'] < minimumQuantity) { 1080 outOfStock = true; 1081 } 1082 1083 var newPriceNumber = Number(newPrice.replace(/[^0-9\.-]+/g,"")); 1084 var freeProductNotAllowed = 1085 newPriceNumber <= 0 && 1086 (typeof window['freeProductsAllowed'] !== 'undefined' && window['freeProductsAllowed'] === false); 1087 1088 if (freeProductNotAllowed) { 1089 $('[id^=add-to-cart-btn-' + in_productId + ']').attr('disabled','disabled'); 1090 $('[id^=add-to-cart-btn-' + in_productId + ']').html('Product Unavailable'); 1091 } else { 1092 $('[id^=add-to-cart-btn-' + in_productId + ']').removeAttr("disabled"); 1093 $('[id^=add-to-cart-btn-' + in_productId + ']').html('Add to Cart'); 1094 } 1095 1096 if (outOfStock || (reserve > 0 && maxInteger == 0 && (window['isFabric' + in_productId] != true || maxFraction == 0))) { 1097 $('[id^=integer' + in_productId + ']').hide(); 1098 $('[id^=fraction' + in_productId + ']').hide(); 1099 $('[id^=add-to-cart-btn-' + in_productId + ']').hide(); 1100 $('[id^=reserve' + in_productId + ']').html('<span style="color:#f00;">Out of Stock</span>').show(); 1101 } else { 1102 $('[id^=integer' + in_productId + ']').show(); 1103 $('[id^=fraction' + in_productId + ']').show(); 1104 $('[id^=add-to-cart-btn-' + in_productId + ']').show(); 1105 $('[id^=reserve' + in_productId + ']').hide(); 1106 } 1107 1108 var conditionalSelect = $('#conditional-select'); 1109 if (!conditionalSelect) { 1110 return; 1111 } 1112 1113 var conditionOptions = window['prices' + in_productId][key]['conditional_option'] 1114 1115 if (conditionOptions) { 1116 $.each(conditionOptions, function (i, item) { 1117 conditionalSelect.append($('<option>', { 1118 value: item.value, 1119 text : item.label, 1120 selected: i === 0. 1121 })); 1122 }); 1123 conditionalSelect.attr('data-key', key); 1124 conditionalSelect.trigger('change'); 1125 } else { 1126 conditionalSelect.parent().parent().css('display','none'); 1127 } 1128} 1129 1130// Cart 1131function formatCurrency(num) { 1132 num = num.toString().replace(/\$|\,/g, ''); 1133 if (isNaN(num)) { 1134 num = "0"; 1135 } 1136 sign = (num == (num = Math.abs(num))); 1137 num = Math.floor(num * 100 + 0.50000000001); 1138 cents = num % 100; 1139 num = Math.floor(num / 100).toString(); 1140 if (cents < 10) { 1141 cents = "0" + cents; 1142 } 1143 for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++) { 1144 num = num.substring(0, num.length - (4 * i + 3)) + ',' + 1145 num.substring(num.length - (4 * i + 3)); 1146 } 1147 return (((sign) ? '' : '-') + window.displayCurrencySymbol + num + '.' + cents + ' ' + window.displayCurrency); 1148} 1149 1150// Rental Cart (Outdoor) 1151function addRentalToCart(rentalDataId, price) { 1152 if (isRentalInCart(rentalDataId)) { 1153 updateRentalPrice(rentalDataId, price); 1154 } else { 1155 AddProductToCart('', 'sale', rentalDataId, 'Rental', price, 0, 'integer', '', 'no', 1, 1, 0, '', '', 0, '', 'RENTAL', '', 'false', '', ''); 1156 } 1157} 1158 1159function isRentalInCart(rentalDataId) { 1160 var cart = Get_Cart_Cookie('cart'); 1161 if (cart && cart.length > 0 && window.cartArray) { 1162 for (var i = 0; i < window.cartArray.length; i++) { 1163 if (window.cartArray[i][1] == 'RENTAL' + rentalDataId) { 1164 return true; 1165 } 1166 } 1167 } 1168 return false;
1169} 1170 1171function updateRentalPrice(rentalDataId, price) { 1172 var cart = Get_Cart_Cookie('cart'); 1173 if (cart && cart.length > 0 && window.cartArray) { 1174 for (var i = 0; i < window.cartArray.length; i++) { 1175 if (window.cartArray[i][1] == 'RENTAL' + rentalDataId) { 1176 window.cartArray[i][3] = price; 1177 updateCart(); 1178 return; 1179 } 1180 } 1181 } 1182} 1183 1184function updateCart() { 1185 Set_Cart_Cookie('cart', BuildCookieFromArray(), '', '/', '', ''); 1186} 1187 1188function addWishlistProductToCart(item, qty, maxQty, unitType) { 1189 1190 var productId = item.product_id; 1191 var pslrId = item.item_id; 1192 1193 var prices = item.prices; 1194 var price = prices['price']; 1195 if(prices['sale_price'] > 0 && prices['sale_price'] < price) { 1196 price = prices['sale_price']; 1197 } 1198 1199 var notes = ''; 1200 console.log('add '+ qty +'product ' + productId + ' pslr ' + pslrId); 1201 1202 var min = 0; 1203 if(item.qty_on_hand > 0 || item.unlimitedWebInventory === 1) { 1204 min = 1; 1205 } 1206 var discountEligibility = item.discount_eligible; 1207 1208 // (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, 1209 // pslrId, packageData, holdingId, deptId, categoryIdList, displayPrice, unitType, soldInIncrements,qty, wishlist_id 1210 AddProductToCart( 1211 '', 1212 'sale', 1213 productId, 1214 item.title, 1215 price, 1216 item.weight, 1217 item.productCountType, 1218 item.sku, 1219 'no', 1220 min, 1221 maxQty, 1222 0, 1223 notes, 1224 '', 1225 item.bitmap_tax, 1226 '', 1227 'PSLR', 1228 '', 1229 discountEligibility, 1230 item.thumbnail, 1231 '', 1232 false, 1233 pslrId, 1234 null, 1235 null, 1236 item.department_id, 1237 JSON.parse(item.category_ids), 1238 null, 1239 unitType, 1240 null, 1241 qty, 1242 item.wishlist_item_id 1243 ); 1244} 1245 1246 1247// RTO Cart (Music) 1248function addRtoToCartWithCondition(token, pslrId, conditionId, schoolDistrictId, schoolId, studentName, selectedMaintenance, selectedProtection, conditionPiiId) { 1249 conditionPiiId = (conditionPiiId === undefined) ? null : conditionPiiId; 1250 var request = { 1251 pslr_id: pslrId, 1252 condition_id: conditionId, 1253 school_district_id: schoolDistrictId, 1254 school_id: schoolId, 1255 student_name: studentName, 1256 selected_maintenance: selectedMaintenance, 1257 selected_protection: selectedProtection, 1258 condition_pii_id: conditionPiiId 1259 }; 1260 1261 $.ajax({ 1262 url: '/api/rto/online/contract', 1263 type: 'POST', 1264 dataType: 'json', 1265 contentType: 'application/json', 1266 data: JSON.stringify(request), 1267 headers: { 1268 Authorization: 'Bearer ' + token 1269 }, 1270 success: function(result) { 1271 if (result.result != 'success') { 1272 alert('There was an error adding your rental to the cart.'); 1273 } else { 1274 var notes = ''; 1275 if (result.taxable_amount) { 1276 notes = JSON.stringify({taxable_amount:result.taxable_amount}); 1277 } 1278 1279 var rto_items = null; 1280 if (result.rto_items !== undefined) { 1281 rto_items = JSON.stringify({ 1282 rto_principle_payment: result.rto_items.rto_principle_payment, 1283 rto_down_payment: result.rto_items.rto_down_payment, 1284 rto_product_tax_bitmap: result.rto_items.rto_product_tax_bitmap, 1285 rto_maintenance_payment: result.rto_items.rto_maintenance_payment, 1286 rto_maintenance_tax_bitmap: result.rto_items.rto_maintenance_tax_bitmap, 1287 rto_insurance_payment: result.rto_items.rto_insurance_payment, 1288 rto_insurance_tax_bitmap: result.rto_items.rto_insurance_tax_bitmap, 1289 rto_security_deposit: result.rto_items.rto_security_deposit, 1290 rto_initial_payments: result.rto_items.rto_initial_payments, 1291 rto_interest_rate: result.rto_items.rto_interest_rate, 1292 rto_interest_tax_bitmap: result.rto_items.rto_interest_tax_bitmap, 1293 }); 1294 } 1295 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); 1296 } 1297 } 1298 }); 1299} 1300 1301function createAndAddOsrToCart(token, rentalId, variationId, conditionId, maintenance, protection, student, customerInfo, image, addons) { 1302 var config = { 1303 headers: { 1304 Authorization: 'Bearer ' + token, 1305 } 1306 }; 1307 1308 var data = { 1309 rentalId: rentalId, 1310 variationId: variationId, 1311 conditionId: conditionId, 1312 maintenance: maintenance, 1313 protection: protection, 1314 student: student, 1315 customerInfo: customerInfo, 1316 addons: addons, 1317 }; 1318 1319 return axios.post('/api/online-school-rentals/cart-contract', data, config) 1320 .then(function (response) { 1321 var data = response.data; 1322 1323 if (!data || !data.rto_id) { 1324 return Promise.reject(new Error('Error on contract creation')); 1325 } 1326 1327 var rtoItems = data.rto_items ? { 1328 rto_principle_payment: data.rto_items.rto_principle_payment, 1329 rto_down_payment: data.rto_items.rto_down_payment, 1330 rto_product_tax_bitmap: data.rto_items.rto_product_tax_bitmap, 1331 rto_maintenance_payment: data.rto_items.rto_maintenance_payment, 1332 rto_maintenance_tax_bitmap: data.rto_items.rto_maintenance_tax_bitmap, 1333 rto_insurance_payment: data.rto_items.rto_insurance_payment, 1334 rto_insurance_tax_bitmap: data.rto_items.rto_insurance_tax_bitmap, 1335 rto_security_deposit: data.rto_items.rto_security_deposit, 1336 rto_initial_payments: data.rto_items.rto_initial_payments, 1337 rto_interest_rate: data.rto_items.rto_interest_rate, 1338 rto_interest_tax_bitmap: data.rto_items.rto_interest_tax_bitmap, 1339 } : null; 1340 1341 return AddOsrToCart( 1342 data.rto_id, 1343 data.title, 1344 data.due, 1345 data.weight, 1346 {taxable_amount: data.taxable_amount}, 1347 image, 1348 data.pslr_id, 1349 conditionId, 1350 rtoItems 1351 ); 1352 }); 1353} 1354 1355function AddOsrToCart(productId, productTitle, productPrice, productWeight, notes, productImagePath, pslrId, holdingId, rtoItems) { 1356 // Get custom fields & notes 1357 productId = 'RTO' + productId; 1358 notes = notes ? JSON.stringify(notes) : ''; 1359 rtoItems = rtoItems ? JSON.stringify(rtoItems) : null; 1360 1361 var cookieData = dataToCookieString(
1362 productId, productTitle, productPrice, 1, productWeight, 'integer', '', 1363 'no', 1, 1, notes, 0, holdingId, '', 1364 0, 'OSR', pslrId || '', '', 'false', productImagePath, '', 1365 '', null, JSON.stringify(null), productPrice, 'each', 1, null, rtoItems 1366 ); 1367 1368 if (cookieData === '') { 1369 return Promise.reject(new Error('Wrong cart item data')); 1370 } 1371 1372 var promise = addItemToCartData(cookieData); 1373 1374 if (window.facebookPixelId) { 1375 fbq('track', 'AddToCart', { 1376 currency: window.currency, 1377 value: productPrice, 1378 content_name: productTitle, 1379 content_ids: [productId], 1380 content_type: 'product', 1381 contents: [{ 1382 'id': productId, 1383 'quantity': 1 1384 }] 1385 }); 1386 } 1387 1388 addGAEvent(productId, productTitle, productPrice, 1); 1389 1390 return promise; 1391} 1392 1393// Cart 1394 1395 1396function yardLoop(maxFractionVal, siteMinimumFraction, fraction, currFractionVal, intVal, maxIntVal){ 1397 //we could probably be clever and do something cool like the meter loop...but not enough values to make it worth it 1398 fraction.html(""); 1399 if(currFractionVal > maxFractionVal && intVal >= maxIntVal){ 1400 currFractionVal = maxFractionVal; 1401 } 1402 if (intVal === 0) { 1403 if (window.siteMinimumFraction === 'fat quarter') { 1404 fraction.append("<option " + (currFractionVal < 0.5 ? "selected" : "") + " value=\'0.25\'>Fat Quarter</option>"); 1405 } 1406 if (window.siteMinimumFraction === '0.25' || window.siteMinimumFraction === '') { 1407 fraction.append("<option " + (currFractionVal < 0.5 ? "selected" : "") + " value=\'0.25\'>1/4</option>"); 1408 } 1409 } else { 1410 fraction.append("<option value=\'0\'>0</option>"); 1411 if (intVal < maxIntVal || maxFractionVal >= 0.25) { 1412 fraction.append("<option " + (currFractionVal === 0.25 ? "selected" : "") + " value=\'0.25\'>1/4</option>"); 1413 } 1414 } 1415 if (intVal < maxIntVal || maxFractionVal >= 0.5) { 1416 fraction.append("<option " + (currFractionVal === 0.5 ? "selected" : "") + " value=\'0.5\'>1/2</option>"); 1417 } 1418 if (intVal < maxIntVal || maxFractionVal >= 0.75) { 1419 fraction.append("<option " + (currFractionVal === 0.75 ? "selected" : "") + " value=\'0.75\'>3/4</option>"); 1420 } 1421} 1422 1423function meterLoop(startingFraction, currentFraction, fraction, maxFractionValue, intVal, maxIntVal){ 1424 1425 var i = parseFloat(startingFraction); 1426 if(intVal<maxIntVal){ 1427 maxFractionValue = .9 1428 } 1429 if(currentFraction < i ){ 1430 currentFraction = i; 1431 } 1432 if(currentFraction > maxFractionValue && intVal >= maxIntVal){ 1433 currentFraction = maxFractionValue; 1434 } 1435 if (startingFraction === .25 ){ 1436 fraction.append("<option " + (currentFraction === .25 ? "selected" : "") + " value=\'0.25\'>Fat Quarter</option>"); 1437 i = parseFloat(.3); 1438 } 1439 for(i; i <= maxFractionValue ; i += .1 ){ 1440 var count = i.toFixed(1); 1441 fraction.append("<option " + (currentFraction == count ? "selected" : "") + " value=\'"+ count +"\'>"+ count.replace(/^0+/,"")+"</option>"); 1442 if (i === .2 && intVal === 0 ){ 1443 fraction.append("<option " + (currentFraction === .25 ? "selected" : "") + " value=\'0.25\'>Fat Quarter</option>"); 1444 } 1445 } 1446 return fraction; 1447} 1448 1449// TODO - This function is a little better, but still messy, and needs additional refactoring and automated tests 1450function checkFabricMinimum(id, maxQuantity) 1451{ 1452 var minFraction = window.siteMinimumFraction; 1453 var minFractionVal = (minFraction === 'fat quarter') ? 0.25 : minFraction; 1454 1455 var intVal = parseInt($("#integer" + id).val()); 1456 var fraction = $("#fraction" + id); 1457 var currFractionVal = parseFloat(fraction.val()); 1458 1459 var maxIntVal; 1460 var maxFractionVal; 1461 1462 if (typeof maxQuantity === 'undefined') { 1463 maxIntVal = parseInt($("#maxInteger" + id).val()); 1464 maxFractionVal = parseFloat($("#maxFraction" + id).val()); 1465 } else { 1466 maxQuantity = parseFloat(maxQuantity); 1467 maxIntVal = Math.floor(maxQuantity); 1468 maxFractionVal = Math.floor((maxQuantity * 100) % 100) / 100; 1469 } 1470 1471 // WishList 1472 1473 if ((typeof wishlistApp !== 'undefined') && wishlistApp) { 1474 var key = ProductAttributeKeyGet(id, 0); 1475 var pslrId = parseInt(window['prices' + id][key]['pslrId']); 1476 1477 wishlistApp.$root.$emit('update_pslr_qty', {pslr_id: pslrId, qty: (intVal + currFractionVal)}); 1478 } 1479 1480 // Fractional handling 1481 1482 if (window.measurementUnit === 'Meter') { 1483 fraction.html(""); 1484 if (intVal === 0) { 1485 meterLoop(minFractionVal, currFractionVal, fraction, maxFractionVal, intVal, maxIntVal); 1486 } else { 1487 meterLoop('0', currFractionVal, fraction, maxFractionVal, intVal, maxIntVal); 1488 } 1489 1490 } else { 1491 yardLoop(maxFractionVal, siteMinimumFraction, fraction, currFractionVal, intVal, maxIntVal); 1492 } 1493} 1494 1495function getPslrIdFromUI(productId) 1496{ 1497 // Find which PSLR is selected 1498 var key = ''; 1499 for (var i = 0; i < window['numAttributes' + productId]; i++) { 1500 key += (key.length > 0 ? '-' : '') + $('#attribute_' + productId + '_' + i).val(); 1501 } 1502 if (key == '') { 1503 key = '0'; 1504 } 1505 pslrId = window['prices' + productId][key]['pslrId']; 1506 return pslrId; 1507} 1508 1509function getQuantityFromUI(productId) 1510{ 1511 quantity = 1; 1512 if (typeof inlineAddToCartBtn !== 'undefined') { 1513 quantity = parseInt(document.getElementById('inlineInteger' + productId).value) + parseFloat(document.getElementById('inlineFraction' + productId).value); 1514 } else { 1515 var element = document.getElementById('integer' + productId); 1516 var element2 = document.getElementById('fraction' + productId); 1517 quantity = 0; 1518 if (element) { 1519 quantity += parseInt(element.value); 1520 } 1521 if (element2) { 1522 quantity += parseFloat(element2.value); 1523 } 1524 } 1525 return quantity; 1526} 1527 1528function getNotesFromUI(productId) { 1529 var notes = ''; 1530 var noteObjects = $(".class" + productId); 1531 noteObjects.each(function(i) { 1532 if (notes === 'return') { 1533 return; 1534 } 1535 var noteName = $(this).attr('name');
1536 var noteValue = ''; 1537 1538 if ($(this).is(':checkbox')) { 1539 noteValue = ($(this).is(":checked") ? 'checked' : 'not checked'); 1540 } 1541 else { 1542 noteValue = $.trim($(this).val()); 1543 } 1544 1545 if ($(this).attr('required') == true && noteValue == '') { 1546 alert(noteName + ' is a required field.'); 1547 notes = 'return'; 1548 return; 1549 } 1550 1551 if (notes == '') { 1552 notes = {}; 1553 } 1554 notes[noteName] = noteValue; 1555 }); 1556 1557 if (notes == 'return') { 1558 return; 1559 } 1560 return notes; 1561} 1562 1563function 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) { 1564 if (in_productType === 'PSLR') { 1565 if (!pslrId) { 1566 pslrId = getPslrIdFromUI(productId); 1567 } 1568 1569 // Get Quantity 1570 if (!quantity) { 1571 quantity = getQuantityFromUI(productId); 1572 } 1573 1574 var notes = in_notes; 1575 if (!notes) { 1576 notes = getNotesFromUI(productId); 1577 } 1578 1579 var pslr = { 1580 type: in_productType, 1581 pslr_id: pslrId, 1582 product_id: productId, 1583 quantity: quantity, 1584 notes: notes, 1585 wishlistItemId: wishlistItemId || 0, 1586 title: productTitle, 1587 }; 1588 1589 if (conditionId) { 1590 pslr['condition'] = conditionId; 1591 } else { 1592 var condition = getConditional(productId); 1593 if (condition) { 1594 pslr['condition'] = condition.id; 1595 } 1596 } 1597 1598 if (conditions) { 1599 pslr['conditions'] = conditions; 1600 } 1601 1602 if (window.knobby && window.knobby['module_comment_sold']) { 1603 pslr.sku = productSku; 1604 pslr.price = productPrice; 1605 } 1606 if (addonId) { 1607 pslr['addon_id'] = addonId; 1608 } 1609 1610 return pslr; 1611 } 1612 return null; 1613} 1614 1615function getConditional(productId) { 1616 if (!document.getElementById('conditional-select')) { 1617 return null; 1618 } 1619 1620 if (document.getElementById('conditional-select') === null) { 1621 return null; 1622 } 1623 1624 var key = ProductAttributeKeyGet(productId, 0); 1625 1626 var value = document.getElementById('conditional-select').value; 1627 1628 var conditional = window['prices' + productId][key]['conditional']; 1629 1630 if (!conditional) { 1631 return null; 1632 } 1633 1634 return conditional.find(function (v) { 1635 return parseInt(v.item_condition_id) === parseInt(value); 1636 }); 1637} 1638 1639function getConditionQuantity(productId, conditionId, key = null) { 1640 key = key === null ? ProductAttributeKeyGet(productId, 0) : key; 1641 1642 var conditionQuantity = window['prices' + productId][key]['conditional_quantity'].find(function (v) { 1643 return parseInt(v.condition_id) === parseInt(conditionId); 1644 }); 1645 1646 return conditionQuantity ? parseInt(conditionQuantity.quantity) : 0; 1647} 1648 1649function addClassToCart(classId, eventId, requireAttendees, packageData, class_id_str) { 1650 if (requireAttendees) { 1651 var result = verifyClassAttendees('CLASS' + eventId); 1652 if (!result) { 1653 return; 1654 } 1655 } 1656 1657 var selectedComponents = []; 1658 var packageId = null; 1659 if (packageData && packageData.available && packageData.option === 'classAndPackage') { 1660 packageId = packageData.packageId; 1661 if (packageData.components) { 1662 packageData.components.forEach(function(c) { 1663 selectedComponents.push(c.selectedItem); 1664 }); 1665 } 1666 } 1667 1668 var item = { 1669 type: 'CLASS', 1670 event_id: eventId, 1671 class_id: classId, 1672 package_id: packageId, 1673 components: selectedComponents, 1674 class_attendees: getClassAttendees('CLASS' + eventId), 1675 } 1676 addItemToCart(item); 1677} 1678 1679function addItemToCart(item, productId) { 1680 if (!isValidConditionQuantityInCart(item, productId)) { 1681 if (!item.hasOwnProperty('conditions')) { 1682 decreaseActualConditionQuantity(productId, item.condition); 1683 } 1684 1685 alert('There was an error adding this item to your cart.'); 1686 return Promise.resolve(); 1687 } 1688 1689 var promise = requestModule.getInstance().addItemToCart({ 1690 item: item, 1691 }); 1692 1693 // Google Analytics 1694 if (item.type === 'PSLR') { 1695 if (item.quantity > 0) { 1696 addGAEvent(item.product_id, item.title, item.price, item.quantity); 1697 } 1698 } 1699 1700 if (window.knobby && window.knobby['module_comment_sold']) { 1701 if (typeof item.type !== 'undefined' && item.type.toLowerCase() === 'pslr') { 1702 //we want to fire event only for pslr items 1703 var data = { 1704 product: { 1705 sku: item.pslr_id || item.sku, 1706 price: parseFloat(item.price), 1707 currency: window.currency || 'USD', 1708 quantity: item.quantity, 1709 } 1710 } 1711 try { 1712 videeoCommand('addToCart', data); 1713 } catch (e) { 1714 console.warn(e); 1715 } 1716 } 1717 } 1718 1719 return promise; 1720} 1721 1722/** 1723 * Adds a product to the cart (pre-2017 version). 1724 * When adding parameters, make sure to also add them for GetAttendees() 1725 */ 1726function AddProductToCart(in_businessEmail, in_paymentAction, productId, productTitle, productPrice, productWeight, productC
1726ountType, 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) { 1727 if (window.location.search.indexOf('ie') == -1) { // IE still can't use the new product page. 1728 if (requireClassAttendees) { 1729 var result = verifyClassAttendees(productId); 1730 if (!result) { 1731 return; 1732 } 1733 } 1734 1735 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); 1736 if (item) { 1737 addItemToCart(item, productId); 1738 return; 1739 } 1740 } 1741 1742 unitType = unitType || 'each'; 1743 soldInIncrements = soldInIncrements || 1; 1744 1745 if (in_businessEmail !== null) { 1746 window.businessEmail = in_businessEmail; 1747 } 1748 1749 if(typeof deptId === 'undefined') { 1750 deptId = null; 1751 } 1752 if(typeof categoryIdList === 'undefined') { 1753 categoryIdList = []; 1754 } 1755 1756 // Class Package Items 1757 var classPackage = false; 1758 var classPackageData = []; 1759 if (productId.indexOf('CLASS') > -1) { 1760 // Overloading here - it's just too much work to add new fields and we want to redo all this anyway 1761 var classUid = new Date().getTime(); 1762 productSku = classUid; 1763 if (packageData && packageData.available) { 1764 classPackage = true; 1765 if (packageData.option == 'classAndPackage') { 1766 in_productType = 'PACKAGE'; 1767 pslrId = packageData.packageId; 1768 productWeight = packageData.class_price; 1769 if (packageData.components) { 1770 packageData.components.forEach(function(c) { 1771 var s = c.selectedItem; 1772 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); 1773 if (packageItemData) { 1774 classPackageData.push(packageItemData); 1775 } 1776 }); 1777 } 1778 } 1779 } 1780 } 1781 1782 categoryIdList = JSON.stringify(categoryIdList); 1783 1784 var class_attendees = ""; 1785 if (requireClassAttendees) { 1786 1787 class_attendees = getClassAttendees(productId); 1788 if (class_attendees.no_value != undefined) { 1789 1790 alert("Attendee Name Required"); 1791 $("#" + class_attendees.input_id).focus(); 1792 return; 1793 } 1794 } 1795 1796 // Set defaults 1797 if (!pslrId) { 1798 pslrId = ''; 1799 } 1800 1801 if (!requiresDownloadEmailAddress || requiresDownloadEmailAddress == 'undefined') { 1802 requiresDownloadEmailAddress = "no"; 1803 } 1804 1805 if (!minQuantity || minQuantity == 'undefined') { 1806 if (productCountType == 'fraction') { 1807 minQuantity = 0.25; 1808 } else { 1809 minQuantity = 1; 1810 } 1811 } 1812 1813 if (!maxQuantity || maxQuantity == 'undefined') { 1814 maxQuantity = 100; 1815 } 1816 1817 if (!isTimed || isTimed == 'undefined') { 1818 isTimed = 0; 1819 } 1820 1821 if ((!in_shipping || in_shipping == 'undefined') && in_shipping !== 0) { 1822 in_shipping = ''; 1823 } 1824 1825 if ((!in_taxes || in_taxes == 'undefined') && in_taxes !== 0) { 1826 in_taxes = ''; 1827 } 1828 1829 // Get current cart 1830 var cart = ''; 1831 if (Get_Cart_Cookie('cart')) { 1832 cart = Get_Cart_Cookie('cart'); 1833 } 1834
1835 var productCount = null; 1836 if (quantity > 0) { 1837 productCount = quantity; 1838 } else if (productCountType !== null) { 1839 if (in_productType == 'RENTAL' || in_productType == 'RTO') { 1840 productCount = 1; 1841 } else if (inlineAddToCartBtn) { 1842 productCount = parseInt(document.getElementById('inlineInteger' + productId).value) + parseFloat(document.getElementById('inlineFraction' + productId).value); 1843 } else { 1844 var element = document.getElementById('integer' + productId); 1845 var element2 = document.getElementById('fraction' + productId); 1846 productCount = 0; 1847 if (element) { 1848 productCount += parseInt(element.value); 1849 } 1850 if (element2) { 1851 productCount += parseFloat(element2.value); 1852 } 1853 } 1854 } else { 1855 productCount = 1; 1856 } 1857 1858 // Get custom fields & notes 1859 var notes = ''; 1860 if (in_notes != 'undefined' && in_notes != '') { 1861 notes = in_notes; 1862 } else { 1863 var noteObjects = $(".class" + productId); 1864 noteObjects.each(function(i) { 1865 if (notes == 'return') { 1866 return; 1867 } 1868 var noteName = $(this).attr('name'); 1869 var noteValue = ''; 1870 1871 if ($(this).is(':checkbox')) { 1872 noteValue = ($(this).is(":checked") ? 'checked' : 'not checked'); 1873 } 1874 else { 1875 noteValue = $.trim($(this).val()); 1876 } 1877 if ($(this).attr('requiredField') == 'true' && noteValue == '') { 1878 noteName = noteName.replace(/_/g, ' '); 1879 alert(noteName + ' is a required field.'); 1880 notes = 'return'; 1881 return; 1882 } 1883 1884 1885 if (notes == '') { 1886 notes = {}; 1887 } 1888 notes[noteName] = noteValue; 1889 }); 1890 1891 if (notes == 'return') { 1892 return; 1893 } 1894 if (notes != '') { 1895 notes = JSON.stringify(notes); 1896 } 1897 } 1898 1899 // Product ID is modified here, so make sure it goes after anything that relies on the Product ID. 1900 // Handle PSLR information 1901 if (in_productType == 'PSLR') { 1902 // Find selected PSLR 1903 var key = ''; 1904 var titleAddOn = ''; 1905 for (var i = 0; i < window['numAttributes' + productId]; i++) { 1906 key += (key.length > 0 ? '-' : '') + $('#attribute_' + productId + '_' + i).val(); 1907 titleAddOn += (titleAddOn.length > 0 ? ' - ' : '') + window['attributeValues' + productId][i][$('#attribute_' + productId + '_' + i).val()]; 1908 } 1909 if (key == '') { 1910 key = '0'; 1911 } 1912 1913 // Fix data 1914 productTitle += (titleAddOn.length > 0 ? ': ' : '') + titleAddOn; 1915 if (window['prices' + productId]) { 1916 productWeight = window['prices' + productId][key]['weight']; 1917 productPrice = window['prices' + productId][key]['finalPrice']; 1918 displayPrice = window['prices' + productId][key]['finalDisplayPrice']; 1919 productSku = window['prices' + productId][key]['sku']; 1920 maxQuantity = window['prices' + productId][key]['quantity']; 1921 pslrId = window['prices' + productId][key]['pslrId']; 1922 } 1923 1924 // Get the option image if no image specified 1925 if (!productImagePath && $('#productImage' + productId).length) { 1926 var optionImage = $('#productImage' + productId).attr('src'); 1927 if (optionImage && optionImage.length > 0) { 1928 productImagePath = optionImage; 1929 } 1930 } 1931 } 1932 // Gift Cards 1933 else if (in_productType == 'GC') { 1934 productPrice = $("#GCValue").val(); 1935 displayPrice = productPrice; 1936 productId += Math.floor(Math.random() * 1000); 1937 } else if (in_productType == 'RENTAL') { 1938 productId = 'RENTAL' + productId; 1939 } else if (in_productType == 'RTO') { 1940 productId = 'RTO' + productId; 1941 } else if (in_productType == 'SUBSCRIPTION') { 1942 productId = 'SUBSCRIPTION' + productId; 1943 } 1944 1945 if (!displayPrice) { 1946 displayPrice = productPrice; 1947 } 1948 1949 // create path for timed inventory ajax calls 1950 if (isTimed == 1) { 1951 var cartUrl = '/module/product.htm?timed=1'; 1952 if (isAdminUrl(location.host)) { 1953 cartUrl = location.pathname.substring(0, location.pathname.indexOf('/', 2)) + cartUrl; 1954 } 1955 } 1956 if (!holdingId) { 1957 holdingId = ''; // timed inventory variable 1958 } 1959 1960 var cookieData = dataToCookieString(productId,productTitle,productPrice,productC
1960ount,productWeight,productCountType,productSku,requiresDownloadEmailAddress,minQuantity,maxQuantity,notes 1961 ,isTimed,holdingId,in_shipping,in_taxes,in_productType,pslrId,in_hasAttendees,isDiscountEligible,productImagePath,productImageStyle,class_attendees 1962 ,deptId,categoryIdList,displayPrice,unitType,soldInIncrements,wishlistItemId, rto_items); 1963 1964 // For packageData, we add it as part of the class 1965 if (productId.indexOf('PITEM') > -1) { 1966 return encodeURIComponent(cookieData); 1967 } 1968 1969 if (cookieData === '') { 1970 return ; 1971 } 1972 addItemToCartData(cookieData, classPackageData); 1973 1974 var contentId = productSku ? productSku : productId; 1975 if (window.facebookPixelId) { 1976 fbq('track', 'AddToCart', { 1977 currency: window.currency, 1978 value: productPrice, 1979 content_name: productTitle, 1980 content_ids: [contentId], 1981 content_type: 'product', 1982 contents: [{ 1983 'id': contentId, 1984 'quantity': productCount 1985 }] 1986 }); 1987 } 1988 1989 addGAEvent(contentId, productTitle, productPrice, productCount); 1990} 1991 1992function verifyClassAttendees(productId) { 1993 var classAttendees = getClassAttendees(productId); 1994 if (classAttendees.no_value !== undefined) { 1995 // TODO: No alerts 1996 alert("Attendee Name Required"); 1997 $("#" + classAttendees.input_id).focus(); 1998 return false; 1999 } 2000 return true; 2001} 2002 2003function getClassAttendees(class_id_str) { 2004 2005 var return_value = ""; 2006 var classToken = "CLASS"; 2007 var pos = class_id_str.indexOf(classToken); 2008 if (pos > -1) { 2009 2010 var event_id = class_id_str.substr(pos + classToken.length); 2011 return_value = getAttendeesJson(event_id); 2012 } 2013 return return_value; 2014} 2015 2016function getAttendeesJson(in_event_id) { 2017 2018 var jsn = ""; 2019 var attendees = $(".attendee"); 2020 if (attendees) { 2021 2022 var names = []; 2023 2024 for (var i = 0; i < attendees.length; i++) { 2025 2026 var ele = attendees[i]; 2027 var event_id = ele.attributes["eventid"].value; 2028 2029 if (in_event_id == event_id && ele.value.length > 0) { 2030 2031 names.push(ele.value); 2032 } 2033 } 2034 if (names.length === 0) { 2035 2036 jsn = {no_value: 1, input_id: "event_" + in_event_id + "_attendee_1", numberOfAttendees: parseInt($('#qty').val())}; 2037 } else { 2038 2039 jsn = JSON.stringify(names); 2040 } 2041 } 2042 return jsn; 2043} 2044 2045function CalculateDiscount(subtotal, i) { 2046 var discount = 0; 2047 if (window.cartArray[i][0] == 'coupon' || window.cartArray[i][0] == 'couponV2') { 2048 var couponInfo = GetCouponInfo(window.cartArray[i]); 2049 if (couponInfo.couponType == 'dollar_off') { 2050 // Calculate discount 2051 if (subtotal > couponInfo.minDollarAmount) { 2052 discount = couponInfo.dollarOffAmount; 2053 } 2054 discount = Math.round(discount * 100) / 100; 2055 } 2056 else if (couponInfo.couponType == 'percent_off') { 2057 if (subtotal > couponInfo.minDollarAmount) { 2058 discount = Number(subtotal) * (Number(couponInfo.percentOff) / 100); 2059 discount = Math.round(discount * 100) / 100; 2060 } 2061 2062 } 2063 if(couponInfo.maxDiscount && couponInfo.maxDiscount < discount) { 2064 discount = couponInfo.maxDiscount; 2065 } 2066 } 2067 2068 if (discount + 0.01 > subtotal) { 2069 discount = subtotal - 0.01; 2070 } 2071 2072 return discount; 2073} 2074 2075function GetCouponInfo(row) { 2076 if (!row) { 2077 return null; 2078 } 2079 2080 var couponInfo = {}; 2081 couponInfo['version'] = row[0]; 2082 couponInfo['couponType'] = row[1]; 2083 couponInfo['title'] = row[2]; 2084 if (couponInfo.version == 'couponV2') { 2085 couponInfo['number'] = row[3]; 2086 couponInfo['couponId'] = row[4]; 2087 if (couponInfo.couponType == 'dollar_off') { 2088 couponInfo['minDollarAmount'] = row[5]; 2089 couponInfo['dollarOffAmount'] = row[6]; 2090 } else if (couponInfo.couponType == 'percent_off') { 2091 couponInfo['percentOff'] = row[5]; 2092 } 2093 } else { 2094 if (couponInfo.couponType == 'dollar_off') { 2095 couponInfo['minDollarAmount'] = row[3]; 2096 couponInfo['dollarOffAmount'] = row[4]; 2097 couponInfo['maxDiscount'] = row[5]; 2098 } 2099 2100 if (couponInfo.couponType == 'percent_off') { 2101 couponInfo['percentOff'] = row[3]; 2102 couponInfo['minDollarAmount'] = row[4]; 2103 couponInfo['maxDiscount'] = row[5]; 2104 } 2105 2106 if (row.length >= 7) { 2107 couponInfo['number'] = row[6]; // coupon_id 2108 } 2109 if (row.length >= 8) { 2110 couponInfo['start_date'] = row[7]; 2111 } 2112 if (row.length >= 9) { 2113 couponInfo['end_date'] = row[8]; 2114 } 2115 } 2116 return couponInfo; 2117} 2118 2119function isAdminUrl(url) { 2120 if (typeof adminUrls != 'undefined') { 2121 var length = adminUrls.length; 2122 for (var i = 0; i < length; i++) { 2123 if (adminUrls[i] == url || 'www.' + adminUrls[i] == url || 'my-' + adminUrls[i] == url || 'www.my-'
2123+ adminUrls[i] == url) { 2124 return true; 2125 } 2126 } 2127 } 2128 return false; 2129} 2130 2131function onChangeConditionalSelect(productId) { 2132 changeConditional(productId); 2133 window.vueEventHub.$eventHub.$emit('product-style-variant-changed'); 2134} 2135 2136function changeConditional(productId) { 2137 var condition = getConditional(productId); 2138 2139 if (!condition) { 2140 return; 2141 } 2142 2143 if (window.knobby && window.knobby['module_improved_waitlist']) { 2144 var conditionSelect = $('#conditional-select'); 2145 conditionSelect.attr('selected-id', condition.id); 2146 conditionSelect.attr('selected-name', condition.name); 2147 } 2148 2149 var price = condition.hasOwnProperty('display_price') ? condition.display_price.price : 0; 2150 2151 var priceHtml = formatCurrency(price); 2152 2153 var sale = condition.hasOwnProperty('display_price') ? condition.display_price.sale_price : 0; 2154 2155 if (+sale > 0) { 2156 priceHtml = '<strike>' + formatCurrency(price) + '</strike> <b><span style="color: #ff0000">' + formatCurrency(sale) + '</span></b>' 2157 } 2158 2159 document.getElementById('spanPrice' + productId).innerHTML = priceHtml; 2160 changQuantity(productId, condition.id); 2161} 2162 2163function changQuantity(productId, conditionId) { 2164 var isUnlimited = +$('#maxInteger' + productId).val() === 1000; 2165 2166 var quantity = isUnlimited === true ? 1000 : getConditionQuantity(productId, conditionId); 2167 2168 var quantitySelect = $('#integer' + productId); 2169 quantitySelect.find('option').remove() 2170 2171 var reserve = $('#reserve' + productId); 2172 var addBtn = $('#add-to-cart-btn-' + productId); 2173 var addToWaitlistBtn = $('#waitlist-wrapper'); 2174 2175 if (quantity === 0) { 2176 reserve.css('display', 'block'); 2177 quantitySelect.css('display', 'none') 2178 addBtn.css('display', 'none'); 2179 addToWaitlistBtn.css('display', 'inline-block'); 2180 2181 return; 2182 } 2183 reserve.css('display', 'none'); 2184 quantitySelect.css('display', 'block'); 2185 addToWaitlistBtn.css('display', 'none'); 2186 addBtn.css('display', 'inline-block'); 2187 2188 for(var i = 0; i < quantity; i++) { 2189 quantitySelect.append($('<option>', { 2190 value: i + 1, 2191 text : i + 1, 2192 })); 2193 } 2194} 2195function findCartItemsByProductId(productId) { 2196 return window.cartArray.filter(function (item) { 2197 if (item[0] !== 'product'){ 2198 return false; 2199 } 2200 2201 return parseInt(item[1].replace('PSLR', '')) === parseInt(productId); 2202 }); 2203} 2204function isValidConditionQuantityInCart(item, currentProductId) { 2205 if (!window.cartArray.length) { 2206 return true; 2207 } 2208 2209 var cart = findCartItemsByProductId(currentProductId); 2210 2211 if (!cart.length) { 2212 return true; 2213 } 2214 2215 var isValidConditionQuantity = function (condition, inCartQuantity) { 2216 var quantity = getConditionQuantity(currentProductId, condition); 2217 2218 return quantity >= inCartQuantity; 2219 }; 2220 2221 var CONDITION_INDEX = 30; 2222 var QUANTITY_INDEX = 4; 2223 2224 for (var i = 0; i < cart.length; i++) { 2225 var cartItem = cart[i]; 2226 2227 var condition = +cartItem[CONDITION_INDEX]; 2228 var quantity = +cartItem[QUANTITY_INDEX]; 2229 2230 if (item.conditions) { 2231 for (var j = 0; j < item.conditions; j++) { 2232 if (!isValidConditionQuantity(item.conditions[j].condition, quantity) && +item.conditions[j].condition === condition) { 2233 return false; 2234 } 2235 } 2236 2237 return true; 2238 } 2239 2240 if (condition !== +item.condition) { 2241 continue; 2242 } 2243 2244 if (!isValidConditionQuantity(condition, quantity)) { 2245 return false; 2246 } 2247 } 2248 2249 return true; 2250} 2251 2252function getInCartQuantity(productId, conditionId, defaultQuantity = 1) { 2253 var cart = findCartItemsByProductId(productId); 2254 2255 if (!cart) { 2256 return defaultQuantity; 2257 } 2258 2259 var CONDITION_INDEX = 30; 2260 var QUANTITY_INDEX = 4; 2261 2262 for (var i = 0; i < cart.length; i++) { 2263 var cartItem = cart[i]; 2264 if (+cartItem[CONDITION_INDEX] === +conditionId) { 2265 return +cartItem[QUANTITY_INDEX]; 2266 } 2267 } 2268 2269 return defaultQuantity; 2270} 2271 2272function decreaseActualConditionQuantity(productId, conditionId, key = null) { 2273 key = key === null ? ProductAttributeKeyGet(productId, 0) : key; 2274 2275 var conditionQuantity = window['prices' + productId][key]['conditional_quantity'].find(function (v) { 2276 return parseInt(v.condition_id) === parseInt(conditionId); 2277 }); 2278 2279 conditionQuantity.quantity = conditionQuantity.quantity - getInCartQuantity(productId, conditionId); 2280} 2281 2282function addGAEvent(productId, productTitle, productPrice, productC
2282ount) { 2283 if (window.knobby && window.knobby['module_flag_google_analytics_v4']) { 2284 if (window.googleAnalyticsId) { 2285 gtag('event', 'add_to_cart', { 2286 currency: window.currency || 'USD', 2287 value: parseFloat(productPrice), 2288 items: [{ 2289 item_id: productId, 2290 item_name: productTitle, 2291 quantity: productCount, 2292 price: productPrice, 2293 }] 2294 }); 2295 } 2296 } else { 2297 if (window.googleAnalyticsId) { 2298 gtag('event', 'add_to_cart', { 2299 "items": [{ 2300 id: productId, 2301 name: productTitle, 2302 quantity: productCount, 2303 price: productPrice, 2304 currency: window.currency, 2305 }] 2306 }); 2307 } 2308 } 2309}
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.