1/** 2 * Magento 3 * 4 * NOTICE OF LICENSE 5 * 6 * This source file is subject to the Academic Free License (AFL 3.0) 7 * that is bundled with this package in the file LICENSE_AFL.txt. 8 * It is also available through the world-wide-web at this URL: 9 * http://opensource.org/licenses/afl-3.0.php 10 * If you did not receive a copy of the license and are unable to 11 * obtain it through the world-wide-web, please send an email 12 * to [email protected] so we can send you a copy immediately. 13 * 14 * DISCLAIMER 15 * 16 * Do not edit or add to this file if you wish to upgrade Magento to newer 17 * versions in the future. If you wish to customize Magento for your 18 * needs please refer to http://www.magento.com for more information. 19 * 20 * @category design 21 * @package base_default 22 * @copyright Copyright (c) 2006-2016 X.commerce, Inc. and affiliates (http://www.magento.com) 23 * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) 24 */ 25if(typeof Product=='undefined') { 26 var Product = {}; 27} 28/**************************** BUNDLE PRODUCT **************************/ 29Product.Bundle = Class.create(); 30Product.Bundle.prototype = { 31 initialize: function(config){ 32 this.config = config; 33 34 // Set preconfigured values for correct price base calculation 35 if (config.defaultValues) { 36 for (var option in config.defaultValues) { 37 if (this.config['options'][option].isMulti) { 38 var selected = new Array(); 39 for (var i = 0; i < config.defaultValues[option].length; i++) { 40 selected.push(config.defaultValues[option][i]); 41 } 42 this.config.selected[option] = selected; 43 } else { 44 this.config.selected[option] = new Array(config.defaultValues[option] + ""); 45 } 46 } 47 } 48 49 this.reloadPrice(); 50 }, 51 changeSelection: function(selection){ 52 var parts = selection.id.split('-'); 53 if (this.config['options'][parts[2]].isMulti) { 54 selected = new Array(); 55 if (selection.tagName == 'SELECT') { 56 for (var i = 0; i < selection.options.length; i++) { 57 if (selection.options[i].selected && selection.options[i].value != '') { 58 selected.push(selection.options[i].value); 59 } 60 } 61 } else if (selection.tagName == 'INPUT') { 62 selector = parts[0]+'-'+parts[1]+'-'+parts[2]; 63 selections = $$('.'+selector); 64 for (var i = 0; i < selections.length; i++) { 65 if (selections[i].checked && selections[i].value != '') { 66 selected.push(selections[i].value); 67 } 68 } 69 } 70 this.config.selected[parts[2]] = selected; 71 } else { 72 if (selection.value != '') { 73 this.config.selected[parts[2]] = new Array(selection.value); 74 } else { 75 this.config.selected[parts[2]] = new Array(); 76 } 77 this.populateQty(parts[2], selection.value); 78 var tierPriceElement = $('bundle-option-' + parts[2] + '-tier-prices'), 79 tierPriceHtml = ''; 80 if (selection.value != '' && this.config.options[parts[2]].selections[selection.value].customQty == 1) { 81 tierPriceHtml = this.config.options[parts[2]].selections[selection.value].tierPriceHtml; 82 } 83 tierPriceElement.update(tierPriceHtml); 84 } 85 this.reloadPrice(); 86 }, 87 88 reloadPrice: function() { 89 var calculatedPrice = 0; 90 var dispositionPrice = 0; 91 var includeTaxPrice = 0; 92 93 for (var option in this.config.selected) { 94 if (this.config.options[option]) { 95 for (var i=0; i < this.config.selected[option].length; i++) { 96 var prices = this.selectionPrice(option, this.config.selected[option][i]); 97 calculatedPrice += Number(prices[0]); 98 dispositionPrice += Number(prices[1]); 99 includeTaxPrice += Number(prices[2]); 100 } 101 } 102 } 103 104 //Tax is calculated in a different way for the the TOTAL BASED method 105 //We round the taxes at the end. Hence we do the same for consistency 106 //This variable is set in the bundle.phtml 107 if (taxCalcMethod == CACL_TOTAL_BASE) { 108 var calculatedPriceFormatted = calculatedPrice.toFixed(10); 109 var includeTaxPriceFormatted = includeTaxPrice.toFixed(10); 110 var tax = includeTaxPriceFormatted - calculatedPriceFormatted; 111 calculatedPrice = includeTaxPrice - Math.round(tax * 100) / 100; 112 } 113
114 //make sure that the prices are all rounded to two digits 115 //this is needed when tax calculation is based on total for dynamic 116 //price bundle product. For fixed price bundle product, the rounding 117 //needs to be done after option price is added to base price 118 if (this.config.priceType == '0') { 119 calculatedPrice = Math.round(calculatedPrice*100)/100; 120 dispositionPrice = Math.round(dispositionPrice*100)/100; 121 includeTaxPrice = Math.round(includeTaxPrice*100)/100; 122 123 } 124 125 var event = $(document).fire('bundle:reload-price', { 126 price: calculatedPrice, 127 priceInclTax: includeTaxPrice, 128 dispositionPrice: dispositionPrice, 129 bundle: this 130 }); 131 if (!event.noReloadPrice) { 132 optionsPrice.specialTaxPrice = 'true'; 133 optionsPrice.changePrice('bundle', calculatedPrice); 134 optionsPrice.changePrice('nontaxable', dispositionPrice); 135 optionsPrice.changePrice('priceInclTax', includeTaxPrice); 136 optionsPrice.reload(); 137 } 138 139 return calculatedPrice; 140 }, 141 142 selectionPrice: function(optionId, selectionId) { 143 if (selectionId == '' || selectionId == 'none') { 144 return 0; 145 } 146 var qty = null; 147 var tierPriceInclTax, tierPriceExclTax; 148 if (this.config.options[optionId].selections[selectionId].customQty == 1 && !this.config['options'][optionId].isMulti) { 149 if ($('bundle-option-' + optionId + '-qty-input')) { 150 qty = $('bundle-option-' + optionId + '-qty-input').value; 151 } else { 152 qty = 1; 153 } 154 } else { 155 qty = this.config.options[optionId].selections[selectionId].qty; 156 } 157 if (this.config.priceType == '0') { 158 price = this.config.options[optionId].selections[selectionId].price; 159 tierPrice = this.config.options[optionId].selections[selectionId].tierPrice; 160 161 for (var i=0; i < tierPrice.length; i++) { 162 if (Number(tierPrice[i].price_qty) <= qty && Number(tierPrice[i].price) <= price) { 163 price = tierPrice[i].price; 164 tierPriceInclTax = tierPrice[i].priceInclTax; 165 tierPriceExclTax = tierPrice[i].priceExclTax; 166 } 167 } 168 } else { 169 selection = this.config.options[optionId].selections[selectionId]; 170 if (selection.priceType == '0') { 171 price = selection.priceValue; 172 } else { 173 price = (this.config.basePrice*selection.priceValue)/100; 174 } 175 } 176 //price += this.config.options[optionId].selections[selectionId].plusDisposition; 177 //price -= this.config.options[optionId].selections[selectionId].minusDisposition; 178 //return price*qty; 179 var disposition = this.config.options[optionId].selections[selectionId].plusDisposition + 180 this.config.options[optionId].selections[selectionId].minusDisposition; 181 182 if (this.config.specialPrice) { 183 newPrice = (price*this.config.specialPrice)/100; 184 price = Math.min(newPrice, price); 185 } 186 187 selection = this.config.options[optionId].selections[selectionId]; 188 if (tierPriceInclTax !== undefined && tierPriceExclTax !== undefined) { 189 priceInclTax = tierPriceInclTax; 190 price = tierPriceExclTax; 191 } else if (selection.priceInclTax !== undefined) { 192 priceInclTax = selection.priceInclTax; 193 price = selection.priceExclTax !== undefined ? selection.priceExclTax : selection.price; 194 } else { 195 priceInclTax = price; 196 } 197 198 if (this.config.priceType == '1' || taxCalcMethod == CACL_TOTAL_BASE) { 199 var result = new Array(price*qty, disposition*qty, priceInclTax*qty); 200 return result; 201 } 202 else if (taxCalcMethod == CACL_UNIT_BASE) { 203 price = (Math.round(price*100)/100).toString(); 204 disposition = (Math.round(disposition*100)/100).toString(); 205 priceInclTax = (Math.round(priceInclTax*100)/100).toString(); 206 var result = new Array(price*qty, disposition*qty, priceInclTax*qty); 207 return result; 208 } else { //taxCalcMethod == CACL_ROW_BASE) 209 price = (Math.round(price*qty*100)/100).toString(); 210 disposition = (Math.round(disposition*qty*100)/100).toString(); 211 priceInclTax = (Math.round(priceInclTax*qty*100)/100).toString(); 212 var result = new Array(price, disposition, priceInclTax); 213 return result; 214 } 215 }, 216 217 populateQty: function(optionId, selectionId){ 218 if (selectionId == '' || selectionId == 'none') { 219 this.showQtyInput(optionId, '0', false); 220 return; 221 } 222 if (this.config.options[optionId].selections[selectionId].customQty == 1) { 223 this.showQtyInput(optionId, this.config.options[optionId].selections[selectionId].qty, true); 224 } else { 225 this.showQtyInput(optionId, this.config.options[optionId].selections[selectionId].qty, false); 226 } 227 }, 228 229 showQtyInput: function(optionId, value, canEdit) { 230 elem = $('bundle-option-' + optionId + '-qty-input'); 231 elem.value = value; 232 elem.disabled = !canEdit; 233 if (canEdit) { 234 elem.removeClassName('qty-disabled'); 235 } else { 236 elem.addClassName('qty-disabled'); 237 } 238 }, 239 240 changeOptionQty: function (element, event) { 241 var checkQty = true; 242 if (typeof(event) != 'undefined') { 243 if (event.keyCode == 8 || event.keyCode == 46) { 244 checkQty = false;
245 } 246 } 247 if (checkQty && (Number(element.value) == 0 || isNaN(Number(element.value)))) { 248 element.value = 1; 249 } 250 parts = element.id.split('-'); 251 optionId = parts[2]; 252 if (!this.config['options'][optionId].isMulti) { 253 selectionId = this.config.selected[optionId][0]; 254 this.config.options[optionId].selections[selectionId].qty = element.value*1; 255 this.reloadPrice(); 256 } 257 }, 258 259 validationCallback: function (elmId, result){ 260 if (elmId == undefined || $(elmId) == undefined) { 261 return; 262 } 263 var container = $(elmId).up('ul.options-list'); 264 if (typeof container != 'undefined') { 265 if (result == 'failed') { 266 container.removeClassName('validation-passed'); 267 container.addClassName('validation-failed'); 268 } else { 269 container.removeClassName('validation-failed'); 270 container.addClassName('validation-passed'); 271 } 272 } 273 } 274}
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.