1app.cartIsUpdating = false; 2app.deliveryMode = "post"; 3app.debugMode = (utils.getParam("dbg") == "1"); 4app.pmmEventRegistered = false; 5app.lastShipmentId = 0; 6app.lastDraftHash = 0; 7app.suppressCartNotify = false; 8 9app.updateDeliveryArea = function(newCountry, newPostCode, cb) { 10 var m = this; 11 // Store values 12 var hasChanged = false; 13 if (m.ls.deliveryCountry != newCountry) { 14 m.ls.deliveryCountry = newCountry; 15 hasChanged = true; 16 } 17 18 if (m.ls.deliveryPostCode != newPostCode) { 19 m.ls.deliveryPostCode = newPostCode; 20 hasChanged = true; 21 } 22 23 if (hasChanged) { 24 m.setLocalState(m.ls); 25 } 26 27 if (cb) { 28 cb(null, m.ls); 29 } 30 // Update all on page combos 31 // Refresh cart 32} 33 34app.cartNeedsRefresh = function(cb) { 35 if(window.disableLegacyCart){ 36 if (cb) cb(); 37 return; 38 } 39 var m = this; 40 //console.log("cartNeedsRefresh request"); 41 if (app.refreshCartTimeout) { 42 clearTimeout(app.refreshCartTimeout); 43 } 44 45 $('.fnc-complete-checkout').prop('disabled', true); 46 47 app.refreshCartTimeout = setTimeout(function() { 48 if (!app.cartIsUpdating) { 49 app.cartIsUpdating = true; 50 //console.log("cartNeedsRefresh run"); 51 app.calculateTotals(function(total) { 52 app.refreshCart("", function() { 53 app.saveDraftSale(); 54 app.cartIsUpdating = false; 55 if (cb) cb(); 56 }); 57 }); 58 } 59 }, 500); 60 61} 62 63app.applyDiscountCode = function(code) { 64 var m = this; 65 var validCode = false; 66 app.checkVoucherCode(code, function(data) { 67 if (data) { 68 if (data.valid) { 69 if (data.comments) { 70 app.alert("Discount Code Applied", data.comments); 71 } 72 validCode = true; 73 } else { 74 app.alert("Discount Code Error", "The code <b>" + code + "</b> is not valid or has expired."); 75 } 76 } else { 77 app.alert("Discount Code Error", "There was an error checking the code."); 78 } 79 80 // store result in sale data 81 var saleOptions = { 82 startkey: "sale_" + m.ls.saleGuid, 83 endkey: "sale_" + m.ls.saleGuid + "\uffff", 84 include_docs: true 85 }; 86 m.db.allDocs(saleOptions, function(err, doc) { 87 if (doc.rows[0].doc) { 88 if (validCode) { 89 if (doc.rows[0].doc.vouchers = "") { 90 doc.rows[0].doc.vouchers = code; 91 } else { 92 doc.rows[0].doc.vouchers += "," + code; 93 } 94 } 95 } 96 m.db.put(doc.rows[0].doc, {}, function(err, resp) { 97 app.cartNeedsRefresh(); 98 }); 99 }); 100 }); 101} 102 103app.selectPickerRefresh = function() { 104 try { 105 if (!utils.isBS5) { 106 if (/webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) { 107 //console.log("Mobile select", navigator.userAgent); 108 $('.selectpicker').selectpicker('mobile'); 109 } else { 110 $('.selectpicker').selectpicker('refresh'); 111 } 112 } 113 } 114 catch (e) { } 115 //Android| 116} 117 118app.validateShipping = function(cb) { 119 var m = this; 120 var shipmentOptions = { 121 startkey: "shp_", 122 endkey: "shp_\uffff", 123 include_docs: true 124 }; 125 m.db.allDocs(shipmentOptions, function(err, shipmentDoc) { 126 //debugger; 127 if (!err) { 128 if (shipmentDoc.rows.length == 0) { 129 cb("Shipping selection is required", null); 130 } else { 131 cb(null, shipmentDoc.rows.length); 132 } 133 } else { 134 cb("Shipping selection is required", null); 135 } 136 }); 137} 138 139app.registerCartEvents = function() { 140 var m = this; 141 142 $(".fnc-pkg-option-select").off().on("change", function(e) { 143 var $pkg = $($(this).parents("div.package-option")); 144 if ($(this).val().substr(0, 1) == "[") { 145 $pkg.attr("data-prd-id", "0"); 146 $pkg.attr("data-pmm-id", "0"); 147 $pkg.attr("data-pmm-code", ""); 148 $('.selectpicker').selectpicker('refresh'); 149 } else { 150 var obj = JSON.parse("{" + $(this).val() + "}"); 151 $pkg.attr("data-prd-id", obj.prdId); 152 $pkg.attr("data-pmm-id", obj.pmmId); 153 $pkg.attr("data-pmm-code", obj.code); 154 $('.selectpicker').selectpicker('refresh'); 155 try { 156 app.calculatePackagePrice(); 157 } 158 catch(e) {} 159 } 160 }); 161 162 $(".fnc-pkg-option-select").trigger('change'); 163 164 var prev = null; 165 if (!app.pmmEventRegistered) { 166 $(".fnc-pmm-select").off().on("change", function(e) { 167 e.stopPropagation(); 168 //if (prev) prev.style.display = "none"; 169 170 var infodata = $(this).find(":selected").data("info"); 171 if (!infodata) { 172 // older combo method 173 infodata = $(this).val(); 174 } 175 var obj = JSON.parse("{" + infodata + "}"); 176 var pi = $(this).parents('.product-item'); 177 var selPanel = $($("#pmm_" + obj.pmmId)[0]); 178 var picId = selPanel.attr("data-pic-id"); 179 if (!picId) { 180 picId = pi.attr("data-pic-id"); 181 } 182 183 $(".pmm-panel[data-prd-id=" + pi.attr("data-prd-id") + "]").css("display", "none"); 184 $(".default-option-price").css("display", "none"); 185 186 pi.attr("data-pmm-id", obj.pmmId); 187 pi.attr("data-prd-code", obj.code); 188 pi.attr("data-pmm-name", obj.name); 189 pi.attr("data-price", obj.price); 190 pi.attr("data-pic-id", picId); 191 pi.attr("data-discount", obj.discount); 192 pi.attr("data-original-price", obj.originalPrice); 193 selPanel.css("display", "block"); 194 prev = selPanel; 195 196 $("body").trigger("productOptionChange", obj); 197 198 }); 199 app.pmmEventRegistered = true; 200 } 201 202 if(window.disableLegacyCart){ 203 return; 204 } 205 206 if (typeof cartOptions !== 'undefined') { 207 cartOptions.userHasSeenMinOrderWarning = false; 208 } 209 210 $(".fnc-cart-save-as-list").off().on("click", function(e) { 211 var el = $(this); 212 var name = prompt("Please provide a name for your list of products", "My List Name"); 213 if (name) { 214 m.saveCartAsList(name, function() { 215 app.alert("List Saved", "Your list named <b>" + name + "</b> was saved successfully!"); 216 }); 217 } else { 218 app.alert("List Save Cancelled", "The cart contents were not saved!"); 219 } 220 }); 221 222 $(".fnc-cart-delete-list").off().on("click", function(e) { 223 var el = $(this); 224 var listId = el.attr("data-list-id"); 225 var listName = el.attr("data-list-name"); 226 app.confirm("Delete List", "Are you sure you want to delete " + listName + "?", "Yes", "No", function() { 227 var ids = listId.split("_"); 228 app.deleteSavedList(ids[2], function() { 229 setTimeout(function() { 230 app.alert("List Deleted", "Your list named <b>" + listName + "</b> was deleted successfully.", function() { 231 location.reload(); 232 }); 233 }, 4000); 234 }) 235 }); 236 }); 237 238 $(".fnc-cart-quote-item-shipping").off().on("click", function(e) { 239 var el = $(this); 240 var prdId = el.attr("data-prd-id"); 241 var pmmId = el.attr("data-pmm-id"); 242 243 $('#dialog-confirm').on('shown.bs.modal', function() { 244 $('#dialog-confirm').off('shown.bs.modal'); 245 app.loadCountryLists();
246 247 if (!m.ls.deliveryCountry) { 248 m.ls.deliveryCountry = user_country; 249 } 250 251 if (m.ls.deliveryCountry) { 252 $('#quoteDeliveryCountry option[value=' + m.ls.deliveryCountry + ']').attr('selected', 'selected'); 253 } 254 255 if (m.ls.deliveryPostCode) { 256 $("#quoteDeliveryPostCode").val(m.ls.deliveryPostCode); 257 } 258 259 $('#quoteDeliveryCountry').focus(); 260 app.selectPickerRefresh(); 261 }); 262 263 app.confirm("Shipping Quote", "Please provide your destination Country and Post Code to see available shipping options:<br><br>" + 264 "<div class='row'><div class='col-md-3'>Country:</div><div class='col-md-9'><select class='selectpicker fnc-update-shipping-country data-country-select' data-size='12' id='quoteDeliveryCountry' name='quoteDeliveryCountry'></select><br><br></div></div>" + 265 "<div class='row'><div class='col-md-3'>Post Code:</div><div class='col-md-9'><input id='quoteDeliveryPostCode' size='5' type='text'></div></div><br><br>", "Quote Shipping", "Cancel", 266 function() { 267 268 var deliveryCountry = $("#quoteDeliveryCountry").val(); 269 var deliveryPostCode = $("#quoteDeliveryPostCode").val(); 270 271 // console.log("Quoting for ", deliveryCountry, deliveryPostCode); 272 273 app.quoteShipping(el, deliveryCountry, deliveryPostCode, function(err, data) { 274 if (err) { 275 alert(err); 276 } else { 277 if (data) { 278 var output = "<table border='0'><tr><th>Shipping Option</th><th>Price</th></tr>"; 279 for (var i = 0; i < data.items.length; i++) { 280 var item = data.items[i]; 281 // if (item.priceCurr == m.ls.currency) { 282 output += "<tr><td>" + item.name + "</td><td>" + item.displayPrice + "</td></tr>"; 283 //} 284 } 285 286 output += "</table>"; 287 setTimeout(function() { 288 app.confirm("Shipping Options Available", output, "", "Close", function() { 289 // all done; 290 }); 291 }, 1000); 292 } 293 } 294 }); 295 }); 296 }); 297 298 $(".fnc-update-shipping").off().on("change", function(e) { 299 var el = $(this); 300 if (app.refreshShippingTimeout) { 301 clearTimeout(app.refreshShippingTimeout); 302 } 303 304 app.refreshShippingTimeout = setTimeout(function() { 305 app.updateShipping(el); 306 }, 500); 307 }); 308 309 310 311 $('.fnc-cart-checkout').off("click").on("click", function(ev) { 312 $('.fnc-cart-checkout').prop('disabled', true); 313 314 if (profile.isLoggedIn()) { 315 app.applyProfileDetailsToSale('shopping-cart-details', function() { 316 $("body").fadeOut(1000); 317 window.location = "/cart/basket?_dc=" + Math.random(); 318 $('.fnc-cart-checkout').prop('disabled', false); 319 }); 320 } else { 321 window.location = "/cart/basket?_dc=" + Math.random(); 322 } 323 }); 324 325 $("#shopping-cart-details").off("submit").on("submit", function(e) { 326 e.preventDefault(); 327 return false; 328 }); 329 330 $(".fnc-complete-checkout").off("click").on("click", function(e) { 331 // validate sale 332 // debugger; 333 $('.fnc-complete-checkout').prop('disabled', true); 334 335 if (window.cartBypassAddressChecks) { 336 // make sure details are set on forms 337 app.applyProfileDetailsToSale('shopping-cart-details', function() { 338 // hide checkbox, show spinner 339 $('.fnc-complete-checkout i').css("display", "none"); 340 $('.fnc-complete-checkout .btn-spinner').css("display", "inline-block"); 341 // debugger; 342 if (app.validateCartForm("shopping-cart-details")) { 343 app.validateShipping(function(err, count) { 344 if (err) { 345 app.notify(err, "error"); 346 } else { 347 app.submitSale("shopping-cart-details"); 348 } 349 }); 350 } else { 351 setTimeout(function() { 352 $('.fnc-complete-checkout').prop('disabled', false); 353 $('.fnc-complete-checkout .btn-spinner').css("display", "none"); 354 $('.fnc-complete-checkout i').css("display", "inline-block"); 355 }, 1000); 356 } 357 }); 358 } else { 359 // hide checkbox, show spinner 360 $('.fnc-complete-checkout i').css("display", "none"); 361 $('.fnc-complete-checkout .btn-spinner').css("display", "inline-block"); 362
363 if (app.validateCartForm("shopping-cart-details")) { 364 app.validateShipping(function(err, count) { 365 if (err) { 366 app.notify(err, "error"); 367 } else { 368 app.submitSale("shopping-cart-details"); 369 } 370 }); 371 } else { 372 setTimeout(function() { 373 $('.fnc-complete-checkout').prop('disabled', false); 374 $('.fnc-complete-checkout .btn-spinner').css("display", "none"); 375 $('.fnc-complete-checkout i').css("display", "inline-block"); 376 }, 1000); 377 } 378 } 379 }); 380 381 $(".fnc-continue-shopping").off("click").on("click", function(e) { 382 var item=$(this); 383 if (item.attr("data-next-action")) { 384 window.location = item.attr("data-next-action"); 385 } else { 386 window.history.back(); 387 } 388 }); 389 390 391 $(".fnc-apply-discount-code").off("click").on("click", function(e) { 392 m.applyDiscountCode($("#cart-discount-code").val()); 393 }); 394 395 $('.fnc-cart-clear').off("click").on("click", function(ev) { 396 $('#dialog-clear-cart').modal('show'); 397 $('.fnc-cart-clear-confirm').off().on("click", function(ev) { 398 app.cartClear(); 399 $('#dialog-clear-cart').modal('hide'); 400 }); 401 }); 402 403 if ($.TouchSpin) { 404 $(".cart-spinner").TouchSpin({ 405 verticalbuttons: true, 406 verticalupclass: 'glyphicon glyphicon-plus', 407 verticaldownclass: 'glyphicon glyphicon-minus' 408 }); 409 } 410 411 $(".cart-spinner").on("change", function(e) { 412 var salelnGuid = $($(this).parents(".cart-saleline")[0]).data('saleln-guid'); 413 var input = $("input[name='saleln-qty-" + salelnGuid + "']"); 414 app.updateSaleLine(salelnGuid, parseFloat(input.val())); 415 e.preventDefault(); 416 return false; 417 }); 418 419 var cartQtyChangeTimeout = null; 420 $(".cart-quantity").on("change", function(e) { 421 var salelnGuid = $($(this).parents(".cart-saleline")[0]).data('saleln-guid'); 422 var input = $("input[name='saleln-qty-" + salelnGuid + "']"); 423 424 if (cartQtyChangeTimeout) { 425 clearTimeout(cartQtyChangeTimeout); 426 } 427 cartQtyChangeTimeout = setTimeout(function() { 428 app.updateSaleLine(salelnGuid, Math.abs(parseFloat(input.val()))); 429 clearTimeout(cartQtyChangeTimeout); 430 cartQtyChangeTimeout = null; 431 }, 500); 432 }); 433 434 $('.cart-quantity').off("keyup").on("keyup", function(ev) { 435 if (ev.keyCode == 13) { 436 var salelnGuid = $($(this).parents(".cart-saleline")[0]).data('saleln-guid'); 437 var input = $("input[name='saleln-qty-" + salelnGuid + "']"); 438 app.updateSaleLine(salelnGuid, Math.abs(parseFloat(input.val()))); 439 ev.preventDefault(); 440 return false; 441 } 442 }); 443 444 $(".fnc-ship-to-billing").off().on("click", function() { 445 app.setShipToAddressFromBilling(); 446 }); 447 448 $(".fnc-update-shipping-methods").on("input", function(e) { 449 var el = $(this); 450 //console.log("fnc-update-shipping-methods"); 451 // console.log("fnc-update-shipping-methods", el); 452 //console.log(el[0].id + " input"); 453 if (el[0].id == "deliveryPostcodePicker") { 454 // console.log("top", el); 455 $("#deliveryPostcode").val(el.val()); 456 } 457 //} else { 458 // fill in bottom value 459 // 460 // } 461 app.cartNeedsRefresh(); 462 }); 463 464 $('.fnc-update-shipping-country').on('change', function() { 465 var el = $(this); 466 //console.log("fnc-update-shipping-country", el); 467 468 m.ls.deliveryCountry = el.val(); 469 //console.log("fnc-update-shipping-country deliveryCountry", m.ls.deliveryCountry); 470 if (m.ls.deliveryCountry) { 471 $('#deliveryCountry option[value=' + m.ls.deliveryCountry + ']').attr('selected', 'selected'); 472 } 473 app.selectPickerRefresh(); 474 app.cartNeedsRefresh(); 475 }); 476 477 $(".fnc-set-pickup-location").on("change", function(cmb) { 478 //console.log("fnc-set-pickup-location"); 479 app.cartNeedsRefresh();
480 }); 481 482 $("#cart-main").css("opacity", 1); 483 484 if (app.pickupList) { 485 if (app.pickupList.length == 0) { 486 app.loadPickupSelectLists(); 487 } 488 } 489 490 // delivery method switch 491 $('#cart-address-panel').off().on('show.bs.collapse', function(e) { 492 switch (e.target.id) { 493 case "cart-address-delivery": 494 var options = document.querySelectorAll('#cmbPickupLocation option'); 495 for (var i = 0, l = options.length; i < l; i++) { 496 if (i == 0) options[i].selected = true; 497 else options[i].selected = false; 498 } 499 app.deliveryMode = "post"; 500 app.cartNeedsRefresh(); 501 break; 502 case "cart-address-pickup": 503 app.deliveryMode = "pickup"; 504 app.cartNeedsRefresh(); 505 break; 506 } 507 }); 508 509 // payment type switch 510 // $('.payment-panel').on('shown.bs.collapse', function (e) { 511 // $("#pay_type").val(e.currentTarget.id); 512 // console.log("Paytype: " + e.currentTarget.id); 513 // }); 514 515 try { 516 $('.cart-user-options .collapse').collapse(); 517 } 518 catch (e) { 519 520 } 521 522 $(".fnc-cart-delete-line").off("click").on("click", function(e) { 523 if (+(e.screenX || 0) > 0) { // weird hack as Enter in discount code field triggers this 524 app.removeFromCart($(this).parents(".cart-saleline").data("saleln-guid")); 525 } 526 }); 527 528 $('#cart-discount-code').off("keyup").on("keyup", function(ev) { 529 if (ev.keyCode == 13) { 530 m.applyDiscountCode($("#cart-discount-code").val()); 531 ev.preventDefault(); 532 return false; 533 } 534 }); 535 536 537}; 538 539app.updateShipping = function(el) { 540 if(window.disableLegacyCart){ 541 return; 542 } 543 var m = this; 544 //console.log("fnc-update-shipping"); 545 546 app.lastShipmentId = 0; 547 var sel = el.find("option:selected"); 548 if (sel.length > 0) { 549 var opt = $(sel[0]); 550 if (opt.attr("data-spg-id")) { 551 var shipment = { 552 shpId: opt.attr("data-shp-id"), 553 spgId: opt.attr("data-spg-id"), 554 flags: opt.attr("data-flags") 555 } 556 // console.log("Update Shipment", shipment); 557 // if (app.debugMode) alert("Shp shipment:" + opt.attr("data-spg-id") + " : " + JSON.stringify(shipment)); 558 var options = { 559 startkey: "shp_", 560 endkey: "shp_\uffff", 561 include_docs: true 562 }; 563 // get all shipment records 564 m.db.allDocs(options, function(err, shipments) { 565 if (!err) { 566 // loop through all shipments and set selected flag on item per group 567 for (var j = 0; j < shipments.rows.length; j++) { 568 var shiprec = shipments.rows[j].doc; 569 //console.log("Compare ", shiprec, shipment); 570 if (shiprec.spgId == shipment.spgId) { 571 shiprec.shpId = shipment.shpId; 572 m.db.put(shiprec, function callback(err, result) { 573 if (err) { 574 console.log("Could not update shipment line", err); 575 } else { 576 app.lastShipmentId = shipment.shpId; 577 //console.log("app.lastShipmentId = " + app.lastShipmentId); 578 } 579 //console.log("Updated Shipping line", result); 580 581 app.calculateTotals(); 582 }); 583 } 584 } 585 } 586 }); 587 } else { 588 //if (app.debugMode) alert("Shp 0:" + opt.attr("data-spg-id")); 589 app.calculateTotals(); 590 } 591 } 592} 593 594app.addItemToCart = function(item, cb) { 595 var m = this; 596 597 var cartBtn = $('.shopping-cart'); 598 for (var i = 0; i < cartBtn.length; i++) { 599 if ($($('.shopping-cart')[i]).is(":visible")) { 600 cartBtn = $($('.shopping-cart')[i]); 601 break; 602 } 603 } 604 605 if (cartBtn.length == 0) { 606 // look for alternate cart buttons 607 cartBtn = $('.cart-status'); 608 for (var i = 0; i < cartBtn.length; i++) { 609 if ($($('.cart-status')[i]).is(":visible")) { 610 cartBtn = $($('.cart-status')[i]); 611 break; 612 } 613 } 614 } 615 616 m.addToCart(item, function(err, showAnimation) { 617 if (err) { 618 console.log("Add to cart error:", err); 619 } else { 620 if (cartBtn) { 621 if (!cartBtn.offset()) { 622 cartBtn = null; 623 } 624 } 625 626 if (showAnimation && cartBtn) { 627 var imgtodrag = item.parents('.product-item').find("img.product-picture").eq(0); 628 629 if (imgtodrag.length == 0) { 630 // themler image? 631 imgtodrag = item.parents('.product-item').find(".product-picture").find("img").eq(0); 632 } 633 if (imgtodrag) { 634 if (imgtodrag.offset()) { 635 var imgclone = imgtodrag.clone() 636 .offset({ 637 top: imgtodrag.offset().top, 638 left: imgtodrag.offset().left 639 }) 640 .css({ 641 'opacity': '0.8', 642 'position': 'absolute', 643 'max-height': '180px', 644 'max-width': '160px', 645 'z-index': '100' 646 }) 647 .appendTo($('body')) 648 .animate({ 649 'top': cartBtn.offset().top - 20, 650 'left': cartBtn.offset().left - 20, 651 'max-height': '50px', 652 'max-width': '50px', 653 }, 150, 'easeInOutExpo'); 654 655 setTimeout(function() { 656 cartBtn.fadeIn(100).fadeOut(100).fadeIn(100).fadeOut(100).fadeIn(100); 657 }, 200); 658 659 imgclone.animate({ 660 'opacity': '0.0' 661 }, 200, function() { 662 $(this).detach(); 663 664 if (cb) cb(); 665 }); 666 } else { 667 if (cb) cb(); 668 } 669 } 670 } else { 671 if (cb) cb(); 672 } 673 } 674 }); 675} 676 677app.initCart = function() { 678 if(window.disableLegacyCart){ 679 return; 680 } 681 var m = this; 682 if (!m.cartMode) { // always init the dropdown, basket init triggered separately 683 m.cartMode = "compactdropdown"; 684 } 685 app.loadCountryLists();
686 687 688 $('.fnc-add-to-cart').off('click').on('click', function() { 689 var item = $(this); 690 691 var cartBtn = $('.shopping-cart'); 692 for (var i = 0; i < cartBtn.length; i++) { 693 if ($($('.shopping-cart')[i]).is(":visible")) { 694 cartBtn = $($('.shopping-cart')[i]); 695 break; 696 } 697 } 698 699 if (item.attr("data-modifier-count")) { 700 // add a list of modifiers one at a time; 701 var allItems = []; 702 //debugger; 703 704 // var product = app.resolveItemToSaleline(item); 705 var area = $(item.parents('.product-item')); 706 707 var modifiers = $(area.find(".product-modifier")); 708 709 modifiers.find("input.product-qty").each(function(index) { 710 var item = $(this); 711 if (item) { 712 //console.log("product-qty: " + index + ": " + item.val()) 713 if (item.val() > 0) { 714 allItems.push(item); 715 } 716 } 717 }); 718 719 //console.log("2 Mods to add", allItems); 720 if (allItems.length > 0) { 721 var numItems = allItems.length; 722 var currentItem = 0; 723 724 var nextItem = function() { 725 if (numItems > currentItem) { 726 var item = allItems[currentItem++]; 727 app.addItemToCart(item, nextItem); 728 } else { 729 // all done 730 for (var i = 0; i < allItems.length; i++) { 731 allItems[i].val(0); 732 } 733 $.magnificPopup.open({ 734 items: { 735 src: "<div class='white-popup-block' id='dlg-thanks'><h1>Items have been added to your cart</h1><br><br><p><button class='btn btn-primary fnc-continue-shopping'>Continue Shopping</button>" + 736 " <button class='btn btn-success fnc-cart-checkout pull-right'>Go to Checkout</button></p></div>", 737 type: 'inline' 738 }, 739 callbacks: { 740 open: function() { 741 app.registerCartEvents(); 742 } 743 } 744 }); 745 } 746 } 747 nextItem(); 748 } 749 // console.log("Add Modifiers", allItems); 750 } else { 751 752 if (item.attr("data-list-container")) { 753 // add a list of items one at a time; 754 var allItems = []; 755 756 // .in is the currently expanded list 757 $(".in #" + item.attr("data-list-container") + " input.product-qty").each(function(index) { 758 var itemQty = $(this); 759 if (itemQty) { 760 //console.log("input.product-qty: " + index + ": " + item.val()) 761 if (itemQty.val() > 0) { 762 allItems.push(itemQty); 763 } 764 } 765 }); 766 if (allItems.length > 0) { 767 var numItems = allItems.length; 768 var currentItem = 0; 769 770 var nextItem = function() { 771 if (numItems > currentItem) { 772 app.addItemToCart(allItems[currentItem++], nextItem); 773 } else { 774 // all done 775 for (var i = 0; i < allItems.length; i++) { 776 allItems[i].val(0); 777 } 778 $.magnificPopup.open({ 779 items: { 780 src: "<div class='white-popup-block' id='dlg-thanks'><h1>Items have been added to your cart</h1><br><br><p><button class='btn btn-primary fnc-continue-shopping' data-next-action='" + item.attr("data-next-action") + "'>Continue Shopping</button>" + 781 " <button class='btn btn-success fnc-cart-checkout pull-right'>Go to Checkout</button></p></div>", 782 type: 'inline' 783 }, 784 callbacks: { 785 open: function() { 786 app.registerCartEvents(); 787 } 788 } 789 }); 790 } 791 } 792 nextItem(); 793 } 794 //console.log("Add List", allItems); 795 } else { 796 // add single item 797 app.addItemToCart(item, function() { 798 try { 799 $.magnificPopup.close(); 800 } catch (ex) {} 801 }); 802 } 803 } 804 }); 805 806 m.sessionDbName = 'session_' + app.ls.sessionGuid; 807 if (typeof PouchDB !== 'undefined') { 808 m.db = new PouchDB(m.sessionDbName, { 809 auto_compaction: true 810 }); 811 m.db.setMaxListeners(20); 812 setTimeout(function() { 813 m.db.info(function(err, info) { 814 if (!err) { 815 m.sync(); 816 m.db.changes({ 817 since: info.update_seq, 818 continuous: false, 819 onChange: m.refreshCart 820 }); 821 m.refreshCart(); 822 } 823 }); 824 }, 500); 825 } 826}; 827 828app.setShipToAddressFromBilling = function() { 829 var form = document.querySelector('#shopping-cart-details'); 830 var addressForm = corridor(form); 831 //console.log("setShipToAddressFromBilling", addressForm) 832 if ($("#chk-ship-to-billing").attr("checked")) { 833 addressForm.deliveryFirstname = addressForm.firstname; 834 addressForm.deliveryLastname = addressForm.lastname; 835 addressForm.deliveryEmail = addressForm.email; 836 addressForm.deliveryCompany = addressForm.company; 837 addressForm.deliveryPhone = addressForm.phone; 838 addressForm.deliveryMobile = addressForm.mobile; 839 addressForm.deliveryAddress1 = addressForm.address1; 840 addressForm.deliveryAddress2 = addressForm.address2; 841 addressForm.deliveryCity = addressForm.city; 842 addressForm.deliveryState = addressForm.state; 843 addressForm.deliveryPostcode = addressForm.postcode; 844 addressForm.deliveryCountry = addressForm.country; 845 } else { 846 addressForm.deliveryFirstname = ""; 847 addressForm.deliveryLastname = ""; 848 addressForm.deliveryEmail = ""; 849 addressForm.deliveryPhone = ""; 850 addressForm.deliveryMobile = ""; 851 addressForm.deliveryCompany = ""; 852 addressForm.deliveryAddress1 = ""; 853 addressForm.deliveryAddress2 = ""; 854 addressForm.deliveryCity = ""; 855 addressForm.deliveryState = ""; 856 addressForm.deliveryPostcode = ""; 857 addressForm.deliveryCountry = ""; 858 } 859 addressForm.deliveryCountry = addressForm.deliveryCountry.trim(); 860 //console.log("setShipToAddressFromBilling setting", addressForm)
861 corridor(form, addressForm); 862 app.selectPickerRefresh(); 863 app.cartNeedsRefresh(); 864}; 865 866 867app.validateCartForm = function(formId) { 868 var m = this; 869 //console.log("validateCartForm: " + formId); 870 //debugger; 871 var cartForm = document.querySelector('#' + formId); 872 $("#" + formId + " .error").removeClass("error"); 873 var cf = null; 874 var isValid = true; 875 var invalidFields = []; 876 877 var invalidCartField = function(formId, name, note) { 878 var fld = $("#" + formId + " input[name='" + name + "']"); 879 if (fld) { 880 fld.addClass("error"); 881 fld.attr("title", note); 882 isValid = false; 883 invalidFields.push({name: name, note: note}); 884 } else { 885 fld = $("#" + formId + " select[name='" + name + "']"); 886 if (fld) { 887 fld.addClass("error"); 888 fld.attr("title", note); 889 isValid = false; 890 invalidFields.push({name: name, note: note}); 891 } 892 } 893 }; 894 895 var validateEmail = function(value) { 896 var input = document.createElement('input'); 897 898 input.type = 'email'; 899 input.value = value; 900 901 return typeof input.checkValidity == 'function' ? input.checkValidity() : /\S+@\S+\.\S+/.test(value); 902 }; 903 904 905 if (cartForm) { 906 cf = corridor(cartForm); 907 // check billing address 908 //console.log(JSON.stringify(cf)); 909 910 911 if (cf.pay_type == "") { 912 app.notify("Please select a payment type!", "error"); 913 isValid = false; 914 } 915 916 917 if (window.cartBypassAddressChecks) { 918 919 if (cf.requiredDate) { 920 //.log("cf.requiredDate", cf.requiredDate); 921 } 922 923 if (cf.custIdRequired == "1") { 924 //console.log("Override valid!"); 925 if (app.ls.profile) { 926 cf.custId = app.ls.profile.custId; 927 928 // if(window.parent){ 929 // if(window.parent.cmsConfig){ 930 // cf.custId = window.parent.cmsConfig.custId; 931 // } 932 //} 933 934 // cust ID must be set for non-verified sales 935 if (!(cf.custId > 0)) { 936 app.notify("There is a problem with your login. Please login again and re-try.", "error"); 937 isValid = false; 938 } 939 } else { 940 app.notify("You must be logged in to checkout. Please login again and re-try.", "error"); 941 isValid = false; 942 } 943 } 944 } else { 945 946 947 if (cf.firstname.length < 2) 948 invalidCartField(formId, "firstname", "Please enter your full first name."); 949 950 if (cf.lastname.length < 2) 951 invalidCartField(formId, "lastname", "Please enter your full last name."); 952 953 if (!validateEmail(cf.email) || cf.email.length < 3) 954 invalidCartField(formId, "email", "Please enter a valid email address."); 955 956 if (cf.address1.length < 2) 957 invalidCartField(formId, "address1", "Please enter an address."); 958 959 if (cf.phone.length < 2) 960 invalidCartField(formId, "phone", "Please enter a phone number."); 961 962 if (cf.city.length < 2) 963 invalidCartField(formId, "city", "Please enter a city name."); 964 965 if (cf.postcode.length < 4) 966 invalidCartField(formId, "postcode", "Please enter a valid post code."); 967 968 if (cf.country.length < 2) 969 invalidCartField(formId, "country", "Please choose a valid country."); 970 971 if (app.deliveryMode != "post") { 972 // pickup mode 973 var found = false; 974 for (var i = 0; i < app.pickupList.length; i++) { 975 if (app.pickupList[i].guid == cf.pickupLocation) { 976 found = true; 977 } 978 } 979 if (!found) { 980 invalidCartField(formId, "pickupLocation", "Please choose a valid pickup location."); 981 isValid = false; 982 } 983 } else { 984 // delivery mode 985 if (cf.deliveryFirstname.length < 2) 986 invalidCartField(formId, "deliveryFirstname", "Please enter your full first name."); 987 988 if (cf.deliveryLastname.length < 2) 989 invalidCartField(formId, "deliveryLastname", "Please enter your full last name."); 990 991 if (!validateEmail(cf.deliveryEmail) || cf.deliveryEmail.length < 3) 992 invalidCartField(formId, "deliveryEmail", "Please enter a valid email address."); 993 994 if (cf.deliveryAddress1.length < 2) 995 invalidCartField(formId, "deliveryAddress1", "Please enter an address."); 996 997 if (cf.deliveryAddress1.length > 50) 998 invalidCartField(formId, "deliveryAddress1", "Address is too long."); 999 1000 if (cf.deliveryAddress2.length > 50) 1001 invalidCartField(formId, "deliveryAddress2", "Address is too long."); 1002 1003 if (cf.deliveryCity.length < 2) 1004 invalidCartField(formId, "deliveryCity", "Please enter a city name."); 1005 1006 if (cf.deliveryPhone.length < 2) 1007 invalidCartField(formId, "deliveryPhone", "Please enter a phone number."); 1008 1009 if (cf.deliveryPostcode.length < 4) 1010 invalidCartField(formId, "deliveryPostcode", "Please enter a valid post code."); 1011 1012 if (cf.deliveryCountry.length < 2) 1013 invalidCartField(formId, "deliveryCountry", "Please choose a valid country."); 1014 1015 } 1016 1017 // also create an account 1018 if (cf.register) { 1019 if (String(cf.password).length > 4) { 1020 if (cf.password != cf.password2) { 1021 invalidCartField(formId, "password", "The two password fields must match."); 1022 invalidCartField(formId, "password2", "The two password fields must match."); 1023 } 1024 } else { 1025 invalidCartField(formId, "password", "The password must be longer than 4 letters."); 1026 } 1027 } 1028 if (cartOptions.cartMinimumOrderAmount > 0) { 1029 var allowMinimumBypass = false; 1030 // CUST_CANBUYANYQTY = 131072 1031 if ((app.ls.profile.flags & 131072) == 131072) { 1032 allowMinimumBypass = true; 1033 } 1034 // console.log("cartOptions.cartMinimumOrderAmount",cartOptions.cartMinimumOrderAmount,allowMinimumBypass,app.ls.profile.flags); 1035 1036 if (!allowMinimumBypass) { 1037 if (cartOptions.cartMinimumOrderAmount > (app.ls.total.due / 10000).toFixed(2)) { 1038 if (!cartOptions.userHasSeenMinOrderWarning) { 1039 $.magnificPopup.open({ 1040 items: { 1041 src: "#minimum-order-popup", 1042 type: 'inline' 1043 } 1044 }); 1045 cartOptions.userHasSeenMinOrderWarning = true; 1046 isValid = false; 1047 } 1048 1049 // hard stop here if the limit is enforced 1050 if (cartOptions.cartMinimumOrderEnforceMinimum) { 1051 isValid = false; 1052 } 1053 } 1054 } 1055 } 1056 } 1057 1058 if (!isValid) { 1059 submitClientError({"cartErrors": JSON.stringify(invalidFields)}); 1060 } 1061 1062 return isValid; 1063 } 1064 return false; 1065} 1066 1067app.updateSaleLine = function(salelnGuid, qty, updateObj) { 1068 var m = this; 1069 if (qty <= 0) { 1070 m.removeFromCart(salelnGuid); 1071 } else { 1072 m.findSaleLine({ 1073 salelnGuid: salelnGuid 1074 }, function(currline) { 1075 if (qty) { 1076 currline.qty = Math.abs(parseFloat(qty)); 1077 } 1078 if (updateObj) { 1079 if (updateObj.notes) { 1080 currline.notes = updateObj.notes; 1081 } else { 1082 //currline.notes = ""; 1083 } 1084 currline.price = updateObj.price; 1085 currline.discount = updateObj.discount; 1086 1087 if (m.ls.currency != updateObj.priceCurr) { 1088 // currency has changed on the server, update the current state of client 1089 m.changeCurrency(updateObj.priceCurr); 1090 } 1091 currline.priceCurr = updateObj.priceCurr; 1092 } 1093 if (currline) { 1094 currline.totalAmount = currline.qty * currline.price; 1095 currline.totalTax = ed.tax; 1096 currline.totalDiscounts = currline.qty * currline.discount; 1097 app.db.put(currline, {}, function callback(err, result) { 1098 if (!err) { 1099 app.sync(); 1100 app.cartNeedsRefresh() 1101 } else { 1102 console.log(err); 1103 } 1104 }); 1105 } 1106 }); 1107 } 1108} 1109 1110app.removeFromCart = function(salelnGuid) { 1111 var m = this; 1112 1113 // "_id": "saleline_" + m.ls.saleGuid + "_" + newSaleLnGuid 1114 var options = { 1115 startkey: "saleline_" + m.ls.saleGuid + "_" + salelnGuid, 1116 endkey: "saleline_" + m.ls.saleGuid + "_" + salelnGuid + "\uffff", 1117 include_docs: true 1118 }; 1119 1120 m.db.allDocs(options, function(err, doc) { 1121 if (!err) { 1122 if (doc.total_rows >= 0) { 1123 if (doc.rows[0]) { 1124 m.db.remove(doc.rows[0].doc, function(err, item) { 1125 m.sync(); 1126 app.cartNeedsRefresh();
1127 m.notify("Removed " + doc.rows[0].doc.name, "info"); 1128 }); 1129 } 1130 } else { 1131 m.refreshCart(); 1132 } 1133 } 1134 }); 1135} 1136 1137app.addToCart = function(domEl, cb) { 1138 var m = this; 1139 var currline = null; 1140 var product = null; 1141 1142 var itemCount = 0; 1143 var subTotal = 0; 1144 1145 app.ls.cartItemCount = 1; 1146 product = m.resolveItemToSaleline(domEl); 1147 1148 product.checkoutRedirect = $(domEl).attr("data-checkout-redirect"); 1149 1150 // check that the sale is not in use Already 1151 m.checkSaleGuid(function() { 1152 console.log("addToCart", product); 1153 m.findSaleLine(product, function(currline) { 1154 if (product.unit) { 1155 switch (product.unit.toLowerCase()) { 1156 case "kg": 1157 case "g": 1158 // don't round qty for these units. 1159 break; 1160 default: 1161 product.qty = Math.ceil(product.qty); 1162 break; 1163 } 1164 } 1165 // console.log(product, currline); 1166 if (!currline) { 1167 // new line 1168 var newSaleLnGuid = app.g(0); 1169 // debugger; 1170 currline = { 1171 "_id": "saleline_" + m.ls.saleGuid + "_" + newSaleLnGuid, 1172 "contentType": "saleline", 1173 "url": window.location.hostname.replace("www.", ""), 1174 "saleGuid": m.ls.saleGuid, 1175 "salelnGuid": newSaleLnGuid, 1176 "prdId": product.prdId, 1177 "pmmId": product.pmmId, 1178 "pmiId": product.pmiId, 1179 "primaryGrpId": product.primaryGrpId, 1180 "picId": product.picId, 1181 "picFileName": product.picFileName, 1182 "schema": product.schema, 1183 "metadata": product.metadata, 1184 1185 "shpId": product.shpId, 1186 "spgId": product.spgId, 1187 "locId": product.locId, 1188 "outletId": product.outletId, 1189 1190 "code": product.code, 1191 "name": product.name, 1192 "type": product.type, // saleln_type 1193 "itemType": +(product.itemType || 0), // prd_type 1194 "description": product.description, 1195 "notes": product.notes, 1196 "flags": product.flags, 1197 1198 "qty": Math.abs(parseFloat(product.qty)), 1199 "unit": product.unit, 1200 "unitQty": product.unitQty, 1201 "outerQty": product.outerQty, 1202 "moq": product.moq, 1203 "unitWeight": product.unitWeight, 1204 "weight": product.weight * product.qty, 1205 1206 "loyaltyCost": 0, 1207 "loyaltyReward": 0, 1208 "price": product.price, 1209 "priceCurr": product.priceCurr, 1210 "priceTax": product.priceTax, 1211 "rrp": product.rrp, 1212 "discount": product.discount, 1213 "isPriceOnApplication": 0, 1214 "outerHeight": product.outerHeight || 0, 1215 "outerWidth": product.outerWidth || 0, 1216 "outerDepth": product.outerDepth || 0, 1217 "totalShipping": 0, 1218 "totalAmount": product.qty * product.price, 1219 "totalTax": parseInt(((product.qty * product.price) * (1 + (ed.tax / 100))) - (product.qty * product.price)), 1220 "totalDiscounts": product.qty * product.discount, 1221 "svcId": product.svcId 1222 } 1223 } else { 1224 currline.qty += parseFloat(product.qty); 1225 currline.weight = currline.qty * currline.unitWeight; 1226 } 1227 currline.totalAmount = currline.qty * product.price; 1228 currline.totalTax = ((currline.qty * product.price) * (1 + (ed.tax / 100))) - (currline.qty * product.price); 1229 currline.totalDiscounts = currline.qty * product.discount; 1230 currline.comment = ""; 1231 1232 var options = []; 1233 var optionError = false; 1234 $(".package-option").each(function(e) { 1235 if ($(this).attr("data-pmm-id") == 0) { 1236 $(this).css("border", "1px solid #f00"); 1237 optionError = true; 1238 } else { 1239 $(this).css("border", "0px solid #f00"); 1240 options.push({ 1241 prdId: $(this).attr("data-prd-id"), 1242 pmmId: $(this).attr("data-pmm-id") 1243 }); 1244 currline.comment += $(this).attr("data-pmm-code") + " "; 1245 } 1246 1247 //console.log("Options",$(this).attr("data-prd-id"),$(this).attr("data-pmm-id"),$(this).attr("data-prd-code")); 1248 }); 1249 1250 if (!optionError) { 1251 // debugger; 1252 if (currline.itemType !== Constants.ProductTypes.PRDTYPE_SERVICE && currline.itemType !== Constants.ProductTypes.PRDTYPE_FEATURE && currline.itemType !== Constants.ProductTypes.PRDTYPE_VOUCHER) { 1253 if(window.disableLegacyCart && currline.itemType === Constants.ProductTypes.PRDTYPE_PACKAGE){ 1254 // create child salelines 1255 var childLines = generatePackageSaleLines(currline, product); 1256 if(childLines.length > 0){ 1257 m.db.bulkDocs(childLines, function callback(err, result) { 1258 1259 }); 1260 } 1261 1262 }else{ 1263 currline.metadata = JSON.stringify(options); 1264 } 1265 } 1266 1267 m.db.put(currline, function callback(err, result) { 1268 if (!err) { 1269 if (!app.suppressCartNotify) { 1270 m.notify("Added " + product.qty + " x " + product.name); 1271 } 1272 if (typeof fbq !== 'undefined') { 1273 fbq('track', 'AddToCart', { 1274 content_name: product.name, 1275 content_category: product.primaryGrpId, 1276 content_ids: [product.code], 1277 content_type: 'product', 1278 value: product.price / 10000, 1279 currency: product.priceCurr 1280 }); 1281 } 1282 if (typeof gtag !== 'undefined' ) { 1283 gtag('event', 'add_to_cart', { 1284 "items": [ 1285 { 1286 "id": product.code, 1287 "name": product.description, 1288 "category": product.primaryGrpId, 1289 "list_position": 1, 1290 "quantity": product.qty, 1291 "price": product.price / 10000 1292 } 1293 ] 1294 }); 1295 } 1296 if (typeof window._paq !== 'undefined') { 1297 window._paq.push(['addEcommerceItem', 1298 product.code, 1299 product.description, 1300 "", 1301 product.price / 10000, 1302 product.qty 1303 ]); 1304 } 1305 app.cartNeedsRefresh(function() { 1306 m.sync(); 1307 }); 1308 $("body").trigger("addToCart", product); 1309 1310 if (product.checkoutRedirect == 1) { 1311 setTimeout(function() { 1312 window.location = '/cart/basket'; 1313 },200);
1314 } 1315 1316 if (cb) cb(null, true); 1317 } else { 1318 //console.log(err); 1319 if (cb) cb("Could not update sale line", false); 1320 } 1321 }); 1322 1323 if (!m.cartTimer) { 1324 m.cartTimer = setTimeout(function() { 1325 m.setLocalState(app.ls); 1326 m.cartTimer = null; 1327 }, 200); 1328 } 1329 } else { 1330 app.alert("Package Options Error", "Please choose all your package options using the dropdown menus."); 1331 if (cb) cb("Please choose all your package options using the dropdown menus", false); 1332 } 1333 }); 1334 }); 1335}; 1336 1337app.cartClear = function(hideConfirm, cb) { 1338 var m = this; 1339 var options = { 1340 startkey: "saleline_" + m.ls.saleGuid, 1341 endkey: "saleline_" + m.ls.saleGuid + "\uffff", 1342 include_docs: true 1343 }; 1344 var toDelete = []; 1345 m.db.allDocs(options, function(err, doc) { 1346 if (!err) { 1347 if (doc.rows.length >= 0) { 1348 for (var i = 0; i < doc.rows.length; i++) { 1349 if (doc.rows[i].doc.contentType == "saleline") { 1350 doc.rows[i].doc._deleted = true; 1351 toDelete.push(doc.rows[i].doc); 1352 } 1353 } 1354 m.db.bulkDocs(toDelete).then(function(result) { 1355 m.sync(); 1356 app.resetTotals(); 1357 app.cartNeedsRefresh(); 1358 if (!hideConfirm) { 1359 m.notify("All items have been removed from your cart", "info"); 1360 } 1361 if (cb) cb(); 1362 }) 1363 } else { 1364 if (cb) cb(); 1365 } 1366 } else { 1367 if (cb) cb(); 1368 } 1369 }) 1370}; 1371 1372app.submitSale = function(formId) { 1373 var m = this; 1374 var input = document.querySelector('#' + formId); 1375 var saleForm = corridor(input); 1376 1377 // create an account? 1378 if (saleForm.register) { 1379 if (String(saleForm.password).length > 4) { 1380 profile.registerProfile(saleForm, function(err, result) { 1381 if (err) { 1382 app.notify(err, "error"); 1383 } 1384 if (result) { 1385 if (result.success) { 1386 app.notify("Your account was created.", "info"); 1387 delete saleForm.register; 1388 app.sendSale(saleForm); 1389 } else { 1390 app.notify(result.message, "error"); 1391 } 1392 } 1393 }); 1394 } else { 1395 app.notify("Password is too short", "error"); 1396 } 1397 } else { 1398 app.sendSale(saleForm); 1399 } 1400}; 1401 1402app.removeSaleDocs = function(cb) { 1403 var m = this; 1404 1405 var saleOptions = { 1406 startkey: "sale_" + m.ls.saleGuid, 1407 endkey: "sale_" + m.ls.saleGuid + "\uffff", 1408 include_docs: true 1409 }; 1410 var saleLineOptions = { 1411 startkey: "saleline_" + m.ls.saleGuid, 1412 endkey: "saleline_" + m.ls.saleGuid + "\uffff", 1413 include_docs: true 1414 }; 1415 1416 1417 m.db.allDocs(saleOptions, function(err, saleObj) { 1418 if (!err) { 1419 var toDelete = []; 1420 1421 m.db.allDocs(saleLineOptions, function(err, doc) { 1422 if (doc.rows.length >= 0) { 1423 1424 for (var i = 0; i < doc.rows.length; i++) { 1425 if (doc.rows[i].doc.contentType == "saleline") { 1426 doc.rows[i].doc._deleted = true; 1427 toDelete.push(doc.rows[i].doc); 1428 } 1429 } 1430 } 1431 1432 if (saleObj.rows.length >= 0) { 1433 for (var i = 0; i < saleObj.rows.length; i++) { 1434 if (saleObj.rows[i].doc.contentType == "sale") { 1435 saleObj.rows[i].doc._deleted = true; 1436 toDelete.push(saleObj.rows[i].doc); 1437 } 1438 } 1439 } 1440 1441 if (toDelete.length >= 0) { 1442 m.db.bulkDocs(toDelete).then(function(result) { 1443 // console.log("All shipments have been removed from cart"); //nestsalelinesonly 1444 if (cb) { 1445 cb(); 1446 } 1447 }); 1448 } else { 1449 if (cb) { 1450 cb(); 1451 } 1452 } 1453 }); 1454 } else { 1455 if (cb) { 1456 cb(); 1457 } 1458 } 1459 }); 1460 1461}; 1462 1463app.sendSale = function(saleForm) { 1464 var m = this; 1465 //console.log("sendSale", saleForm); 1466 $('.fnc-complete-checkout').prop('disabled', true); 1467 var saleOptions = { 1468 startkey: "sale_" + m.ls.saleGuid, 1469 endkey: "sale_" + m.ls.saleGuid + "\uffff", 1470 include_docs: true 1471 }; 1472 var saleLineOptions = { 1473 startkey: "saleline_" + m.ls.saleGuid, 1474 endkey: "saleline_" + m.ls.saleGuid + "\uffff", 1475 include_docs: true 1476 }; 1477 var shipmentOptions = { 1478 startkey: "shp_", 1479 endkey: "shp_\uffff", 1480 include_docs: true 1481 }; 1482 m.db.allDocs(saleOptions, function(err, saleObj) { 1483 if (!err) { 1484 m.db.allDocs(saleLineOptions, function(err, doc) { 1485 // debugger; 1486 if (!err) { 1487 m.db.allDocs(shipmentOptions, function(err, shipmentDoc) { 1488 //debugger; 1489 if (!err) { 1490 1491 var sale = saleObj.rows[0].doc; 1492 //console.log("SendSale sale: ",sale); 1493 if (!sale) { 1494 sale = {} 1495 } 1496 1497 // if (sale.vouchers) { 1498 // sale.vouchers = [sale.vouchers]; 1499 // } 1500 1501 var saleSummary = []; 1502 1503 //console.log("SendSale: ", doc.rows, shipmentDoc.rows, app.pickupList, saleForm.pickupLocation ) 1504 var saleLines = []; 1505 for (var i = 0; i < doc.rows.length; i++) { 1506 saleLines.push(doc.rows[i].doc); 1507 saleSummary.push({ 1508 code: doc.rows[i].doc.code, 1509 name: doc.rows[i].doc.name, 1510 price: doc.rows[i].doc.price, 1511 qty: doc.rows[i].doc.qty 1512 }); 1513 } 1514 sale.saleLines = saleLines; 1515 var shipmentLines = []; 1516 for (var i = 0; i < shipmentDoc.rows.length; i++) { 1517 shipmentLines.push(shipmentDoc.rows[i].doc); 1518 saleSummary.push({ 1519 code: "Shipping", 1520 name: shipmentDoc.rows[i].doc.name, 1521 price: shipmentDoc.rows[i].doc.price, 1522 qty: 1 1523 }); 1524 } 1525 sale.shipments = shipmentLines; 1526 1527 delete saleForm.cardholder; 1528 delete saleForm.cardnumber; 1529 delete saleForm.mm; 1530 delete saleForm.yy; 1531 delete saleForm.number; 1532 1533 1534 1535 saleForm.saleGuid = m.ls.saleGuid; 1536 if (saleForm.requiredDate) { 1537 saleForm.requiredDate = saleForm.requiredDate.substr(0, 10); 1538 } 1539 1540 // handle pickup, copy address to delivery 1541 if (app.pickupList) { 1542 if (saleForm.pickupLocation) { 1543 if (saleForm.pickupLocation.length > 10) { 1544 for (var i = 0; i < app.pickupList.length; i++) { 1545 //console.log("Pickup",saleForm.pickupLocation,app.pickupList[i]); 1546 if (app.pickupList[i].guid == saleForm.pickupLocation) { 1547 var loc = app.pickupList[i]; 1548 saleForm.deliveryFirstname = ""; 1549 saleForm.deliveryLastname = ""; 1550 saleForm.deliveryCompany = saleForm.company; 1551 saleForm.deliveryEmail = saleForm.email; 1552 saleForm.deliveryPhone = loc.phone; 1553 saleForm.deliveryMobile = loc.mobile; 1554 saleForm.deliveryAddress1 = loc.address1; 1555 saleForm.deliveryAddress2 = loc.address2; 1556 saleForm.deliveryCity = loc.city; 1557 saleForm.deliveryPostcode = loc.postcode; 1558 if (loc.country == "") { 1559 saleForm.deliveryCountry = "NZ"; 1560 } else { 1561 saleForm.deliveryCountry = loc.country.trim(); 1562 } 1563 } 1564 } 1565 delete saleForm.pickupLocation; 1566 } 1567 } 1568 } 1569 1570 var saleRec = $.extend({}, sale, saleForm); 1571 1572 if (m.ls.profile) { 1573 if (m.ls.profile.custId) { 1574 saleRec.custId = m.ls.profile.custId; 1575 } 1576 if (m.ls.profile.guid) { 1577 saleRec.custGuid = m.ls.profile.guid; 1578 } 1579 } 1580 saleRec.taxRate = ed.tax * 10000; 1581 saleRec.currCode = ed.currency; 1582 saleRec.priceLevel = ed.priceLevel; 1583 saleRec.url = window.location.host; 1584 saleRec.status = "ORDER"; 1585 saleRec._id = "sale_" + m.ls.saleGuid; 1586 saleRec._rev = saleObj.rows[0].value.rev; 1587 delete saleRec._csrf; 1588 //console.log("Submitting", saleRec); 1589 m.db.put(saleRec, function callback(err, result) { 1590 if (!err) { 1591 // app.sync(function () { 1592 var nextUrl = "/cart/confirmation?paytype=" + saleForm.pay_type.trim().toLowerCase() + "&amount=" + (m.ls.total.due / 10000).toFixed(2) + "&ref=" + m.ls.saleGuid; 1593 var oldSale = saleRec; 1594 var debug = false; 1595 var submitUrl = '/api/sale/submit'; 1596 //debugger; 1597 if(typeof Common !== "undefined"){ 1598 if(Common.getUrlParameterByName("appDebug",window.top.location.href) === "1"){ 1599 1600 if(window.top.cmsConfig){ 1601 submitUrl = window.top.cmsConfig.apiBaseUrl + '/api/express/saletest'; 1602 debug = true; 1603 1604 } 1605 } 1606 } 1607 1608 // FB conversion tracking 1609 if (typeof fbq !== 'undefined') { 1610 try { 1611 var contents = []; 1612 for (var i = 0; i < saleSummary.length; i++) { 1613 contents.push({ 1614 id: saleSummary[i].code, 1615 item_price: saleSummary[i].price, 1616 quantity: saleSummary[i].qty 1617 }); 1618 } 1619 1620 fbq('track', 'Purchase', 1621 { 1622 value: (m.ls.total.due / 10000).toFixed(2), 1623 currency: m.ls.currency, 1624 contents: contents, 1625 content_type: 'product' 1626 } 1627 ); 1628 } 1629 catch (ex) { 1630 console.log("FB conversion tracking failed"); 1631 } 1632 } 1633 1634 // Google conversion tracking 1635 if (typeof gtag !== 'undefined') { 1636 try { 1637 var contents = []; 1638 for (var i = 0; i < saleSummary.length; i++) { 1639 contents.push({ 1640 id: saleSummary[i].code, 1641 name: saleSummary[i].name, 1642 price: saleSummary[i].price, 1643 quantity: saleSummary[i].qty 1644 }); 1645 } 1646 1647 gtag('event', 'purchase', { 1648 "value": (m.ls.total.due / 10000).toFixed(2), 1649 "currency": m.ls.currency, 1650 "items": contents 1651 }); 1652 } 1653 catch (ex) { 1654 console.log("Google conversion tracking failed"); 1655 } 1656 } 1657 1658 switch (saleForm.pay_type.trim().toUpperCase()) { 1659 case "ACCOUNT":
1660 case "TELEBANK": 1661 case "CHEQUE": 1662 saleRec.payments = [{ 1663 tenderId: Constants.transactions.paymentMethods["PAYTYPE_" + saleForm.pay_type.trim().toUpperCase()], 1664 saleGuid: m.ls.saleGuid, 1665 paidAmount: m.ls.total.due, 1666 state: 1 1667 }]; 1668 1669 var saleData = JSON.stringify(saleRec); 1670 1671 var data = JSON.stringify({ 1672 _csrf: csrf_token, 1673 sale: saleData 1674 }); 1675 1676 if(debug === true){ 1677 data = saleData 1678 } 1679 1680 var ajaxConfig = { 1681 url: submitUrl, 1682 type: 'POST', 1683 headers: { 1684 'Content-Type': 'application/json', 1685 'x-csrf-token': csrf_token 1686 }, 1687 data: data, 1688 dataType: 'json', 1689 success: function(d) { 1690 // clear cart and start new sale 1691 1692 1693 1694 if (d.seqNumber) { 1695 m.removeSaleDocs(function() { 1696 m.ls.saleGuid = m.g(0); 1697 m.ls.baseCurrency = ed.currency; 1698 m.ls.baseTaxRate = ed.tax; 1699 1700 m.resetTotals(); 1701 m.setLocalState(m.ls); 1702 1703 window.location = nextUrl + "&invNumber=" + d.seqNumber; //?sid=" + app.ls.sessionGuid + "&sg=" + m.ls.saleGuid; 1704 1705 }); 1706 1707 } else { 1708 alert("There was a problem generating a order sequence number, please try again."); 1709 } 1710 }, 1711 failure: function() { 1712 alert("There was a connection problem processing your order, please reload the page and try again. "); 1713 } 1714 }; 1715 1716 if(debug === true){ 1717 ajaxConfig.headers = { 1718 "Content-Type": 'application/json', 1719 "Session": window.top.cmsConfig.sessionGuid 1720 }; 1721 } 1722 1723 $.ajax(ajaxConfig); 1724 break; 1725 1726 case "CREDITCARD": 1727 case "PAYPAL": 1728 saleRec.payments = [{ 1729 tenderId: Constants.transactions.paymentMethods["PAYTYPE_" + saleForm.pay_type.trim().toUpperCase()], 1730 saleGuid: m.ls.saleGuid, 1731 paidAmount: m.ls.total.due, 1732 state: 1 1733 }]; 1734 var saleData = JSON.stringify(saleRec); 1735 1736 var data = JSON.stringify({ 1737 _csrf: csrf_token, 1738 sale: saleData 1739 }); 1740 1741 if(debug === true){ 1742 data = saleData 1743 } 1744 1745 var ajaxConfig ={ 1746 url: submitUrl, 1747 type: 'POST', 1748 headers: { 1749 'Content-Type': 'application/json', 1750 'x-csrf-token': csrf_token 1751 }, 1752 data: data, 1753 dataType: 'json', 1754 success: function(d) { 1755 //console.log("CREDITCARD sale resp: " + d); 1756 // clear cart and start new sale 1757 1758 if (d.seqNumber) { 1759 m.removeSaleDocs(function() { 1760 //debugger; 1761 var payGuid = ""; 1762 try { 1763 if (d.payments[0]) { 1764 payGuid = d.payments[0].payGuid; 1765 } 1766 } 1767 catch (e) {} 1768 1769 nextUrl = "/function/gateway?currency=" + m.ls.currency + 1770 "&amount=" + (m.ls.total.due / 10000).toFixed(2) + 1771 "&ref=" + m.ls.saleGuid + 1772 "&invNumber=" + d.seqNumber + 1773 "&gateway=" + saleForm.pay_type.trim().toUpperCase() + 1774 "&firstname=" + encodeURIComponent(saleForm.firstname) + 1775 "&lastname=" + encodeURIComponent(saleForm.lastname) + 1776 "&company=" + encodeURIComponent(saleForm.company) + 1777 "&address1=" + encodeURIComponent(saleForm.address1) + 1778 "&address2=" + encodeURIComponent(saleForm.address2) + 1779 "&city=" + encodeURIComponent(saleForm.city) + 1780 "&country=" + encodeURIComponent(saleForm.country) + 1781 "&phone=" + encodeURIComponent(saleForm.phone) + 1782 "&state=" + encodeURIComponent(saleForm.state) + 1783 "&postcode=" + encodeURIComponent(saleForm.postcode) + 1784 "&email=" + encodeURIComponent(saleForm.email) + 1785 "&context=" + encodeURIComponent(JSON.stringify(saleSummary)) + 1786 "&payId=" + encodeURIComponent(payGuid); 1787 1788 m.ls.saleGuid = m.g(0); 1789 m.ls.baseCurrency = ed.currency; 1790 m.ls.baseTaxRate = ed.tax; 1791 1792 m.resetTotals(); 1793 m.setLocalState(m.ls); 1794 1795 window.location = nextUrl; //?sid=" + app.ls.sessionGuid + "&sg=" + m.ls.saleGuid; 1796 1797 }); 1798 1799 } else { 1800 alert("There was a problem processing your order, please try again."); 1801 } 1802 }, 1803 failure: function() { 1804 alert("There was a problem processing your order, please try again."); 1805 } 1806 }; 1807 1808 if(debug === true){ 1809 ajaxConfig.headers = { 1810 "Content-Type": 'application/json', 1811 "Session": window.top.cmsConfig.sessionGuid 1812 }; 1813 } 1814 1815 $.ajax(ajaxConfig); 1816 1817 // // sync again to get Inv Numbers etc 1818 // app.sync(function () { 1819 // var saleOptions = { 1820 // startkey: "sale_" + m.ls.saleGuid, 1821 // endkey: "sale_" + m.ls.saleGuid + "\uffff", 1822 // include_docs: true 1823 // }; 1824 // m.db.allDocs(saleOptions, function (err, saleObj) { 1825 // // get the sale lines 1826 1827 // // clear cart and start new sale 1828 // m.ls.saleGuid = m.g(0); 1829 // m.ls.baseCurrency = "NZD"; 1830 // m.ls.baseTaxRate = 0; 1831 // m.resetTotals(); 1832 // m.setLocalState(m.ls); 1833 // window.location = nextUrl; //?sid=" + app.ls.sessionGuid + "&sg=" + m.ls.saleGuid; 1834 // }); 1835 // }); 1836 break; 1837 1838 case "BITCOIN": 1839 break; 1840 case "CONTACT": 1841 break; 1842 1843 } 1844 // }); 1845 1846 } else { 1847 console.log(err); 1848 } 1849 }); 1850 } 1851 }); 1852 } 1853 }); 1854 } else { 1855 //app.ScriptNot 1856 } 1857 }); 1858} 1859 1860app.resolveItemToSaleline = function(item) { 1861 var m = this; 1862 var group = {}; 1863 var loyalty = {}; 1864 var discount = {}; 1865 var area = item.closest('.product-item'); 1866 if (area) { 1867 var product = { 1868 prdId: +area.attr("data-prd-id") || 0, 1869 pmmId: +area.attr("data-pmm-id") || 0, 1870 code: area.attr("data-prd-code"), 1871 type: +area.attr("data-prd-type") || 0, 1872 itemType: +(area.attr("data-item-type") || 0), 1873 name: area.attr("data-item-name"), 1874 spgId: +area.attr("data-spg-id") || 0, 1875 outletId: area.attr("data-outlet-id"), 1876 locId: area.attr("data-loc-id"), 1877 picId: +area.attr("data-pic-id") || 0, 1878 picFileName: area.attr("data-pic-filename"), 1879 schema: area.attr("data-pic-path"), 1880 grpIdTree: area.attr("data-group-tree"), 1881 description: "", 1882 rrp: 0, 1883 discount: 0, 1884 price: 0, 1885 flags: +area.attr("data-flags") || 0, 1886 unitQty: 1, 1887 outerQty: 0, 1888 moq: 0, 1889 weight: +area.attr("data-weight") || 0, 1890 unitWeight: +area.attr("data-weight") || 0, 1891 outerHeight: +area.attr("data-height") || 0, 1892 outerWidth: +area.attr("data-width") || 0, 1893 outerDepth: +area.attr("data-depth") || 0, 1894 primaryGrpId: 0, 1895 unit: area.attr("data-prd-unit") || "ea", 1896 shpId: 0, 1897 notes: "", 1898 qty: 0, 1899 svcId: +area.attr("data-svc-id") || 0, 1900 metadata: area.attr("data-metadata") || "" 1901 } 1902 1903 // any product options? 1904 var pmm = item.parents('.product-modifier'); 1905 var findPmmId = pmm.attr("data-pmm-id"); 1906 if (findPmmId) { 1907 product.pmmId = +findPmmId || 0; 1908 product.code = pmm.attr("data-prd-code"); 1909 if (pmm.attr("data-pmm-name")) { 1910 product.name += " - " + pmm.attr("data-pmm-name"); 1911 } 1912 product.weight = (+pmm.attr("data-weight") || product.weight); 1913 product.unitWeight = (+pmm.attr("data-weight") || product.weight); 1914 product.qty = Math.abs(parseFloat(+pmm.find(".product-qty").val() || 0)); 1915 product.price = +pmm.attr("data-price") || 0; 1916 product.discount = Math.abs(+pmm.attr("data-discount") || 0); 1917 product.rrp = +pmm.attr("data-original-price") || 0; 1918 product.priceCurr = pmm.attr("data-cur") || ed.currency; 1919 product.priceTax = +pmm.attr("data-tax") || 0; 1920 1921 1922 if ((+pmm.attr("data-pic-id") || 0) > 0) { 1923 product.picId = +pmm.attr("data-pic-id") || 0; 1924 product.schema = pmm.attr("data-pic-path") || ""; 1925 product.picFileName = pmm.attr("data-pic-filename"); 1926 } 1927 } 1928 1929 if (product.picId == 0) { 1930 var img = area.find("img.product-picture"); 1931 if (img.length == 0) { 1932 // themler image? 1933 img = area.find(".product-picture").find("img").eq(0); 1934 } 1935 1936 if (img.length == 0) { 1937 // div image? 1938 img = area.find(".product-picture"); 1939 } 1940 1941 if (img) { 1942 product.picId = +img.attr("data-pic-id") || 0; 1943 product.schema = img.attr("data-pic-path") || ""; 1944 product.picFileName = img.attr("data-pic-filename") || ""; 1945 } 1946 } 1947 1948 if (area.find(".product-notes").length > 0) { 1949 product.notes = area.find(".product-notes").val(); 1950 product.description = area.find(".product-notes").val(); 1951 area.find(".product-notes").val(""); 1952 } 1953 1954 if (area.find(".voucher-name").length > 0) { 1955 console.log("Voucher name found"); 1956 var voucherData = {}; 1957 voucherData.name = area.find(".voucher-name").val(); 1958 voucherData.email = area.find(".voucher-email").val(); 1959 voucherData.message = area.find(".voucher-message").val(); 1960 product.metadata = JSON.stringify(voucherData); 1961 console.log(product.metadata); 1962 1963 } 1964 1965 // handle variable price vouchers 1966 if (area.find(".voucher-amount").val() > 0) { 1967 product.price = area.find(".voucher-amount").val() * 10000; 1968 } 1969 1970 if (product.pmmId) { 1971 if (product.price == 0) { 1972 product.price = +area.attr("data-price") || 0; 1973 product.discount = Math.abs(+area.attr("data-discount") || 0); 1974 product.rrp = +area.attr("data-original-price") || 0; 1975 } 1976 if (product.priceCurr == "") { 1977 product.priceCurr = area.attr("data-cur") || ed.currency; 1978 product.priceTax = +area.attr("data-tax") || 0; 1979 } 1980 if (product.price == 0) { 1981 // change context to PMM level here, to get the context price 1982 area = pmm; 1983 } 1984 } 1985 1986 1987 // if still 0 (post pmmId, normal prdId) 1988 if (product.price == 0) { 1989 var prices = area.find(".price"); 1990 if (prices.length > 0) { 1991
1991 for (var i = 0; i < prices.length; i++) { 1992 var p = $(prices[i]); 1993 switch (p.attr("data-type")) { 1994 case "org": 1995 product.rrp = +p.attr("data-amt") || 0; 1996 break; 1997 case "adisc": //amount disc 1998 product.discount = Math.abs(+p.attr("data-amt") || 0); 1999 break; 2000 case "pdisc": //% disc 2001 product.discount = +p.attr("data-amt") || 0; 2002 break; 2003 default: 2004 product.price = +p.attr("data-amt") || 0; 2005 break; 2006 } 2007 product.priceCurr = p.attr("data-cur") || ed.currency; 2008 product.priceTax = +p.attr("data-tax") || 0; 2009 } 2010 } 2011 } 2012 2013 // which price matrix entry is selected? 2014 var findPmiId = area.find("div.cart-price-selector"); 2015 if (findPmiId) { 2016 if (findPmiId.length > 0) { 2017 var checkedOption = findPmiId.children().filter(":checked"); 2018 var checkedOptionPrice = +(checkedOption.attr("data-pmi-price") || 0); 2019 product.pmiId = checkedOption.val(); 2020 2021 if (checkedOptionPrice > 0) { 2022 product.price = checkedOptionPrice; 2023 } 2024 2025 if (checkedOption.attr("data-pmi-title")) { 2026 product.name += " - " + checkedOption.attr("data-pmi-title"); 2027 } 2028 console.log("PMI selection: " + product.pmiId + " : " + product.name + " Price: " + product.price); 2029 } 2030 } 2031 2032 2033 if (product.outerQty == 0) { 2034 product.outerQty = 1; 2035 } 2036 if (product.qty == 0) { 2037 if (area.context) { 2038 if (area.context.value > 0) { 2039 product.qty = Math.abs(parseFloat(+area.context.value || 0)); 2040 } 2041 } 2042 } 2043 2044 if (product.qty == 0) { 2045 // no modifier context available, use default area qty 2046 product.qty = Math.abs(parseFloat(+area.find(".product-qty").val() || 0)); 2047 } 2048 2049 if (product.qty == 0) { 2050 // final default to single QTY 2051 //console.log("QTY is 0, default to 1"); 2052 product.qty = 1; 2053 } 2054 product.weight = product.qty * product.unitWeight; 2055 } 2056 return product; 2057 }, 2058 2059 app.findSaleLine = function(prod, cb) { 2060 var m = this; 2061 var currline = null; 2062 var options = { 2063 startkey: "saleline_" + m.ls.saleGuid, 2064 endkey: "saleline_" + m.ls.saleGuid + "\uffff", 2065 include_docs: true 2066 }; 2067 2068 m.db.allDocs(options, function(err, doc) { 2069 if (!err) { 2070 if (doc.rows.length == 0) { 2071 // *** NEW SALE - add to db 2072 2073 // lookup country 2074 app.getGeoByIp(function(g) { 2075 var country = "NZ"; 2076 var postcode = "0000"; 2077 if (g) { 2078 if (g.geo) { 2079 country = g.geo.country; 2080 } 2081 if (g.postcode) { 2082 postcode = g.postcode.postcode; 2083 } 2084 } 2085 2086 var newSale = { 2087 _id: "sale_" + m.ls.saleGuid, 2088 contentType: "sale", 2089 saleGuid: m.ls.saleGuid, 2090 status: "BASKET", 2091 url: window.location.host, 2092 ostId: -1, // new order 2093 totalToPay: 0, 2094 totalAmount: 0, 2095 totalTax: 0, 2096 totalShipping: 0, 2097 totalDiscounts: 0, 2098 loyaltyReward: 0, 2099 loyaltyCost: 0, 2100 deliveryCountry: country, 2101 deliveryPostcode: postcode, 2102 country: country, 2103 currCode: ed.currency, 2104 taxRate: ed.tax * 10000, 2105 vouchers: "" 2106 }; 2107 2108 //console.log("New Sale", newSale); 2109 2110 m.db.put(newSale, function callback(err, result) { 2111 if (!err) { 2112 m.db.compact().then(function(result) { 2113 m.db.viewCleanup().then(function(result) { 2114 // handle result 2115 app.applyProfileDetailsToSale(); 2116 }).catch(function(err) { 2117 console.log(err); 2118 }); 2119 }).catch(function(err) { 2120 console.log(err); 2121 }); 2122 } 2123 }); 2124 }); 2125 } 2126 2127 doc.rows.forEach(function(item) { 2128 var sl = item.doc; 2129 if (sl._id.indexOf("saleline_") > -1) { 2130 app.ls.cartItemCount++; 2131 if (prod.salelnGuid) { 2132 if (prod.salelnGuid == sl.salelnGuid) { 2133 currline = item.doc; 2134 } 2135 } 2136 if (sl.prdId == prod.prdId) { 2137 if (prod.itemType != 8 && prod.itemType != 6) { // Package Type or Voucher PRDTYPE_VOUCHER: 6,PRDTYPE_PACKAGE: 8, 2138 if (typeof prod.taskId != "undefined") { 2139 if (sl.taskId == prod.taskId) { 2140 if (typeof prod.pmmId != "undefined") { 2141 if (sl.pmmId == prod.pmmId) { 2142 currline = item.doc; 2143 } 2144 } else { 2145 // found item line 2146 currline = item.doc; 2147 } 2148 } 2149 } else { 2150 if (typeof prod.pmmId != "undefined") { 2151 if (sl.pmmId == prod.pmmId) { 2152 currline = item.doc; 2153 } 2154 } else { 2155 if (typeof prod.pmiId != "undefined") { 2156 if (sl.pmiId == prod.pmiId) { 2157 currline = item.doc; 2158 } 2159 } else { 2160 // found item line 2161 currline = item.doc; 2162 } 2163 } 2164 } 2165 } 2166 } 2167 } 2168 }); 2169 } 2170 if (currline) { 2171 cb(currline); 2172 } else { 2173 // new line 2174 cb(null); 2175 } 2176 }); 2177 }; 2178 2179app.calculateTotals = function(cb) { 2180 var m = this; 2181 var currline = null; 2182 var lineTax = 0; 2183 2184 var saleLineOptions = { 2185 startkey: "saleline_" + m.ls.saleGuid, 2186 endkey: "saleline_" + m.ls.saleGuid + "\uffff", 2187 include_docs: true 2188 }; 2189 2190 // start all at 0 2191 m.resetTotals(); 2192 2193 m.db.allDocs(saleLineOptions, function(err, doc) { 2194 if (!err) { 2195 // start total off with group-wide shipping totals 2196 m.ls.total.due += m.ls.total.shipping; 2197 if (doc.total_rows == 0) { 2198 app.setLocalState(app.ls); 2199 m.renderTotals(); 2200 prices.initPrices(m.ls.currency); 2201 $(".shoppingBtn").addClass("no-cart-items"); 2202 cb(m.ls.total); 2203 return; 2204 } 2205 $(".shoppingBtn").removeClass("no-cart-items"); 2206 2207 doc.rows.forEach(function(item) { 2208 var sl = item.doc; 2209 2210 if (sl._id.indexOf("saleline_") > -1) { 2211 m.ls.total.amount += sl.totalAmount; 2212 lineTax = (sl.totalAmount * (1 + (ed.tax / 100))) - sl.totalAmount; 2213 m.ls.total.tax += lineTax; 2214 m.ls.total.shipping += (+sl.totalShipping || 0); 2215 m.ls.total.discounts += sl.totalDiscounts;
2216 m.ls.total.weight += (+sl.weight || 0); 2217 m.ls.total.volume += ((+sl.outerDepth || 0) * (+sl.outerWidth || 0) * (+sl.outerDepth || 0)); 2218 m.ls.total.due += (sl.totalAmount + sl.totalShipping + lineTax); // - sl.totalDiscounts; 2219 2220 m.ls.total.itemCount += sl.qty; 2221 m.ls.total.loyaltyReward += sl.loyaltyReward; 2222 m.ls.total.loyaltyCost += sl.loyaltyCost; 2223 m.ls.baseCurrency = sl.priceCurr; 2224 m.ls.baseTaxRate = ed.tax; 2225 m.ls.total.lineCount++; 2226 2227 2228 if (typeof window._paq !== 'undefined') { 2229 window._paq.push(['addEcommerceItem', 2230 sl.code, 2231 sl.name, 2232 "", 2233 sl.price / 10000, 2234 sl.qty 2235 ]); 2236 } 2237 } 2238 }); 2239 2240 if (typeof window._paq !== 'undefined') { 2241 window._paq.push(['trackEcommerceCartUpdate', m.ls.total.amount / 10000]); 2242 } 2243 2244 app.refreshShipping(true, function() { 2245 setTimeout(function() { 2246 // get all shipping options 2247 var shipOptions = { 2248 startkey: "shp_", 2249 endkey: "shp_\uffff", 2250 include_docs: true 2251 }; 2252 m.db.allDocs(shipOptions, function(err, doc) { 2253 if (!err) { 2254 doc.rows.forEach(function(item) { 2255 var sl = item.doc; 2256 m.ls.total.shipping += (+sl.price || 0); 2257 // debugger; 2258 2259 // m.ls.saleShippingTotal += (+shipment.price || 0); 2260 2261 }); 2262 //console.log("LOOP2, m.ls.saleShippingTotal: " + m.ls.total.shipping, doc); 2263 2264 var saleOptions = { 2265 startkey: "sale_" + m.ls.saleGuid, 2266 endkey: "sale_" + m.ls.saleGuid + "\uffff", 2267 include_docs: true 2268 }; 2269 m.db.allDocs(saleOptions, function(err, doc) { 2270 if (doc.rows[0]) { 2271 if (!doc.rows[0].doc.vouchers) doc.rows[0].doc.vouchers = ""; 2272 2273 var voucherDiscountAmt = 0; 2274 var voucherDiscountTaxAmt = 0; 2275 m.checkVoucherCode(doc.rows[0].doc.vouchers, function(data) { 2276 if (data) { 2277 if (data.valid) { 2278 if (data.type == 2) { // %/$ off 2279 if (data.discount > 0) { // % off 2280 voucherDiscountAmt = m.ls.total.amount - (m.ls.total.amount * ((100 - (data.discount / 10000)) / 100)); 2281 } else { // $ off 2282 voucherDiscountAmt = Math.abs(data.discount); 2283 } 2284 } 2285 voucherDiscountTaxAmt = (voucherDiscountAmt * (1 + (ed.tax / 100))) - voucherDiscountAmt; 2286 m.ls.total.tax -= voucherDiscountTaxAmt; 2287 m.ls.total.discounts += voucherDiscountAmt; 2288 m.ls.total.due -= (voucherDiscountAmt + voucherDiscountTaxAmt); 2289 m.ls.total.amount -= voucherDiscountAmt; 2290 //console.log("Applied discount of: " + data.discount); 2291 } 2292 } 2293 2294 // pickup is free 2295 if (app.deliveryMode == "pickup") { 2296 m.ls.total.shipping = 0; 2297 } 2298 2299 2300 // add on the group shipping 2301 m.ls.total.due += m.ls.total.shipping; 2302 2303 // add tax to shipping as well 2304 var totalShippingTax = (m.ls.total.shipping * (1 + (ed.tax / 100))) - m.ls.total.shipping; 2305 m.ls.total.due += totalShippingTax; 2306 m.ls.total.tax += totalShippingTax; 2307 2308 if (app.ls.profile) { 2309 if (app.ls.profile.resourceName) { 2310 doc.rows[0].doc.notifyEmail = app.ls.profile.resourceName; 2311 } 2312 } 2313 2314 doc.rows[0].doc.totalToPay = parseInt(m.ls.total.due); 2315 doc.rows[0].doc.totalAmount = parseInt(m.ls.total.amount); 2316 doc.rows[0].doc.totalTax = parseInt(m.ls.total.tax); 2317 doc.rows[0].doc.totalShipping = parseInt((+m.ls.total.shipping || 0)); 2318 doc.rows[0].doc.totalDiscounts = parseInt(m.ls.total.discounts); 2319 doc.rows[0].doc.loyaltyReward = parseInt(m.ls.total.loyaltyReward); 2320 doc.rows[0].doc.loyaltyCost = parseInt(m.ls.total.loyaltyCost); 2321 2322 if (m.ls.total.discounts > 0) { 2323 $(".total-discounts").css("display", "block"); 2324 } 2325 2326 if (m.ls.profile) { 2327 if (m.ls.profile.custId) { 2328 doc.rows[0].doc.custId = m.ls.profile.custId; 2329 } 2330 } 2331 2332 m.db.put(doc.rows[0].doc, function(resp) { 2333 app.setLocalState(app.ls); 2334 m.renderTotals(); 2335 prices.initPrices(m.ls.currency); 2336 app.selectPickerRefresh();
2337 if (cb) { 2338 cb(m.ls.total); 2339 } 2340 }); 2341 }); 2342 } else { 2343 if (cb) { 2344 cb(m.ls.total); 2345 } 2346 } 2347 }); 2348 } 2349 }); 2350 }, 500); 2351 }); 2352 } else { 2353 app.setLocalState(app.ls); 2354 m.renderTotals(); 2355 prices.initPrices(m.ls.currency); 2356 } 2357 }); 2358} 2359 2360app.getCurrentSale = function(cb) { 2361 var m = this; 2362 var options = { 2363 startkey: "sale_" + m.ls.saleGuid, 2364 endkey: "sale_" + m.ls.saleGuid + "\uffff", 2365 include_docs: true 2366 }; 2367 2368 m.db.allDocs(options, function(err, docs) { 2369 if (docs.rows.length > 0) { 2370 cb(docs.rows[0].doc); 2371 } else { 2372 cb(null); 2373 } 2374 }); 2375} 2376 2377app.checkSaleGuid = function(cb) { 2378 var m = this; 2379 $.ajax({ 2380 url: '/api/sale/checksaleguid', 2381 type: 'GET', 2382 contentType: 'application/json', 2383 data: { 2384 saleGuid: m.ls.saleGuid 2385 }, 2386 success: function(d) { 2387 if(d.used === true){ 2388 m.removeSaleDocs(function() { 2389 m.ls.saleGuid = m.g(0); 2390 m.ls.baseCurrency = ed.currency; 2391 m.ls.baseTaxRate = ed.tax; 2392 2393 m.resetTotals(); 2394 m.setLocalState(m.ls); 2395 cb(); 2396 }); 2397 }else{ 2398 cb(); 2399 } 2400 }, 2401 failure: function() { 2402 cb(); 2403 } 2404 }); 2405} 2406 2407app.nestSaleLinesByShippingGroup = function(sale, doc, cb) { 2408 var m = this; 2409 var data = doc.rows; 2410 var groups = {}; 2411 var output = []; 2412 var groupCount = 0; 2413 var totalGroupCount = 0; 2414 var totalWithOptions = 0; 2415 var isPickup = false; 2416 var isPostCodeOk = false; 2417 2418 // console.log("nestSaleLinesByShippingGroup"); 2419 function isNumeric(n) { 2420 return !isNaN(parseFloat(n)) && isFinite(n); 2421 } 2422 2423 if (sale) { 2424 if (sale.deliveryPostcode != "") { 2425 isPostCodeOk = true; 2426 } 2427 } 2428 2429 function complete() { 2430 groupCount--; 2431 if (groupCount == 0) { 2432 if (sale) { 2433 if (sale.pickupLocation) { 2434 if (sale.pickupLocation.length > 5) { 2435 isPickup = true; 2436 } 2437 } 2438 } 2439 2440 // console.log("nestSaleLinesByShippingGroup: " + window.cartBypassAddressChecks) 2441 if ((totalGroupCount == totalWithOptions && isPostCodeOk) || isPickup || window.cartBypassAddressChecks) { 2442 $('.fnc-complete-checkout').prop('disabled', false); 2443 $('.fnc-complete-checkout').attr("title", ""); 2444 } else { 2445 //$('.fnc-complete-checkout').prop('disabled', true); 2446 $('.fnc-complete-checkout').css("pointer-events", "auto"); 2447 $('.fnc-complete-checkout').attr("title", "This sale cannot be shipped to your address, please choose different options."); 2448 } 2449 2450 output.sort(function(a, b) { 2451 if (a.group.spgId < b.group.spgId) { 2452 return -1; 2453 } 2454 if (a.group.spgId > b.group.spgId) { 2455 return 1; 2456 } 2457 return 0; 2458 }); 2459 2460 //console.log("SHIP out: ",output); 2461 2462 try { 2463 2464 // console.log("LOOP3 m.ls.saleShippingTotal: " + m.ls.total.shipping, doc); 2465 } catch (ex) {} 2466 cb({ 2467 cart: output 2468 }); 2469 } 2470 } 2471 2472 for (var i = 0; i < data.length; i++) { 2473 var row = data[i].doc; 2474 var groupValue = row["spgId"]; 2475 if (groups["grp-" + groupValue] == undefined) { 2476 groups["grp-" + groupValue] = new Array(); 2477 } 2478 groups["grp-" + groupValue].push(row); 2479 } 2480 2481 groupCount = Object.keys(groups).length; 2482 totalGroupCount = groupCount; 2483 2484 if (groupCount) { 2485 for (var v in groups) { 2486 if (groups[v]) { 2487 var weight = 0; 2488 var volume = 0; 2489 var lineQty = 0; 2490 var groupQty = 0; 2491 2492 for (var i = 0; i < groups[v].length; i++) { 2493 if (groups[v][i].code) { 2494 if (groups[v][i].code.indexOf("/") > 0) { 2495 var cmp = groups[v][i].code.split("/"); 2496 if (isNumeric(cmp[1])) { 2497 lineQty = cmp[1] 2498 groupQty += lineQty; 2499 } 2500 } else { 2501 lineQty = groups[v][i].qty 2502 groupQty += lineQty; 2503 } 2504 } else { 2505 lineQty = groups[v][i].qty 2506 groupQty += lineQty; 2507 } 2508 weight += (groups[v][i].weight * lineQty);
2509 volume += (groups[v][i].volume * lineQty); 2510 } 2511 var grp = { 2512 spgId: groups[v][0].spgId, 2513 spgName: "", 2514 items: groups[v], 2515 weight: weight, 2516 volume: volume, 2517 qty: groupQty, 2518 isRural: false, 2519 isPickup: false 2520 } 2521 2522 app.getShippingMethods(sale, grp, function(data) { 2523 if (data) { 2524 // console.log("getShippingMethods groupCount",groupCount); 2525 // console.log("getShippingMethods out",data); 2526 if (data.items.length > 0) { 2527 totalWithOptions++; 2528 } 2529 output.push(data); 2530 } 2531 complete(); 2532 }); 2533 } 2534 } 2535 } else { 2536 cb(data); 2537 } 2538}; 2539 2540app.tagSelectedOptions = function(cartInfo, cb) { 2541 var m = this; 2542 2543 var options = { 2544 startkey: "shp_", 2545 endkey: "shp_\uffff", 2546 include_docs: true 2547 }; 2548 m.ls.total.shipping = 0; 2549 2550 if (cartInfo) { 2551 // get all shipment records 2552 m.db.allDocs(options, function(err, shipments) { 2553 if (!err) { 2554 // loop through all shipments and set selected flag on item per group 2555 //console.log("Shipments: ", shipments); 2556 for (var j = 0; j < shipments.rows.length; j++) { 2557 var shipment = shipments.rows[j].doc; 2558 if (cartInfo.cart) { 2559 for (var i = 0; i < cartInfo.cart.length; i++) { 2560 var cI = cartInfo.cart[i]; 2561 //console.log("cI", cI, shipment); 2562 if (cI.group.spgId == shipment.spgId) { 2563 // got the right group 2564 var foundSelection = false; 2565 for (var x = 0; x < cI.items.length; x++) { 2566 var opt = cI.items[x]; 2567 //console.log("Ship Opt", opt); 2568 if (opt.shpId == shipment.shpId) { 2569 // have found the selected option 2570 opt.selected = true; 2571 m.ls.total.shipping += +(shipment.price || 0); 2572 2573 foundSelection = true; 2574 //console.log("* Selected Opt", shipment); 2575 } else { 2576 opt.selected = false; 2577 } 2578 } 2579 if (!foundSelection) { 2580 // first new option 2581 if (cI.items[0]) { 2582 m.ls.total.shipping += +(cI.items[0].price || 0); 2583 } 2584 } 2585 } 2586 } 2587 } 2588 } 2589 cb(cartInfo); 2590 } 2591 }); 2592 } else { 2593 cb(null); 2594 } 2595} 2596 2597app.refreshCart = function(mode, cb) { 2598 var m = this; 2599 2600 if(window.disableLegacyCart){ 2601 return; 2602 } 2603 2604 var options = { 2605 startkey: "saleline_" + m.ls.saleGuid, 2606 endkey: "saleline_" + m.ls.saleGuid + "\uffff", 2607 include_docs: true 2608 }; 2609 2610 if (mode) { 2611 if (mode != "nestsalelinesonly") { 2612 m.cartMode = mode; 2613 } 2614 } 2615 2616 var cartForm = document.querySelector('#shopping-cart-details'); 2617 var addressForm = null; 2618 if (cartForm) { 2619 addressForm = corridor(cartForm); 2620 } 2621 m.db.allDocs(options, function(err, doc) { 2622 if (!err) { 2623 //console.log("Nesting Lines"); 2624 app.nestSaleLinesByShippingGroup(addressForm, doc, function(doc) { 2625 if (mode != "nestsalelinesonly") { 2626 if (doc.cart && doc.cart[0].stockUpdates.length > 0) { 2627 // do the updates 2628 for (var i = 0; i < doc.cart[0].stockUpdates.length; i++) { 2629 var itm = doc.cart[0].stockUpdates[i]; 2630 app.updateSaleLine(itm.salelnGuid, itm.newQty, itm); 2631 } 2632 if (cb) cb(); 2633 } else { 2634 // render cart 2635 //console.log("tagging lines"); 2636 app.tagSelectedOptions(doc, function(doc) { 2637 //console.log("tagSelectedOptions shp total:", m.ls.total.shipping); 2638 console.log("tagSelectedOptions Ship Doc", doc) 2639 if (app.deliveryMode == "pickup") { 2640 m.ls.total.shipping = 0; 2641 } 2642 if (doc.cart) { 2643 doc.cart[0].group.items.sort(function(a, b) { 2644 if (a.code < b.code) { 2645 return -1; 2646 } 2647 if (a.code > b.code) { 2648 return 1; 2649 } 2650 return 0; 2651 }); 2652 } 2653 2654 dust.render("templates/components/client/cart/" + m.cartMode, doc, function(err, out) { 2655 if (err) { 2656 console.error(err); 2657 } else { 2658 $(".cart-item-list").html(out); 2659 } 2660 2661 app.calculateTotals(function() { 2662 // console.log("price refresh", app.deliveryMode, m.ls.total); 2663 // debugger; 2664 // if (app.deliveryMode == "pickup") { 2665 // m.ls.total.shipping = 0; 2666 //} 2667 // app.setLocalState(app.ls); 2668 // m.renderTotals(); 2669 // prices.initPrices(m.ls.currency); 2670 2671 if (addressForm) { 2672 if (addressForm.email != "") { 2673 corridor(cartForm, addressForm); 2674 } 2675 } 2676 app.selectPickerRefresh();
2677 if (m.ls.total.lineCount > 0) { 2678 $('.fnc-complete-checkout').prop('disabled', false); 2679 } else { 2680 $('.fnc-complete-checkout').prop('disabled', true); 2681 $('.fnc-complete-checkout').attr("title", "There are no items in the cart. To checkout please add something first."); 2682 //app.notify("There are no items in the cart. To checkout please add something first.", "error"); 2683 } 2684 m.registerCartEvents(); 2685 2686 if (cb) cb(); 2687 }); 2688 2689 }); 2690 2691 }); 2692 } 2693 } else { 2694 if (cb) cb(); 2695 } 2696 }); 2697 } 2698 }); 2699} 2700 2701app.setCartFormDetailsFromSale = function(formId, callback) { 2702 if (formId) { 2703 var input = document.querySelector('#' + formId); 2704 //console.log("setCartFormDetailsFromSale", formId, input); 2705 app.getCurrentSale(function(sale) { 2706 sale.deliveryCountry = "NZ"; 2707 //console.log("setCartFormDetailsFromSale setting", sale); 2708 var saleForm = corridor(input, sale); 2709 // console.log("setCartFormDetailsFromSale", sale); 2710 //$('#country').selectpicker('refresh'); 2711 //$('#deliveryCountry').selectpicker('refresh'); 2712 app.selectPickerRefresh(); 2713 if (callback) callback(); 2714 }); 2715 } else { 2716 if (callback) callback(); 2717 } 2718}; 2719 2720app.applyProfileDetailsToSale = function(formId, callback) { 2721 var m = this; 2722 // debugger; 2723 if (window.parent) { 2724 if (window.parent.cmsConfig) { 2725 if (window.parent.cmsConfig.customerProfile) { 2726 app.ls.profile = window.parent.cmsConfig.customerProfile; 2727 } 2728 } 2729 } 2730 if (app.ls.profile) { 2731 var p = app.ls.profile; 2732 2733 // only update if legit data 2734 if (p.email) { 2735 2736 app.getCurrentSale(function(sale) { 2737 if (sale) { 2738 if (!sale.email) { 2739 sale.email = ""; 2740 } 2741 if (sale.email == "") { 2742 sale.custId = p.custId; 2743 sale.custGuid = p.custGuid; 2744 // if (p.firstname != "" && sale.firstname == "") 2745 sale.firstname = p.firstname; 2746 2747 // if (sale.lastname == "" && p.lastname != "") 2748 sale.lastname = p.lastname; 2749 2750 sale.name = p.name; 2751 sale.company = p.company; 2752 sale.email = p.email; 2753 if (p.phone) 2754 if (p.phone != "") 2755 sale.phone = p.phone; 2756 else 2757 sale.phone = p.mobile; 2758 2759 sale.address1 = p.address1; 2760 sale.address2 = p.address2; 2761 sale.city = p.city; 2762 sale.postcode = p.postcode; 2763 if (p.country) { 2764 sale.country = p.country.trim(); 2765 } else { 2766 sale.country = "NZ"; 2767 } 2768 if (sale.country == "") { 2769 sale.country = "NZ"; 2770 } 2771 } 2772 sale.priceLevel = p.priceLevel; 2773 if (!sale.deliveryEmail) { 2774 sale.deliveryEmail = ""; 2775 } 2776 if (sale.deliveryEmail == "") { 2777 sale.deliveryFirstname = p.deliveryFirstname; 2778 sale.deliveryLastname = p.deliveryLastname; 2779 sale.deliveryCompany = p.deliveryCompany; 2780 sale.deliveryEmail = p.deliveryEmail; 2781 sale.deliveryPhone = p.deliveryPhone; 2782 sale.deliveryAddress1 = p.deliveryAddress1; 2783 sale.deliveryAddress2 = p.deliveryAddress2; 2784 sale.deliveryCity = p.deliveryCity; 2785 sale.deliveryPostcode = p.deliveryPostcode; 2786 if (p.deliveryCountry) { 2787 sale.deliveryCountry = p.deliveryCountry.trim(); 2788 } else { 2789 sale.deliveryCountry = app.ls.geoCountry; 2790 } 2791 } 2792 2793 app.db.put(sale, {}, function(err, resp) { 2794 app.setLocalState(app.ls); 2795 if (formId) { 2796 var input = document.querySelector('#' + formId); 2797 if (input) { 2798 //console.log("applyProfileDetailsToSale setting", sale); 2799 var saleForm = corridor(input, sale); 2800 2801 //$('#country').selectpicker('refresh'); 2802 //$('#deliveryCountry').selectpicker('refresh'); 2803 app.selectPickerRefresh();
2804 2805 if (callback) callback(); 2806 return; 2807 } else { 2808 if (callback) callback(); 2809 return; 2810 } 2811 } else { 2812 if (callback) callback(); 2813 return; 2814 } 2815 }); 2816 } else { 2817 if (callback) callback(); 2818 return; 2819 } 2820 }); 2821 } else { 2822 if (callback) callback(); 2823 return; 2824 } 2825 } else { 2826 if ($("#email").val() === "") { 2827 app.setCartFormDetailsFromSale("shopping-cart-details", function() { 2828 //$("#chk-ship-to-billing").attr("checked","checked"); 2829 // app.setShipToAddressFromBilling(); 2830 if (callback) callback(); //joseph added this because of double up issue 2831 2832 }); 2833 } else { 2834 2835 if (callback) callback(); //joseph added this because of double up issue 2836 } 2837 } 2838 2839 //if (callback) callback(); //joseph commented this out because of double up issue. callback is being called twice, once on line 2329 and again here 2840}; 2841 2842app.quoteShipping = function(domEl, deliveryCountry, deliveryPostcode, cb) { 2843 2844 var m = this; 2845 var product = m.resolveItemToSaleline(domEl); 2846 var totalAmount = parseFloat(product.qty) * product.price; 2847 var totalTax = ((parseFloat(product.qty) * product.price) * (1 + (ed.tax / 100))) - (parseFloat(product.qty) * product.price); 2848 var totalDiscounts = parseFloat(product.qty) * product.discount; 2849 2850 m.updateDeliveryArea(deliveryCountry, deliveryPostcode, function() { 2851 var obj = { 2852 "_csrf": csrf_token, 2853 "totals": { 2854 "amount": totalAmount, 2855 "tax": totalTax, 2856 "shipping": 500000, 2857 "discounts": totalDiscounts, 2858 "weight": parseFloat(product.qty) * product.weight, 2859 "volume": 0, 2860 "due": 0, 2861 "lineCount": 1, 2862 "itemCount": parseFloat(product.qty), 2863 "loyaltyReward": 0, 2864 "loyaltyCost": 0 2865 }, 2866 "sale": { 2867 "pickupLocation": "", 2868 "deliveryCountry": deliveryCountry, 2869 "deliveryPostcode": deliveryPostcode 2870 }, 2871 "group": { 2872 "spgId": product.spgId, 2873 "spgName": "", 2874 "items": [{ 2875 "contentType": "saleline", 2876 "url": window.location.host, 2877 "saleGuid": "00000000-0000-0000-0000-000000000000", 2878 "salelnGuid": "00000000-0000-0000-0000-000000000000", 2879 "prdId": product.prdId, 2880 "pmmId": product.pmmId, 2881 "pmiId": product.pmiId, 2882 "primaryGrpId": product.prdId, 2883 "picId": product.picId, 2884 "picFileName": product.picFileName, 2885 "schema": product.schema, 2886 "metadata": "", 2887 2888 "shpId": product.shpId, 2889 "spgId": product.spgId, 2890 "locId": product.locId, 2891 "outletId": product.outletId, 2892 2893 "code": product.code, 2894 "name": product.name, 2895 "type": product.type, // saleln_type 2896 "itemType": +(product.itemType || 0), // prd_type 2897 "description": product.description, 2898 "notes": product.notes, 2899 "flags": product.flags, 2900 2901 "qty": parseFloat(product.qty), 2902 "unit": product.unit, 2903 "unitQty": product.unitQty, 2904 "outerQty": product.outerQty, 2905 "moq": product.moq, 2906 "weight": product.weight, 2907 "unitWeight": product.unitWeight, 2908 "loyaltyCost": 0, 2909 "loyaltyReward": 0, 2910 "price": product.price, 2911 "priceCurr": product.priceCurr, 2912 "priceTax": product.priceTax, 2913 "rrp": product.rrp, 2914 "discount": product.discount, 2915 "isPriceOnApplication": 0, 2916 "outerHeight": 0, 2917 "outerWidth": 0, 2918 "outerDepth": 0, 2919 "totalShipping": 0, 2920 "totalAmount": product.qty * product.price, 2921 "totalTax": ((product.qty * product.price) * (1 + (ed.tax / 100))) - (product.qty * product.price), 2922 "totalDiscounts": product.qty * product.discount 2923 }], 2924 "weight": parseFloat(product.qty) * product.unitWeight, 2925 "volume": null, 2926 "qty": parseFloat(product.qty), 2927 "isRural": false, 2928 "isPickup": false 2929 } 2930 }; 2931 // console.log("quoteShipping req"); 2932 $.ajax({
2933 url: '/api/shipping/methods', 2934 type: 'POST', 2935 headers: { 2936 'Content-Type': 'application/json', 2937 'x-csrf-token': csrf_token 2938 }, 2939 data: JSON.stringify(obj), 2940 dataType: 'json', 2941 success: function(d) { 2942 if (cb) { 2943 cb(null, d); 2944 } 2945 }, 2946 failure: function() { 2947 if (cb) { 2948 cb("An error occurred getting the available shipping options.", null); 2949 } 2950 } 2951 }); 2952 }); 2953}; 2954 2955app.refreshShipping = function(calcOnly, cb) { 2956 if(window.disableLegacyCart){ 2957 if (cb) cb(); 2958 return; 2959 } 2960 var m = this; 2961 // refreshCart loads shipping options by group 2962 2963 var options = { 2964 startkey: "shp_", 2965 endkey: "shp_\uffff", 2966 include_docs: true 2967 }; 2968 2969 m.ls.saleShippingTotal = 0; 2970 var toDelete = []; 2971 //alert("refreshShipping"); 2972 m.db.allDocs(options, function(err, doc) { 2973 if (!err) { 2974 if (doc.rows.length >= 0) { 2975 for (var i = 0; i < doc.rows.length; i++) { 2976 if (doc.rows[i].doc.contentType == "shippingmethod") { 2977 doc.rows[i].doc._deleted = true; 2978 toDelete.push(doc.rows[i].doc); 2979 } 2980 } 2981 m.db.bulkDocs(toDelete).then(function(result) { 2982 // console.log("All shipments have been removed from cart"); //nestsalelinesonly 2983 var shipments = []; 2984 var addNewShipment = true; 2985 m.refreshCart("nestsalelinesonly", function() { 2986 setTimeout(function() { 2987 // console.log("Reloading from current selected options"); 2988 $("#cart-main select.fnc-update-shipping").each(function(index) { 2989 var sel = $(this); 2990 var sel = sel.find("option:selected"); 2991 if (sel.length > 0) { 2992 var opt = $(sel[0]); 2993 if (opt.attr("data-spg-id")) { 2994 var shipment = { 2995 _id: "shp_" + opt.attr("data-spg-id") + "_" + index, 2996 contentType: "shippingmethod", 2997 shpId: opt.attr("data-shp-id"), 2998 spgId: opt.attr("data-spg-id"), 2999 flags: opt.attr("data-flags"), 3000 name: opt.text(), 3001 price: opt.attr("data-price") 3002 } 3003 addNewShipment = true; 3004 for (var i = 0; i < shipments.length; i++) { 3005 //alert("shipments[i].shpId: " + shipments[i].shpId + ", " + shipment.shpId); 3006 if (shipments[i].shpId == shipment.shpId) { 3007 addNewShipment = false; 3008 } 3009 } 3010 // alert("addNewShipment: " + addNewShipment + ", " + shipments.length); 3011 3012 if (addNewShipment) { 3013 shipments.push(shipment); 3014 3015 //alert("Adding shipment" + JSON.stringify(shipment)); 3016 //console.log("!foundExistingShipment: ", shipment); 3017 } 3018 app.lastShipmentId = shipment.shpId; 3019 } 3020 } 3021 }); 3022 3023 m.db.bulkDocs(shipments, function(err, item) { 3024 if (cb) cb(); 3025 }); 3026 }, 1000); 3027 }); 3028 }); 3029 } 3030 } 3031 }) 3032}; 3033 3034app.updateSaleShipment = function(spgId, shpId, shpName, quotedPrice) { 3035 var m = this; 3036 3037 var options = { 3038 startkey: "shp_" + spgId, 3039 endkey: "shp_" + spgId + "\uffff", 3040 include_docs: true 3041 }; 3042 // console.log("updateSaleShipment"); 3043 m.db.allDocs(options, function(err, doc) { 3044 if (!err) { 3045 if (doc.total_rows == 0) { 3046 var shipment = { 3047 _id: "shp_" + spgId, 3048 contentType: "shippingmethod", 3049 shpId: shpId, 3050 spgId: spgId, 3051 name: shpName, 3052 price: quotedPrice 3053 } 3054 } else { 3055 var shipment = doc.rows[0].doc; 3056 shipment.shpId = shpId; 3057 shipment.spgId = spgId; 3058 shipment.name = shpName; 3059 shipment.price = quotedPrice; 3060 } 3061 m.db.put(shipment, {}, function(err, item) { 3062 m.sync(); 3063 app.cartNeedsRefresh();
3064 }); 3065 } 3066 }); 3067} 3068 3069app.getShippingMethods = function(sale, group, cb) { 3070 var m = this; 3071 if (!sale) { 3072 sale = {} 3073 } 3074 if (!sale.pickupLocation) sale.pickupLocation = ""; 3075 if (!sale.deliveryCountry) sale.deliveryCountry = ""; 3076 if (!sale.deliveryPostcode) sale.deliveryPostcode = ""; 3077 3078 var obj = { 3079 _csrf: csrf_token, 3080 totals: m.ls.total, 3081 sale: sale, 3082 group: group 3083 }; 3084 //console.log("getShippingMethods req"); 3085 //console.trace(); 3086 //console.log(JSON.stringify(obj)); 3087 $.ajax({ 3088 url: '/api/shipping/methods', 3089 type: 'POST', 3090 headers: { 3091 'Content-Type': 'application/json', 3092 'x-csrf-token': csrf_token 3093 }, 3094 data: JSON.stringify(obj), 3095 dataType: 'json', 3096 success: function(d) { 3097 if (cb) { 3098 cb(d); 3099 } 3100 }, 3101 failure: function() { 3102 if (cb) { 3103 cb(null); 3104 } 3105 } 3106 }); 3107} 3108 3109app.checkVoucherCode = function(voucherCode, cb) { 3110 var m = this; 3111 if (voucherCode != "") { 3112 $.ajax({
3113 url: '/api/sale/checkvoucher', 3114 type: 'POST', 3115 headers: { 3116 'Content-Type': 'application/json', 3117 'x-csrf-token': csrf_token 3118 }, 3119 data: JSON.stringify({ 3120 _csrf: csrf_token, 3121 voucherCode: voucherCode, 3122 totals: m.ls.total 3123 }), 3124 dataType: 'json', 3125 success: function(d) { 3126 if (cb) { 3127 cb(d); 3128 } 3129 }, 3130 failure: function() { 3131 if (cb) { 3132 cb(null); 3133 } 3134 } 3135 }); 3136 } else { 3137 if (cb) { 3138 cb(null); 3139 } 3140 } 3141} 3142 3143app.saveCartAsList = function(name, cb) { 3144 var m = this; 3145 3146 var options = { 3147 startkey: "saleline_" + m.ls.saleGuid, 3148 endkey: "saleline_" + m.ls.saleGuid + "\uffff", 3149 include_docs: true 3150 }; 3151 3152 m.db.allDocs(options, function(err, doc) { 3153 if (!err) { 3154 var lines = []; 3155 for (var i = 0; i < doc.rows.length; i++) { 3156 var item = doc.rows[i].doc; 3157 lines.push({ 3158 cOrdPrd_ID: item.prdId, 3159 cOrdPrd_Qty: item.qty, 3160 cOrdPrd_Amt: item.price / 10000, 3161 cOrdPrd_PMM: item.pmmId, 3162 cOrdPrd_Text: item.text, 3163 cOrdPrd_Type: item.type, 3164 cOrdPrd_Code: item.code, 3165 cOrdPrd_Note: item.note, 3166 cOrdPrd_GUID: item.salelnGuid, 3167 cOrdPrd_ShippingID: item.shpId, 3168 cOrdPrd_ShippingCost: item.totalShipping, 3169 cOrdPrd_MetaData: item.metadata, 3170 cOrdPrd_Discount: item.discount 3171 }); 3172 } 3173 var obj = { 3174 "Description": name, 3175 "order": lines 3176 } 3177 $.ajax({
3178 url: '/account/itemlink', 3179 type: 'POST', 3180 headers: { 3181 'Content-Type': 'application/json', 3182 'x-csrf-token': csrf_token 3183 }, 3184 data: JSON.stringify({ 3185 _csrf: csrf_token, 3186 metadata: obj, 3187 type: "25", 3188 description: name, 3189 flags: 0, 3190 action: "save" 3191 }), 3192 dataType: 'json', 3193 success: function(d) { 3194 if (cb) { 3195 cb(null, d); 3196 } 3197 }, 3198 failure: function(d) { 3199 if (cb) { 3200 cb("Error saving list - please try a different list name", null); 3201 } 3202 } 3203 }); 3204 } 3205 }); 3206} 3207 3208app.deleteSavedList = function(listId, cb) { 3209 var m = this; 3210 $.ajax({ 3211 url: '/account/itemlink', 3212 type: 'POST', 3213 headers: { 3214 'Content-Type': 'application/json', 3215 'x-csrf-token': csrf_token 3216 }, 3217 data: JSON.stringify({ 3218 _csrf: csrf_token, 3219 itlId: listId, 3220 action: "delete" 3221 }), 3222 dataType: 'json', 3223 success: function(d) { 3224 if (cb) { 3225 cb(null, "List deleted"); 3226 } 3227 }, 3228 failure: function() { 3229 if (cb) { 3230 cb("Could not delete list", null); 3231 } 3232 } 3233 }); 3234} 3235 3236app.saveDraftSale = function(cb) { 3237 var m = this; 3238 3239 var options = { 3240 startkey: "saleline_" + m.ls.saleGuid, 3241 endkey: "saleline_" + m.ls.saleGuid + "\uffff", 3242 include_docs: true 3243 }; 3244 3245 m.db.allDocs(options, function(err, doc) { 3246 if (!err) { 3247 var lines = []; 3248 for (var i = 0; i < doc.rows.length; i++) { 3249 var item = doc.rows[i].doc; 3250 lines.push({ 3251 prdId: item.prdId, 3252 qty: item.qty, 3253 pmmId: item.pmmId, 3254 pmiId: item.pmiId, 3255 text: item.text, 3256 type: item.type, 3257 code: item.code, 3258 note: item.note, 3259 meta: item.metadata 3260 }); 3261 } 3262 var dataStr = JSON.stringify(lines); 3263 var currentHash = app.hashCode(dataStr); 3264 3265 if (app.lastDraftHash != app.hashCode(dataStr)) { 3266 app.lastDraftHash = currentHash; 3267 $.ajax({
3268 url: '/api/sale/draft', 3269 type: 'POST', 3270 headers: { 3271 'Content-Type': 'application/json', 3272 'x-csrf-token': csrf_token 3273 }, 3274 data: JSON.stringify({ 3275 _csrf: csrf_token, 3276 saleLines: dataStr 3277 }), 3278 dataType: 'json', 3279 success: function(d) { 3280 if (cb) { 3281 cb(null, d); 3282 } 3283 }, 3284 failure: function(d) { 3285 if (cb) { 3286 cb("Error saving draft sale", null); 3287 } 3288 } 3289 }); 3290 } 3291 } 3292 }); 3293} 3294 3295app.loadDraftSale = function(cb) { 3296 var m = this; 3297 3298 $.ajax({ 3299 url: '/api/sale/draft', 3300 type: 'GET', 3301 contentType: 'application/json', 3302 data: JSON.stringify({ 3303 _csrf: csrf_token 3304 }), 3305 dataType: 'json', 3306 success: function(d) { 3307 if (cb) { 3308 cb(null, d); 3309 } 3310 }, 3311 failure: function(d) { 3312 if (cb) { 3313 cb("Error loading draft sale", null); 3314 } 3315 } 3316 }); 3317} 3318 3319app.checkCartDraftOrders = function(cb) { 3320 if (app.ls.total.itemCount == 0) { 3321 app.loadDraftSale(function(err, data) { 3322 if (err) { 3323 if (cb) { 3324 cb("Error getting draft sale", null); 3325 return; 3326 } 3327 } else { 3328 if (data.success) { 3329 var item = $('#cart-draft-sale-reload'); 3330 var allItems = []; 3331 3332 $('body').append('<div id="cart-draft-sale-reload" style="display:none">' + data.html + '</div>'); 3333 $("#cart-draft-sale-reload input.product-qty").each(function(index) { 3334 var item = $(this); 3335 if (item) { 3336 if (item.val() > 0) { 3337 allItems.push(item); 3338 } 3339 } 3340 }); 3341 3342 if (allItems.length > 0) { 3343 app.suppressCartNotify = true; 3344 var numItems = allItems.length; 3345 var currentItem = 0; 3346 var nextItem = function() { 3347 if (numItems > currentItem) { 3348 var item = allItems[currentItem++]; 3349 app.addItemToCart(item, nextItem); 3350 } else { 3351 console.log("Draft sale with " + numItems + " restored."); 3352 app.suppressCartNotify = false; 3353 cb(null, "Draft sale with " + numItems + " restored."); 3354 return; 3355 } 3356 } 3357 nextItem(); 3358 } else { 3359 // no items 3360 cb(null, "No draft sale items"); 3361 } 3362 } else { 3363 cb("No data", null); 3364 } 3365 } 3366 }); 3367 } else { 3368 cb("Already have cart entries", null); 3369 return; 3370 } 3371} 3372 3373app.registerCartEvents();
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.