1/** 2 * СÑаÑиÑÐ½Ð°Ñ Ð»Ð¾Ð³Ð¸ÐºÐ° каÑÑоÑки ÑоваÑа (catalog.element.claude). 3 * 4 * ÐдеÑÑ Ð»ÐµÐ¶Ð°Ñ methods, computed, Ñ Ñки и watch Vue-компоненÑа product-detail. 5 * Ðод одинаков Ð´Ð»Ñ Ð»Ñбого ÑоваÑа и не ÑодеÑÐ¶Ð¸Ñ ÑеÑвеÑнÑÑ Ð²ÑÑавок, поÑÑÐ¾Ð¼Ñ 6 * вÑнеÑен из inline-ÑкÑипÑа в оÑделÑнÑй Ñайл: бÑаÑÐ·ÐµÑ ÐºÐµÑиÑÑÐµÑ ÐµÐ³Ð¾ и не 7 * ÑазбиÑÐ°ÐµÑ Ð·Ð°Ð½Ð¾Ð²Ð¾ на каждой каÑÑоÑке. 8 * 9 * Ðинамика â data Ñ Ð´Ð°Ð½Ð½Ñми ÑоваÑа и Ñам Ñаблон â оÑÑалаÑÑ Ð² template.php. 10 * 11 * Файл подклÑÑаеÑÑÑ Ñ ?v=filemtime, поÑÑÐ¾Ð¼Ñ Ð¿Ð¾Ñле пÑавок ÐºÐµÑ ÑбÑаÑÑваеÑÑÑ Ñам. 12 */ 13 14function pluralForm(n, forms) { 15 return n % 10 == 1 && n % 100 != 11 ? forms[0] : (n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? forms[1] : forms[2]); 16} 17 18var tobasket = 0; 19 20// ÐпÑимизаÑиÑ: debounce Ð´Ð»Ñ ÑаÑÑÑÑ Ð²Ñзовов 21function debounce(fn, delay) { 22 let timer = null; 23 return function(...args) { 24 clearTimeout(timer); 25 timer = setTimeout(() => fn.apply(this, args), delay); 26 }; 27} 28 29// ÐпÑимизаÑиÑ: кÑÑ Ð´Ð»Ñ Ð·Ð°Ð¿ÑоÑов 30const requestCache = new Map(); 31const CACHE_TTL = 300000; // 5 минÑÑ 32 33// РазмеÑка ÑпиÑка оÑзÑвов: ÑеÑÐ²ÐµÑ Ð¾ÑдаÑÑ ÐµÑ ÑкÑÑÑÑм блоком в обÑÑном DOM (Ñади 34// индекÑаÑии). Таб пеÑеÑоздаÑÑÑÑ ÑеÑез v-if, поÑÑÐ¾Ð¼Ñ Ð´ÐµÑжим ÑазмеÑÐºÑ Ð·Ð´ÐµÑÑ Ð¸ 35// подÑÑавлÑем заново пÑи каждом оÑкÑÑÑии вкладки. 36let reviewsHtmlCache = null; 37 38// ХаÑакÑеÑиÑÑики ÑеÑÐ²ÐµÑ Ð¾ÑдаÑÑ ÑкÑÑÑÑм блоком в обÑÑном DOM (Ñади индекÑаÑии). 39// ÐабиÑаем ÑазмеÑÐºÑ ÑÑда один Ñаз и подÑÑавлÑем в Ñаб пÑи каждом оÑкÑÑÑии. 40let techHtmlCache = null; 41 42export const cardOptions = { 43 methods: { 44 // ÐпÑимизаÑиÑ: вÑÑиÑление summarRRC вÑнеÑено в меÑод Ñ ÐºÑÑиÑованием 45 calculateSummarRRC() { 46 let summarRRC = 0; 47 let isSumelement = true; 48 49 if (this.basketItems) { 50 for (let key in this.basketItems) { 51 if (this.basketItems[key].ID == this.currentSku?.ID) { 52 isSumelement = false; 53 } 54 summarRRC += this.basketItems[key].PRICE_RRC * this.basketItems[key].QUANTITY; 55 } 56 } 57 58 if (isSumelement && this.currentSku?.PRICE_MATRIX?.RRC?.DISCOUNT_VALUE && this.dataSkuJs[this.currentSku.ID]) { 59 summarRRC += this.currentSku.PRICE_MATRIX.RRC.DISCOUNT_VALUE * (this.dataSkuJs[this.currentSku.ID].QUANTITY_DEFAULT - 1); 60 } 61 62 return summarRRC; 63 }, 64 65 // ÐпÑимизаÑиÑ: getSkuDataPrice Ñ Ð·Ð°ÑиÑой Ð¾Ñ Ð¿Ð¾Ð²ÑоÑного вÑзова 66 getSkuDataPrice() { 67 if (this.isUpdating || !this.currentSku) return; 68 69 const data = []; 70 const sku = this.currentSku; 71 72 this.priceLine.forEach((price) => { 73 const priceType = price.CODE; 74 const priceNew = sku.new_price_set?.[priceType]; 75 if (!priceNew) return; 76 77 if (price.ID == 40 && ['TIKKURILA', 'FINNCOLOR РоÑÑиÑ', 'ТÐÐС РоÑÑиÑ'].includes(this.brand.NAME)) { 78 return; 79 } 80 81 let isHidden = sku.MARKETING && priceType !== 'RRC'; 82 let requestPrice = sku.REQUEST_PRICES?.includes(priceType) && !this.brand.SHOW_ALL_PRICES; 83 84 let oldPrice, currentPrice, iterator, classPrice; 85 86 if ((sku.SHOW_YM_MRC && !requestPrice) && priceNew.NEW_VALUE < priceNew.OLD_VALUE) { 87 oldPrice = priceNew.OLD_VALUE; 88 currentPrice = priceNew.NEW_VALUE; 89 isHidden = false;
90 iterator = 1; 91 classPrice = 'new_price'; 92 } else { 93 const skuPriceRrcOld = parseFloat(sku.new_price_set?.RRC_OLD?.VALUE || 0); 94 if (parseInt(sku.MARKETING?.DISCOUNTNTH) !== 1) { 95 oldPrice = skuPriceRrcOld > parseFloat(priceNew.VALUE) ? skuPriceRrcOld : null; 96 currentPrice = priceNew.VALUE; 97 iterator = 2; 98 classPrice = 'price'; 99 } else { 100 oldPrice = skuPriceRrcOld; 101 currentPrice = priceNew.VALUE; 102 iterator = 3; 103 classPrice = 'new_price'; 104 } 105 } 106 107 data.push({ 108 old_price: oldPrice, 109 price: currentPrice, 110 hidden: isHidden, 111 id: price.ID, 112 priceType, 113 iterator, 114 class_price: classPrice, 115 bonus_price: priceNew.BONUS_RUB, 116 price_cancel: isHidden ? 'set-price-cancel' : '' 117 }); 118 }); 119 120 this.dataPrice = data; 121 122 // ÐпÑимизаÑиÑ: оÑложенное обновление DOM 123 this.$nextTick(() => { 124 this.updatePriceLine(); 125 }); 126 }, 127 128 // ÐпÑимизаÑиÑ: updatePriceLine Ñ Ð·Ð°ÑиÑой 129 updatePriceLine() { 130 if (this.isUpdating) return; 131 132 this.$nextTick(() => { 133 $(".info-box-card-price [data-price-id]").each(function (index, el) { 134 if ($(el).find(".new_price, .price").hasClass('set-price-cancel')) { 135 $(el).removeClass("price_active").addClass("price_hidden"); 136 $(el).parent().find("[data-price-id]:first").addClass("price_active").removeClass("price_hidden"); 137 } 138 }); 139 }); 140 }, 141 142 // ÐпÑимизаÑиÑ: getDiscontLable без forceUpdate 143 getDiscontLable(sku) { 144 if (!sku?.MARKETING) return false; 145 146 const RRC = sku.new_price_set?.RRC; 147 if (!RRC) return false; 148 149 const value = Math.floor((1 - RRC.NEW_VALUE / RRC.OLD_VALUE).toFixed(2) * 100); 150 const title = Object.values(sku.MARKETING)[0].TITLE; 151 const text = title.includes(value) ? title : value + "% " + title; 152 const smallLable = value ? "-" + value + "%" : "%"; 153 154 return { 155 smallLable, 156 text, 157 link: Object.values(sku.MARKETING)[0].URL 158 }; 159 }, 160 161 getCurrentDiscontLable() { 162 const discont = this.getDiscontLable(this.currentSku); 163 this.visibleMainMarketing = discont; 164 return discont; 165 }, 166 167 // ÐпÑимизаÑиÑ: requestReviews Ñ ÐºÑÑиÑованием 168 async requestReviews() { 169 if (this.reviewsRequested) return; 170 this.reviewsRequested = true; 171 172 const cacheKey = `reviews_${this.PRODUCT_ID}`; 173 const cached = requestCache.get(cacheKey); 174 175 if (cached && (Date.now() - cached.timestamp < CACHE_TTL)) { 176 this.reviews = cached.data; 177 return; 178 } 179 180 try { 181 const response = await axios.post( 182 "/local/php_interface/ajax/ajaxReviewsJson.php?clear_cache=Y", 183 { PRODUCT_ID: this.PRODUCT_ID } 184 ); 185 186 requestCache.set(cacheKey, { 187 data: response.data, 188 timestamp: Date.now() 189 }); 190 191 this.reviews = response.data; 192 } catch (e) { 193 this.reviewsRequested = false;
194 console.log("Ðе загÑÑзилиÑÑ Ð¾ÑзÑвÑ"); 195 } 196 }, 197 198 // ÐпÑимизаÑиÑ: обÑабоÑÑики Ñ debounce 199 handleScroll: debounce(function(event) { 200 this.scroll = window.scrollY; 201 202 const element = document.querySelector('.product-box'); 203 if (element) { 204 const rect = element.getBoundingClientRect(); 205 this.scrollMAX = rect.bottom + window.pageYOffset - 600; 206 } 207 208 this.iOffset = window.scrollY || document.documentElement.scrollTop; 209 }, 16), 210 211 handleResize: debounce(function() { 212 this.isSmallScreen = window.innerWidth <= 1200; 213 this.isIPad = window.innerWidth >= 1100 && window.innerWidth <= 1200; 214 }, 100), 215 216 // ÐÑÑалÑнÑе меÑÐ¾Ð´Ñ Ð±ÐµÐ· изменений 217 getSkuQuantity(quantity, minus = false) { 218 const item = this.dataSkuJs[this.currentSku.ID]; 219 if (minus) { 220 item.QUANTITY_DEFAULT = Math.max(item.QUANTITY_DEFAULT - quantity, 1); 221 } else { 222 item.QUANTITY_DEFAULT += quantity; 223 } 224 }, 225 226 getCurrentPrice() { 227 if (this.currentSku?.MARKETING) { 228 return this.currentSku?.new_price_set?.RRC?.NEW_VALUE; 229 } 230 return this.currentSku?.new_price_set?.[this.getCurrentPriceType]?.NEW_VALUE; 231 }, 232 233 getSumDiscount() { 234 var discount = (this.currentSku?.new_price_set?.[this.getCurrentPriceType]?.OLD_VALUE || 0) - (this.getCurrentPrice() || 0); 235 if(discount==0){ 236 discount = this.currentSku?.new_price_set.RRC.OLD_VALUE-this.getCurrentPrice(); 237 } 238 return (discount); 239 }, 240 241 showPopup() { 242 this.img.showPopup = true; 243 $('#main .container .header_wrapper').addClass('lower'); 244 }, 245 246 initSlider() { 247 const $slider = $('.img-box [data-js="slick-slider"]'); 248 if (!$slider.length) return; 249 250 $slider.slick({ 251 dots: true, 252 arrows: false, 253 autoplay: false, 254 infinite: true, 255 slidesToShow: 1, 256 slidesToScroll: 1, 257 lazyLoad: 'ondemand', 258 // Ð¡Ð²Ð¾Ñ ARIA-ÑазмеÑка slick не пÑÐ¾Ñ Ð¾Ð´Ð¸Ñ Ð¿ÑовеÑÐºÑ Ð´Ð¾ÑÑÑпноÑÑи 259 // (role=tablist Ñ Ð½ÐµÐ´Ð¾Ð¿ÑÑÑимÑми деÑÑми, aria-selected на li, 260 // aria-hidden повеÑÑ ÑÑÑлок). ÐиÑÑание Ñ ÐºÐ»Ð°Ð²Ð¸Ð°ÑÑÑÑ Ð¸ мÑÑÑÑ 261 // пÑи ÑÑом не менÑеÑÑÑ. 262 accessibility: false 263 }); 264 265 // ТоÑки пеÑеклÑÑÐµÐ½Ð¸Ñ â кнопки без ÑекÑÑа, подпиÑÑваем Ð¸Ñ Ñами. 266 // Ðаодно Ñнимаем aria-hidden, коÑоÑÑй slick ÑÑÐ°Ð²Ð¸Ñ Ð½ÐµÐ°ÐºÑивнÑм 267 // ÑоÑкам: кнопка внÑÑÑи оÑÑаÑÑÑÑ Ð´Ð¾ÑÑÑпной Ñ ÐºÐ»Ð°Ð²Ð¸Ð°ÑÑÑÑ, и 268 // полÑÑаеÑÑÑ ÑлеменÑ, ÑпÑÑÑаннÑй Ð¾Ñ ÑÑениÑ, но доÑÑижимÑй Ñабом. 269 const fixDots = () => { 270 $slider.find('.slick-dots li').each(function (index) { 271 this.removeAttribute('aria-hidden'); 272 const button = this.querySelector('button'); 273 if (button) { 274 button.setAttribute('aria-label', 'ФоÑо ' + (index + 1)); 275 } 276 }); 277 }; 278 fixDots(); 279 $slider.on('afterChange setPosition', fixDots); 280 281 $slider.on('afterChange', (event, slick, currentSlide) => { 282 const images = this.getColectionImg; 283 if (images[currentSlide]) { 284 this.selectImg(images[currentSlide]); 285 } 286 }); 287 }, 288 289 updateBasket(ELEMENT_ID, QUANTITY) { 290 const smallBasket = $('.head_basket_drop form'); 291 const currentItem = smallBasket.find(`[data-product-id=${ELEMENT_ID}]`); 292 293 if (currentItem.is('tr')) { 294 currentItem.find('[data-quantity]').val(QUANTITY); 295 } else if (currentItem.is('input')) { 296 currentItem.val(QUANTITY); 297 } 298 299 if (QUANTITY > 0) { 300 this.currentBasketItem.QUANTITY = QUANTITY; 301 this.currentBasketItem.PRICE_RRC = $(currentItem).data("pricerrc"); 302 } else { 303 this.basketItems = this.basketItems?.filter((item) => item.ID !== this.currentBasketItem.ID); 304 this.currentBasketItem = this.inBasket(); 305 currentItem.remove(); 306 } 307 308 obBasket.refreshBasket(smallBasket[0]); 309 }, 310 311 inBasket() { 312 return this.basketItems?.find((item) => item.ID === this.currentSku?.ID); 313 }, 314 315 toggleBlock(blockNumber) { 316 this.showBlock[blockNumber] = !this.showBlock[blockNumber]; 317 }, 318 319 addCompare() {}, 320 321 addToWishList() { 322 obWishList.click(this); 323 }, 324 325 showShopCount(ELEMENT_ID) { 326 obDetailProduct.showQuantity(ELEMENT_ID); 327 }, 328 329 pushEcommerceDetail() { 330 window.dataLayer = window.dataLayer || []; 331 dataLayer.push({ 332 'ecommerce': { 333 'currencyCode': 'RUB', 334 'detail': { 335 'products': [this.currentSku?.GTM], 336 }, 337 }, 338 'goods_id': this.currentSku?.ID, 339 'goods_price': this.currentSku?.new_price_set?.RRC?.VALUE, 340 'page_type': 'product', 341 'event': 'pixel-mg-event', 342 'pixel-mg-event-category': 'Enhanced Ecommerce', 343 'pixel-mg-event-action': 'Product Details', 344 'pixel-mg-event-non-interaction': 'True' 345 }); 346 }, 347 348 pushEcommerceAddBasket(currentSku, QUANTITY) { 349 window.dataLayer = window.dataLayer || []; 350 if (!QUANTITY) QUANTITY = 1; 351 currentSku.GTM.quantity = QUANTITY; 352 dataLayer.push({ 353 "ecommerce": { 354 'currencyCode': 'RUB', 355 "add": { 356 "products": [{ 357 "id": currentSku.ID, 358 "name": currentSku.GTM.name, 359 "brand": currentSku.GTM.brand, 360 "category": currentSku.GTM.category, 361 "price": currentSku.GTM.price, 362 "variant": currentSku.GTM.variant, 363 "quantity": currentSku.GTM.quantity 364 }], 365 } 366 }, 367 'goods_id': currentSku.ID, 368 'goods_price': currentSku.GTM.price, 369 'page_type': 'add_product', 370 'event': 'pixel-mg-event', 371 'pixel-mg-event-category': 'Enhanced Ecommerce', 372 'pixel-mg-event-action': 'Adding a Product to a Shopping Cart', 373 'pixel-mg-event-non-interaction': 'False' 374 }); 375 }, 376 377 pushEcommerceRemove(currentSku, QUANTITY) { 378 window.dataLayer = window.dataLayer || []; 379 if (!QUANTITY) QUANTITY = 1; 380 currentSku.GTM.quantity = QUANTITY; 381 dataLayer.push({ 382 "ecommerce": { 383 "currencyCode": "RUB", 384 "remove": { 385 "products": [{ 386 "id": currentSku.ID, 387 "name": currentSku.GTM.name, 388 "brand": currentSku.GTM.brand, 389 "category": currentSku.GTM.category, 390 "price": currentSku.GTM.price, 391 "variant": currentSku.GTM.variant, 392 "quantity": currentSku.GTM.quantity 393 }] 394 } 395 }, 396 'goods_id': currentSku.ID, 397 'goods_price': currentSku.GTM.price, 398 "page_type": "add_product", 399 "event": "pixel-mg-event", 400 "pixel-mg-event-category": "Enhanced Ecommerce", 401 "pixel-mg-event-action": "Adding a Product to a Shopping Cart", 402 "pixel-mg-event-non-interaction": "False" 403 }); 404 }, 405 406 addToBasket(ELEMENT_ID, QUANTITY, options = {}) { 407 var MF_COLOR = $('.MF_COLOR .property-filter-value.__active:first').index(); 408 tobasket = 1; 409
410 let colorParams = {}; 411 if (selectedColor && selectedColor[MF_COLOR]) { 412 colorParams = { 413 COLOR_ID: selectedColor[MF_COLOR].COLOR_ID, 414 COLOR_SKU_ID: selectedColor[MF_COLOR].COLOR_SKU_ID, 415 COLLECTION_NAME: selectedColor[MF_COLOR].COLLECTION_NAME, 416 COLLECTION_ID: selectedColor[MF_COLOR].COLLECTION_ID, 417 COLOR_NAME: selectedColor[MF_COLOR].COLOR_NAME, 418 HEX: selectedColor[MF_COLOR].HEX, 419 VOLUME: selectedColor[MF_COLOR].VOLUME, 420 COLOR_PRICE: selectedColorPRICE?.[MF_COLOR] 421 }; 422 } 423 424 return $.ajax({ 425 type: "POST", 426 url: "/local/components/art-fresh/sale.basket/ajax_new.php", 427 data: { 428 action: "add", 429 ELEMENT_ID, 430 QUANTITY, 431 ...colorParams 432 }, 433 timeout: 15000, 434 success: (data) => { 435 const $data = $(data); 436 console.log('123456'); 437 console.log($data); 438 const price = $data.find(`[data-product-id=${ELEMENT_ID}]`).data('price'); 439 const priceRRC = $data.find(`[data-product-id=${ELEMENT_ID}]`).data('pricerrc'); 440 441 obProduct.productAdded(ELEMENT_ID, true); 442 $('.icon-link.cart-link span').html(data); 443 $('.link-cart span').html(data); 444 obProduct.productShowPopup(ELEMENT_ID, false, QUANTITY, price); 445 446 $("[data-box-basket]").addClass("active"); 447 this.basketItems.push({ ID: ELEMENT_ID, QUANTITY, PRICE_RRC: priceRRC }); 448 this.$nextTick(() => this.applyTintPrice()); 449 }, 450 error: function () { 451 // ÐбÑабоÑка оÑибки 452 } 453 }); 454 }, 455 456 getCalcSkuBaseCode(sku) { 457 const candidates = [ 458 sku?.IB_BASE_ENUM, 459 sku?.FILTER_PROPS?.IB_BASE?.VALUE_XML_ID, 460 sku?.FILTER_PROPS?.IB_BASE?.VALUE_ENUM, 461 sku?.BASE_ENUM, 462 sku?.WEB_NAME, 463 sku?.NAME 464 ]; 465 466 for (const candidate of candidates) { 467 const value = String(candidate || '').trim().toUpperCase(); 468 if (!value) { 469 continue; 470 } 471 472 const match = value.match(/\b(BW|BC|TR|CLR|A|B|C)\b/); 473 if (match) { 474 return match[1]; 475 } 476 } 477 478 return ''; 479 }, 480 481 getCalcSkuVolume(sku) { 482 const rawVolume = sku?.OBEM_V_L ?? sku?.VOLUME ?? sku?.VES_MATERIALA ?? 0; 483 const volume = Number(String(rawVolume).replace(',', '.')); 484 return Number.isFinite(volume) ? volume : 0; 485 }, 486 487 resolveCalcBasketProductId(item) { 488 const requestedProductId = String(item?.product_id || '').trim(); 489 const requestedBase = String(item?.base || '').trim().toUpperCase(); 490 const requestedSize = Number(item?.size || 0); 491 492 if (requestedProductId) { 493 const byId = (this.skus || []).find((sku) => String(sku?.ID || '') === requestedProductId); 494 if (byId?.ID) return String(byId.ID); 495 } 496 497 if (!requestedBase || !Number.isFinite(requestedSize) || requestedSize <= 0) { 498 return ''; 499 } 500 501 const byBaseAndVolume = (this.skus || []).find((sku) => { 502 const skuBase = this.getCalcSkuBaseCode(sku); 503 const skuVolume = this.getCalcSkuVolume(sku); 504 return skuBase === requestedBase && Math.abs(skuVolume - requestedSize) < 0.0001; 505 }); 506 507 return byBaseAndVolume?.ID ? String(byBaseAndVolume.ID) : ''; 508 }, 509 510 getCalcColorPayload() { 511 const activeIndex = $('.MF_COLOR .property-filter-value.__active:first').index(); 512 const colorIndex = activeIndex >= 0 ? activeIndex : 0; 513 const colorData = typeof selectedColor !== 'undefined' ? selectedColor[colorIndex] : null; 514 const colorPrice = typeof selectedColorPRICE !== 'undefined' ? selectedColorPRICE[colorIndex] : null; 515 516 if (!colorData || typeof colorData !== 'object') return null; 517 518 return { 519 COLOR_ID: colorData.COLOR_ID, 520 COLOR_SKU_ID: colorData.COLOR_SKU_ID, 521 COLLECTION_NAME: colorData.COLLECTION_NAME, 522 COLLECTION_ID: colorData.COLLECTION_ID, 523 COLOR_NAME: colorData.COLOR_NAME, 524 HEX: colorData.HEX, 525 VOLUME: colorData.VOLUME, 526 COLOR_PRICE: colorPrice 527 }; 528 }, 529 530 async handleCalcAddToCart(event) { 531 const detail = event?.detail || {}; 532 const payload = detail.payload || {}; 533 const basketItems = Array.isArray(detail.basketItems) ? detail.basketItems : []; 534 const colorPayload = this.getCalcColorPayload(); 535 const newBasketItems = []; 536
537 basketItems.forEach((item) => { 538 const quantity = Number(item?.quantity || 0); 539 const productId = this.resolveCalcBasketProductId(item); 540 541 if (!productId || !Number.isFinite(quantity) || quantity <= 0) return; 542 543 newBasketItems.push({ 544 PRODUCT_ID: productId, 545 itemsUsed: quantity 546 }); 547 }); 548 549 if (!newBasketItems.length) { 550 const fallbackQuantity = Number(payload?.quantity || 0); 551 const fallbackProductId = this.resolveCalcBasketProductId({ 552 product_id: payload?.product_id || '', 553 base: payload?.base || '', 554 size: null 555 }); 556 557 if (fallbackProductId && Number.isFinite(fallbackQuantity) && fallbackQuantity > 0) { 558 newBasketItems.push({ 559 PRODUCT_ID: fallbackProductId, 560 itemsUsed: fallbackQuantity 561 }); 562 } 563 } 564 565 if (!newBasketItems.length) return; 566 567 await $.ajax({ 568 type: "POST", 569 url: "/local/components/art-fresh/sale.basket/ajax_new.php", 570 data: { 571 items: newBasketItems, 572 action: 'calc_basket_add', 573 BIG_BASKET: 1, 574 basket_new: 'Y', 575 sku: (this.skus || []).map(item => item.ID), 576 ...(colorPayload || {}) 577 }, 578 timeout: 15000, 579 success: (data) => { 580 const firstBasketItem = newBasketItems[0] || null; 581 const firstElementId = firstBasketItem?.PRODUCT_ID || this.currentSku?.ID || 0; 582 const firstQuantity = Number(firstBasketItem?.itemsUsed || payload?.quantity || 0) || 1; 583 const price = $(data).find(`[data-product-id=${firstElementId}]`).data('price'); 584 const priceRRC = $(data).find(`[data-product-id=${firstElementId}]`).data('pricerrc'); 585 586 if (firstElementId) { 587 obProduct.productAdded(firstElementId, true); 588 } 589 590 obBasket.changeBasket(data); 591 $('.icon-link.cart-link span').html(data); 592 $('.link-cart span').html(data); 593 594 if (firstElementId) { 595 obProduct.productShowPopup(firstElementId, false, firstQuantity, price); 596 } 597 598 $("[data-box-basket]").addClass("active"); 599 600 newBasketItems.forEach((basketItem) => { 601 this.basketItems.push({ 602 ID: basketItem.PRODUCT_ID, 603 QUANTITY: basketItem.itemsUsed, 604 PRICE_RRC: priceRRC 605 }); 606 }); 607 } 608 }); 609 610 this.closeCalcIframePopup(); 611 }, 612 613 openCalcIframe() { 614 const trigger = document.getElementById('openCalcIframe'); 615 if (!trigger) return; 616 617 const plainProducts = JSON.parse(JSON.stringify(this.calcIframe.products || {})); 618 const currentPriceType = String(this.getCurrentPriceType || this.PriceType?.PRICE_CODE || 'RRC'); 619 620 Object.keys(plainProducts).forEach((baseCode) => { 621 const product = plainProducts[baseCode]; 622 if (!product || typeof product !== 'object') return; 623 624 product.line_price = this.PriceType?.AVAILABLE_PRICES || {}; 625 product.selected_price_code = currentPriceType; 626 627 if (!Array.isArray(product.base_prices)) return; 628 629 product.base_prices = product.base_prices.map((pack) => { 630 const volumeKey = String(Number(pack?.volume ?? pack?.size ?? 0)); 631 const productSkuIds = Array.isArray(product.
631sku_ids) ? product.sku_ids.map(String) : []; 632 const matchedSku = (this.skus || []).find((sku) => { 633 const skuId = String(sku?.ID || ''); 634 return productSkuIds.includes(skuId) && String(this.getCalcSkuVolume(sku)) === volumeKey; 635 }); 636 637 const pricesFromSku = matchedSku ? { 638 RRC: this.getSkuPriceByCode(matchedSku, 'RRC'), 639 MRC: this.getSkuPriceByCode(matchedSku, 'MRC'), 640 PRC: this.getSkuPriceByCode(matchedSku, 'PRC'), 641 BOC1: this.getSkuPriceByCode(matchedSku, 'BOC1'), 642 } : {}; 643 644 const prices = { ...(pack?.prices || {}), ...pricesFromSku }; 645 const rrcPrice = Number(prices.RRC); 646 647 return { 648 ...pack, 649 prices, 650 price: Number.isFinite(rrcPrice) && rrcPrice >= 0 ? rrcPrice : pack.price 651 }; 652 }); 653 }); 654 655 trigger.setAttribute('data-products', JSON.stringify(plainProducts)); 656 if (String(this.currentSku?.ID || '').trim()) { 657 trigger.setAttribute('data-selected-sku-id', String(this.currentSku.ID).trim()); 658 } else { 659 trigger.removeAttribute('data-selected-sku-id'); 660 } 661 trigger.click(); 662 }, 663 664 getSkuPriceByCode(sku, priceCode) { 665 const priceData = sku?.new_price_set?.[priceCode]; 666 const priceValue = priceData?.NEW_VALUE ?? priceData?.VALUE ?? sku?.PRICE_MATRIX?.[priceCode]?.VALUE ?? 0; 667 const price = Number(priceValue); 668 return Number.isFinite(price) ? price : 0; 669 }, 670 671 closeCalcIframePopup() { 672 const closeBtn = document.getElementById('closeCalcIframe'); 673 if (closeBtn) closeBtn.click(); 674 }, 675 676 addToRezerv(ELEMENT_ID) { 677 if (!this.getQuantityShop) return false; 678 obDetailProduct.showQuantityRezerv(ELEMENT_ID); 679 }, 680 681 addToFastOrder(ELEMENT_ID) { 682 obFastOrder.get(ELEMENT_ID); 683 }, 684 685 plusMinus(data, value) { 686 return Math.max(data + value, 1); 687 }, 688 689 plusMinusMobile(data, value) { 690 return Math.max(data + value, 0); 691 }, 692 693 getCurrencyFormat(price) { 694 return BX.Currency.currencyFormat(price, 'RUB', true); 695 }, 696 697 getCurrencyFormat2(price) { 698 return BX.Currency.currencyFormat(price, 'RUB', true).replace('â½', ''); 699 }, 700 701 getPriceByOneVolume(price) { 702 return Math.ceil(price / this.getVolume); 703 }, 704 705 getMinPriceByMetr(price) { 706 return Math.ceil(this.getPriceByOneVolume(price) / this.Consumption?.TO); 707 }, 708 709 setTab(tabName) { 710 if (tabName === 'review') { 711 this.initializeAsync(); 712 } else { 713 // ÐÑкÑÑÑÑ Ð¾ÑзÑÐ²Ñ Ð¼Ð¾Ð¶Ð½Ð¾ и по оÑделÑÐ½Ð¾Ð¼Ñ Ð°Ð´ÑеÑÑ 714 // /product/<code>/reviews/ â ÑÑ Ð¾Ð´Ñ Ð½Ð° дÑÑгой Ñаб, ÑбиÑаем 715 // Ñ Ð²Ð¾ÑÑ. ÐбÑаÑно его не допиÑÑваем: Ñ ÐºÐ°ÑÑоÑки Ñ SKU 716 // Ñакого ÑоÑÑа Ð½ÐµÑ (urlrewrite Ð·Ð½Ð°ÐµÑ /reviews/ ÑолÑко без 717 // sku_), и ÑÑÑаниÑа по Ð½ÐµÐ¼Ñ Ð¾Ñдавала 404 â адÑÐµÑ Ð»Ð¾Ð¼Ð°Ð»ÑÑ 718 // пÑи пеÑезагÑÑзке и в оÑпÑавленной комÑ-Ñо ÑÑÑлке. 719 const currentUrl = window.location.href; 720 const cleanUrl = currentUrl.replace('reviews/', ''); 721 722 if (cleanUrl !== currentUrl) { 723 window.history.replaceState({}, '', cleanUrl); 724 } 725 } 726 727 this.tabActive = tabName; 728 729 // ТолÑко ÑепеÑÑ, поÑле ÑÐ¼ÐµÐ½Ñ tabActive: ÑÐ°Ð±Ñ ÑендеÑÑÑÑÑ ÑеÑез
730 // v-if, и конÑейнеÑÑ Ð¿Ð¾ÑвлÑÑÑÑÑ Ð² DOM лиÑÑ Ð½Ð° ÑÑом 731 // пеÑеÑиÑовÑвании. РанÑÑе $nextTick ÑÑабаÑÑвал до него. 732 if (tabName === 'review') { 733 this.$nextTick(() => this.fillReviewsList()); 734 } 735 if (tabName === 'tech') { 736 this.$nextTick(() => this.fillTechSpecs()); 737 } 738 }, 739 740 selectImg(currentImg) { 741 this.getColectionImg.forEach(img => img.active = false); 742 currentImg.active = true; 743 744 setTimeout(() => { 745 if (this.isOboi && !this.isSmallScreen) { 746 magnify("magnificZoom", 1.7); 747 } 748 }, 300); 749 }, 750 751 handleLeftArrowClick() { 752 const images = this.getColectionImg; 753 const currentIndex = images.findIndex(img => img.active); 754 const newIndex = currentIndex > 0 ? currentIndex - 1 : images.length - 1; 755 756 images[currentIndex].active = false; 757 images[newIndex].active = true; 758 }, 759 760 handleRightArrowClick() { 761 const images = this.getColectionImg; 762 const currentIndex = images.findIndex(img => img.active); 763 const newIndex = currentIndex < images.length - 1 ? currentIndex + 1 : 0; 764 765 images[currentIndex].active = false; 766 images[newIndex].active = true; 767 }, 768 769 handleKeyDown(event) { 770 if (!this.img.showPopup) return; 771 772 if (event.key === 'ArrowLeft') { 773 this.handleLeftArrowClick(); 774 } else if (event.key === 'ArrowRight') { 775 this.handleRightArrowClick(); 776 } else if (event.key === 'Escape') { 777 this.img.showPopup = false; 778 } 779 }, 780 781 popupAction(event) { 782 if (!event.target.closest('.popup-main-content')) { 783 this.img.showPopup = false; 784 } 785 }, 786 787 findSku(keyProp, prop) { 788 let skuNoFound; 789 let newSku; 790 791 for (let keySku in this.skus) { 792 let sku = this.skus[keySku]; 793 if (sku.FILTER_PROPS[keyProp]?.VALUE == prop.VALUE) { 794 skuNoFound = sku; 795 let goodFilter = true; 796 797 for (let keyCurrent in this.getCurrentPropsFilter) { 798 if (keyCurrent != keyProp) { 799 if (this.getCurrentPropsFilter[keyCurrent].VALUE != sku.FILTER_PROPS[keyCurrent]?.VALUE) { 800 goodFilter = false; 801 } 802 } 803 } 804 805 if (goodFilter) { 806 newSku = sku; 807 break; 808 } 809 } 810 } 811 812 this.applyTintPrice(); 813 814 return newSku || skuNoFound; 815 }, 816 817 /** 818 * СÑÑока Ñ Ñеной колеÑовки в пÑавой колонке. 819 * 820 * РанÑÑе ÑÑо бÑл побоÑнÑй ÑÑÑÐµÐºÑ findSku(), а findSku зовÑÑ Ð¿ÑивÑзки 821 * Ñаблона (showSkuLink, getPopupImg) â они оÑÑиÑовÑваÑÑÑÑ, ÑолÑко когда 822 * поÑеÑиÑÐµÐ»Ñ Ð´Ð¾ÑкÑÐ¾Ð»Ð»Ð¸Ñ Ð´Ð¾ ÑооÑвеÑÑÑвÑÑÑего блока. Ðз-за ÑÑого ÑвеÑ, 823 * пеÑеданнÑй в адÑеÑе (?barcode=â¦&colorid=â¦), поÑвл
823ÑлÑÑ Ð½Ðµ пÑи загÑÑзке, 824 * а поÑле пеÑвой пÑокÑÑÑки. ТепеÑÑ Ð¼ÐµÑод оÑделÑнÑй, и mounted() зовÑÑ ÐµÐ³Ð¾ 825 * ÑÑазÑ. 826 */ 827 applyTintPrice() { 828 let colordata = jQuery.parseJSON($('.color-box--rect.--gtm-event_opentinter').attr('data-tint-data')); 829 if (!colordata) { 830 colordata = jQuery.parseJSON($('.color-box--rect.--gtm-event_opentinter').attr('data-dom-data')); 831 } 832 833 var MF_COLOR = $('.MF_COLOR .property-filter-value.__active:first').index(); 834 if (MF_COLOR > 0 && fromColers) { 835 Object.defineProperty(selectedColor, 1, Object.getOwnPropertyDescriptor(selectedColor, 0)); 836 delete selectedColor[0]; 837 fromColers = false; 838 } 839 840 if (selectedColor[MF_COLOR] && colordata?.VOLUME) { 841 obColorer.showcolor(); 842 selectedColor[MF_COLOR].VOLUME = colordata.VOLUME; 843 844 var oldprice = parseInt($('.right-sidebar-price-row.--price-box .right-sidebar-price-title.--price-value').text() 845 .replace(' <span class="rub">â½</span>', '').replace(' ', '')); 846 847 848 849 var collerprice = selectedColorPRICE[MF_COLOR] 850 ? selectedColorPRICE[MF_COLOR] * selectedColor[MF_COLOR].VOLUME 851 : selectedColorPRICE1 * selectedColor[MF_COLOR].VOLUME; 852 853 if (!selectedColorPRICE[MF_COLOR]) { 854 selectedColorPRICE[MF_COLOR] = selectedColorPRICE1; 855 } 856 857 var price = collerprice + oldprice; 858 859 // Ð¦ÐµÐ½Ñ Ð·Ð° лиÑÑ Ð¸ за м² ÑанÑÑе ÑобиÑали из ÑекÑÑа блока «РаÑÑ Ð¾Ð´Â»: 860 // в нÑм бÑл оÑделÑнÑй ÑÐ»ÐµÐ¼ÐµÐ½Ñ .obiem Ñ Ð¾Ð±ÑÑмом банки («9л»). 861 // ÐÑÐ¾Ñ ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð·Ð°ÐºÐ¾Ð¼Ð¼ÐµÐ½ÑиÑован (Ñм. include/template_all_vue.php), 862 // клаÑÑ obiem пеÑÐµÐµÑ Ð°Ð» на ÑÑÑÐ¾ÐºÑ Â«1л = 5-11ÐÐ.Ð.», и 863 // Number('1л') ÑÑал даваÑÑ NaN. number_format пеÑаÑÐ°ÐµÑ NaN 864 // как 0 â обе колонки в ÑÑÑоке Ñ ÐºÐ¾Ð»ÐµÑовкой обнÑлÑлиÑÑ. 865 // СÑиÑаем Ñеми же ÑоÑмÑлами, ÑÑо и оÑÐ½Ð¾Ð²Ð½Ð°Ñ ÑÑÑока ÑÐµÐ½Ñ 866 // (Ñм. include/price_right_block.php): обÑÑм и ÑаÑÑ Ð¾Ð´ беÑÑм 867 // из даннÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñа, а не из ÑазмеÑки. 868 var priceL = this.getPriceByOneVolume(price); 869 var priceR = this.getMinPriceByMetr(price); 870 871 // Ðолонки показÑваем Ñовно Ñам же, где Ð¸Ñ Ð¿Ð¾ÐºÐ°Ð·ÑÐ²Ð°ÐµÑ Ð¾ÑÐ½Ð¾Ð²Ð½Ð°Ñ 872 // ÑÑÑока ÑенÑ, инаÑе на ÑоваÑÐ°Ñ Ð±ÐµÐ· обÑÑма ÑеÑка ÑазÑедеÑÑÑ. 873 var basePrice = this.currentSku?.new_price_set?.[this.getCurrentPriceType]?.NEW_VALUE; 874 var showPriceL = this.getPriceByOneVolume(basePrice) != 'Infinity'; 875 var showPriceR = this.getMinPriceByMetr(basePrice) != 'Infinity'; 876 877 $('.right-sidebar-price-row.new-price').remove(); 878 $('.right-sidebar-price-row.--price-box').after( 879 '<div class="right-sidebar-price-row new-price" data-unit-price="' + price + '">' + 880 '<div class="right-sidebar-price-title --price-value">' + number_format(price, 0, ".", " ") + ' <span class="rub">â½</span></div>' + 881 (showPriceL ? '<div class="right-sidebar-price-title">' + number_format(priceL, 0, ".", " ") + ' â½</div>' : '') + 882 (showPriceR ? '<div class="right-sidebar-price-title">' + number_format(priceR, 0, ".", " ") + ' â½</div>' : '') + 883 '</div>' 884 ); 885 $('.mk-cartbar-price').text(number_format(price, 0, ".", " ") + ' â½'); 886 } else { 887 obColorer.hidecolor(); 888 } 889 890 }, 891 892 selectProp(keyProp, prop) { 893 tobasket = 0; 894 this.currentSku = this.findSku(keyProp, prop); 895 this.reloadCalc(); 896 897 const h1Element = document.querySelector('[data-js="h1-sku"]'); 898 if (h1Element) { 899 h1Element.innerText = this.currentSku?.NAME; 900 } 901 }, 902 903 showSkuLink(keyProp, prop) { 904 const sku = this.findSku(keyProp, prop); 905 return window.location.href.replace(/sku_\d+/, 'sku_' + sku.ID); 906 }, 907 908 getPopupImg(keyProp, prop) { 909 const sku = this.findSku(keyProp, prop); 910 return sku.PREVIEW_PICTURE !== null ? sku.LINK_PREVIEW_PICTURE : this.img?.imgProduct?.srcBig; 911 }, 912 913 checkPriceDiscontPrice(oPrice, nPrice) { 914 return parseFloat(oPrice) > parseFloat(nPrice); 915 }, 916 917 checkPropsDisabled(keyProp, prop) { 918 var poropsfilter = document.getElementsByClassName('property-filter-title'); 919 if (poropsfilter.length == 1) return false;
920 921 for (let skuKey in this.skus) { 922 let sku = this.skus[skuKey]; 923 if (sku.FILTER_PROPS[keyProp]?.VALUE == prop.VALUE) { 924 for (let skuPropKey in sku.FILTER_PROPS) { 925 if (this.getCurrentPropsFilter[skuPropKey]?.VALUE && 926 this.getCurrentPropsFilter[skuPropKey].VALUE == sku.FILTER_PROPS[skuPropKey].VALUE) { 927 return false; 928 } 929 } 930 } 931 } 932 return true; 933 }, 934 935 filterSkusMarketingText(keyProp, prop) { 936 if (keyProp !== "UPAKOVKA") return ""; 937 938 let propsFilter = {}; 939 for (let keyPropCurrent in this.getCurrentPropsFilter) { 940 if (keyPropCurrent != keyProp) { 941 propsFilter[keyPropCurrent] = this.getCurrentPropsFilter[keyPropCurrent]; 942 } 943 } 944 945 for (let keySku in this.skus) { 946 let sku = this.skus[keySku]; 947 if (prop.VALUE === sku?.FILTER_PROPS[keyProp]?.VALUE) { 948 let goodFilter = true; 949 950 for (let keyFilterProp in propsFilter) { 951 if (propsFilter[keyFilterProp].VALUE !== sku?.FILTER_PROPS[keyFilterProp]?.VALUE) { 952 goodFilter = false; 953 } 954 } 955 956 if (goodFilter) { 957 const obDiscont = this.getDiscontLable(sku); 958 return obDiscont ? obDiscont.smallLable : false; 959 } 960 } 961 } 962 return ""; 963 }, 964 965 getOffsetTop(element) { 966 let offsetTop = 0; 967 while (element) { 968 offsetTop += element.offsetTop; 969 element = element.offsetParent; 970 } 971 return offsetTop; 972 }, 973 974 openForm(id) { 975 obFastOrder.getDolymi(id); 976 this.toogleModal(); 977 }, 978 979 toogleModal() { 980 this.isOpenModal = !this.isOpenModal; 981 }, 982 983 setLocalStoregeSkuCurrent(n) { 984 localStorage.setItem('currentSku', JSON.stringify(n)); 985 window.dispatchEvent(new CustomEvent('currentSku-changed', { 986 detail: { storage: localStorage.getItem('currentSku') } 987 })); 988 }, 989 990 changeUrlSku(sku) { 991 const newURL = window.location.href.replace(/sku_\d+/, 'sku_' + sku.ID); 992 window.history.pushState({ path: newURL }, '', newURL); 993 $('.buy-button-box .product-cart-control').hide(); 994 $('.buy-button-box .add-to-cart').show(); 995 996 }, 997 998 getCountBaseSku() { 999 return this.calcPropertiesFilter?.MF_COLOR?.length; 1000 }, 1001 1002 hideCurrentPriceSku() {}, 1003 1004 getOtherBase() { 1005 let propertiesFilter = this.calcPropertiesFilter; 1006 for (let propKey in propertiesFilter) { 1007 if (propKey == "MF_COLOR") { 1008 for (let propValueKey in propertiesFilter[propKey]) { 1009 if (propertiesFilter[propKey][propValueKey].VALUE !== this.getCurrentPropsFilter[propKey]?.VALUE) { 1010 return propertiesFilter[propKey][propValueKey]?.VALUE_PRINT?.VALUE; 1011 } 1012 } 1013 } 1014 } 1015 }, 1016 1017 getBaseNeedColorate() { 1018 const colors = this.calcPropertiesFilter?.MF_COLOR 1019 ?.filter(color => this.needColoratesColor?.includes(color.VALUE)) 1020 .map(color => ({ name: color.VALUE_PRINT.VALUE })) || []; 1021 1022 return `Ðаз${colors.length > 1 ? 'Ñ' : 'а'} ${colors.map(c => c.name).join(' ')} ${colors.length > 1 ? 'обÑзаÑелÑнÑ' : 'обÑзаÑелÑна'} к колеÑовке`; 1023 }, 1024 1025 reloadCalc: function () { 1026 this.calcOpen = false;
1027 this.surfaces = [{ width: '', length: '', square: '', square_grout: '', width_seam: '', thickness: '' }]; 1028 this.totalPrice = 0; 1029 this.totalColorPrice = 0; 1030 this.totalTovarPrice = 0; 1031 this.tinsList = []; 1032 1033 if ($('.title-tint-select').text()) { 1034 this.RoboTintColor = $('.title-tint-select').text(); 1035 this.RoboTintColorHex = $('.color-box--rect .pic.cl').attr('style'); 1036 } else { 1037 this.RoboTintColor = false; 1038 this.RoboTintColorHex = false; 1039 } 1040 1041 this.layers.forEach(layer => layer.value = 0); 1042 }, 1043 1044 showCalc() { 1045 this.reloadCalc(); 1046 ym(7500958,'reachGoal','calc'); 1047 $(".product-info-box").after($(".new_block_calc")); 1048 this.calcOpen = !this.calcOpen; 1049 1050 if (selectedColor?.[MF_COLOR]) { 1051 $('.calc-comp__tins-sum-title.note.selectedcolor').html( 1052 '<span><span class="title-tint-left">ÐÑбÑан ÑвеÑ: </span>' + 1053 '<span class="pic cl" style="background-color:' + selectedColor[MF_COLOR].HEX + '"> </span>' + 1054 '<span class="title-tint">' + $('.title-tint-select').text() + '</span></span>' 1055 ); 1056 } 1057 obColorer.showcolor(); 1058 }, 1059 1060 closeCalc() { 1061 this.calcOpen = false; 1062 }, 1063 1064 handlerSquare: function () { 1065 this.calculateLayer(); 1066 this.getResult(); 1067 }, 1068 1069 validateSquare: function (index, type) { 1070 let currentValue = Math.abs(parseFloat(String(this.surfaces[index][type]).replace(/,/, '.'))); 1071 this.surfaces[index][type] = (typeof currentValue === 'number' && isFinite(currentValue) && currentValue > 0) 1072 ? currentValue.toFixed(1) 1073 : ''; 1074 }, 1075 1076 updateCalcInput: function (index, type, surface) { 1077 this.validateSquare(index, type); 1078 this.updateSquare(index, type, surface); 1079 1080 if (this.surfaces[index]?.length > 0) { 1081 this.surfaces[index].length = parseFloat(this.surfaces[index].length) + ' м'; 1082 } 1083 if (this.surfaces[index]?.width > 0) { 1084 this.surfaces[index].width = parseFloat(this.surfaces[index].width) + ' м'; 1085 } 1086 if (this.surfaces[index]?.square > 0) { 1087 this.surfaces[index].square = parseFloat(this.surfaces[index].square) + ' м'; 1088 } 1089 }, 1090 1091 updateCalcInputGrout: function (index, type, surface) { 1092 this.validateSquare(index, type); 1093 this.updateSquareGrout(index, type, surface); 1094 1095 if (this.surfaces[index]?.length > 0) { 1096 this.surfaces[index].length = parseFloat(this.surfaces[index].length); 1097 } 1098 if (this.surfaces[index]?.width > 0) { 1099 this.surfaces[index].width = parseFloat(this.surfaces[index].width); 1100 } 1101 if (this.surfaces[index]?.thickness > 0) { 1102 this.surfaces[index].thickness = parseFloat(this.surfaces[index].thickness); 1103 } 1104 if (this.surfaces[index]?.width_seam > 0) { 1105 this.surfaces[index].width_seam = parseFloat(this.surfaces[index].width_seam); 1106 } 1107 if (this.surfaces[index]?.square_grout > 0) { 1108 this.surfaces[index].square_grout = parseFloat(this.surfaces[index].square_grout); 1109 } 1110 }, 1111 1112 calculateLayer: function () { 1113 const square = this.calcSquare(); 1114 const paintNeed = parseFloat((square / this.paintRate * 100) / 100).toFixed(2); 1115
1116 this.layers.forEach(layer => { 1117 layer.value = layer.val * paintNeed; 1118 }); 1119 }, 1120 1121 getCalcLayer: function (layerIndex) { 1122 let doReload = false; 1123 1124 this.layers.forEach((layer, index) => { 1125 layer.active = index === layerIndex; 1126 if (index !== layerIndex) doReload = true; 1127 }); 1128 1129 if (doReload) this.getResult(); 1130 }, 1131 1132 calcSquare: function () { 1133 return this.surfaces.reduce((total, ele) => { 1134 if (ele.square) { 1135 return total + this.clearValue(ele.square); 1136 } 1137 return total + this.clearValue(ele.length) * this.clearValue(ele.width); 1138 }, 0); 1139 }, 1140 1141 addSurface() { 1142 this.surfaces.push({ width: '', length: '', square: '' }); 1143 }, 1144 1145 clearValue(value) { 1146 return parseFloat(String(value).replace(/[^\d.,]/g, '')); 1147 }, 1148 1149 setValue(index, type) { 1150 if (this.surfaces[index][type] !== '') { 1151 this.surfaces[index][type] = this.clearValue(this.surfaces[index][type]); 1152 } 1153 }, 1154 1155 getCalculatedItems: function (volume) { 1156 let recommendedProducts = this.getFilteredItems(); 1157 let currentVolume = Math.round(volume * 10) / 10; 1158 1159 recommendedProducts.sort((a, b) => parseFloat(b.VOLUME) - parseFloat(a.VOLUME)); 1160 1161 for (let i = 0; i < recommendedProducts.length; i++) { 1162 let productVOLUME = parseFloat(recommendedProducts[i].VOLUME); 1163 recommendedProducts[i].itemsUsed = 0; 1164 1165 if (currentVolume >= productVOLUME) { 1166 recommendedProducts[i].itemsUsed = Math.floor(currentVolume / productVOLUME); 1167 currentVolume = Math.round((currentVolume - (recommendedProducts[i].itemsUsed * productVOLUME)) * 10) / 10; 1168 } 1169 1170 if (currentVolume <= 0) break; 1171 1172 if (i === (recommendedProducts.length - 1) && currentVolume > 0) { 1173 recommendedProducts[i].itemsUsed += Math.ceil(currentVolume / productVOLUME); 1174 } 1175 } 1176 1177 for (let i = 0; i < recommendedProducts.length; i++) { 1178 const product = recommendedProducts[i]; 1179 const nextProduct = recommendedProducts[i + 1]; 1180 1181 if (nextProduct && product.itemsUsed > 0 && 1182 parseFloat(product.VOLUME) === (parseFloat(nextProduct.VOLUME) * nextProduct.itemsUsed)) { 1183 recommendedProducts[i].itemsUsed += 1; 1184 recommendedProducts[i + 1].itemsUsed = 0; 1185 } 1186 } 1187 1188 return recommendedProducts; 1189 }, 1190 1191 multiplyVolumeByItemsUsed: function (volume, itemsUsed) { 1192 return parseFloat(volume) * itemsUsed; 1193 }, 1194 1195 getFilteredItems: function () { 1196 return this.items.filter(item => item.MF_COLOR === this.currentSku?.MF_COLOR); 1197 }, 1198 1199 addToBasketCalc: function () { 1200 if (typeof this.items == "undefined") return; 1201 1202 const newBasketItems = this.items.filter(e => e.itemsUsed > 0); 1203 if (!newBasketItems.length) return; 1204 1205 var MF_COLOR = $('.MF_COLOR .property-filter-value.__active:first').index(); 1206 let colorParams = {}; 1207 1208 if (selectedColor?.[MF_COLOR]) { 1209 colorParams = { 1210 COLOR_ID: selectedColor[MF_COLOR].COLOR_ID, 1211 COLOR_SKU_ID: selectedColor[MF_COLOR].COLOR_SKU_ID, 1212 COLLECTION_NAME: selectedColor[MF_COLOR].COLLECTION_NAME, 1213 COLLECTION_ID: selectedColor[MF_COLOR].COLLECTION_ID, 1214 COLOR_NAME: selectedColor[MF_COLOR].COLOR_NAME, 1215 HEX: selectedColor[MF_COLOR].HEX, 1216 COLOR_PRICE: selectedColorPRICE?.[MF_COLOR] 1217 }; 1218 } 1219 1220 $.ajax({ 1221 type: "POST",
1222 url: "/local/components/art-fresh/sale.basket/ajax.php", 1223 data: { 1224 items: newBasketItems, 1225 action: 'calc_basket_add', 1226 BIG_BASKET: 1, 1227 basket_new: 'Y', 1228 sku: this.items.map(item => item.PRODUCT_ID), 1229 ...colorParams 1230 }, 1231 timeout: 15000, 1232 beforeSend: () => { 1233 $('.calc-comp__accept').remove(); 1234 $(".calc-comp__result-tins.active.is_tins").after('<a href="/personal/cart/" class="calc-comp__accept">ÐеÑейÑи РкоÑзинÑ</a>'); 1235 1236 newBasketItems.forEach(basketItem => { 1237 this.basketItems.push({ 1238 ID: basketItem.PRODUCT_ID, 1239 QUANTITY: basketItem.itemsUsed 1240 }); 1241 }); 1242 }, 1243 success: (data) => { 1244 obBasket.changeBasket(data); 1245 1246 newBasketItems.forEach(basketItem => { 1247 $.ajax({ 1248 url: '/local/ajax/getProduct.php', 1249 dataType: 'html', 1250 data: { id: basketItem.PRODUCT_ID, quantity: basketItem.itemsUsed }, 1251 type: 'POST', 1252 success: function (data) { 1253 var dataJSON = JSON.parse(data); 1254 dataLayer.push({ 1255 "ecommerce": { 1256 'currencyCode': 'RUB', 1257 "add": { 1258 "products": [{ 1259 "id": basketItem.PRODUCT_ID, 1260 "name": dataJSON.name, 1261 "brand": dataJSON.brand, 1262 "category": dataJSON.category, 1263 "price": dataJSON.price, 1264 "variant": dataJSON.variant, 1265 "quantity": basketItem.itemsUsed 1266 }] 1267 } 1268 }, 1269 'goods_id': basketItem.PRODUCT_ID, 1270 'goods_price': dataJSON.price, 1271 'page_type': 'add_product', 1272 'event': 'pixel-mg-event', 1273 'pixel-mg-event-category': 'Enhanced Ecommerce', 1274 'pixel-mg-event-action': 'Adding a Product to a Shopping Cart', 1275 'pixel-mg-event-non-interaction': 'False' 1276 }); 1277 }, 1278 timeout: 2000 1279 }); 1280 }); 1281 }, 1282 }); 1283 }, 1284 1285 removeSurface: function (index) { 1286 this.surfaces.splice(index, 1); 1287 this.calculateLayer(); 1288 this.getResult(); 1289 }, 1290 1291 getTinLabel(tin) { 1292 return `${tin.used} ${PluralForm(tin.used, ['банка', 'банки', 'банок'])} по ${tin.volume}`; 1293 }, 1294 1295 getResult: function () { 1296 const layer = this.layers.find(layer => layer.active); 1297 if (!layer?.value) return; 1298 1299 let value = Math.round(layer.value * 10) / 10;
1300 if (value === 0) value = Math.ceil(layer.value * 10) / 10; 1301 1302 if (value) { 1303 var MF_COLOR = $('.MF_COLOR .property-filter-value.__active:first').index(); 1304 let ColorPrice = 0; 1305 this.totalPrice = 0; 1306 this.totalColorPrice = 0; 1307 this.totalTovarPrice = 0; 1308 this.tinsList = []; 1309 1310 const tinsList = this.getCalculatedItems(value); 1311 tinsList.forEach(item => { 1312 if (item.itemsUsed) { 1313 this.tinsList.push({ 1314 used: item.itemsUsed, 1315 volume: item.VOLUME 1316 }); 1317 if (selectedColorPRICE?.[MF_COLOR] > 0) { 1318 ColorPrice = Math.round(item.VOLUME) * selectedColorPRICE[MF_COLOR] * item.itemsUsed; 1319 this.totalColorPrice += ColorPrice; 1320 } 1321 this.totalTovarPrice += item.PRICE * item.itemsUsed; 1322 this.totalPrice += item.PRICE * item.itemsUsed + ColorPrice; 1323 } 1324 }); 1325 } 1326 }, 1327 1328 updateSquare(index, type, surface) { 1329 switch (type) { 1330 case 'width': 1331 case 'length': 1332 if (!surface[type]) { 1333 surface.square = ''; 1334 } else if (surface.width !== '' && surface.length !== '') { 1335 surface.square = (this.clearValue(surface.width) * this.clearValue(surface.length)).toFixed(1); 1336 } 1337 break; 1338 1339 case 'square': 1340 if (!surface[type]) { 1341 surface.width = ''; 1342 surface.length = ''; 1343 } else if (this.needUpdateSquare(surface)) { 1344 surface.width = String(this.clearValue(surface[type])); 1345 surface.length = '1'; 1346 } 1347 break; 1348 } 1349 1350 this.handlerSquare(); 1351 }, 1352 1353 updateSquareGrout(index, type, surface) { 1354 this.calculateLayer(); 1355 this.totalWeight = parseFloat(surface.square_grout) * 1356 (parseFloat(surface.length) + parseFloat(surface.width)) * 1357 parseFloat(surface.thickness) * 1358 parseFloat(surface.width_seam) * 1359 parseFloat(this.density) / 1360 (parseFloat(surface.length) * parseFloat(surface.width)); 1361 1362 this.totalPrice = 1; 1363 this.surfaces[index].weight_grout = Math.round(this.totalWeight * 100) / 100 + ' кг'; 1364 }, 1365 1366 needUpdateSquare(surface) { 1367 const width = this.clearValue(surface.width); 1368 const length = this.clearValue(surface.length); 1369 return (width * length).toFixed(1) !== this.clearValue(surface.square).toFixed(1); 1370 }, 1371 1372 getUnitType() { 1373 if (this.currentSku?.VES_V_KG) return 'кг'; 1374 if (this.currentSku?.OBEM_V_L || 1375 this.getPriceByOneVolume(this.currentSku?.new_price_set?.[this.getCurrentPriceType]?.NEW_VALUE) !== 'Infinity') { 1376 return 'л'; 1377 } 1378 return this.currentSku?.UNIT_TYPE ? 'л' : 'кг'; 1379 }, 1380 1381 calcSquareRoom: function () { 1382 let calcModal = $('.calc-comp'); 1383 let squareTotal = 0; 1384 let squaresRows = calcModal.find(`[data-block-square=${this.typeRashet}] .calc-comp__square-row`); 1385 1386 squaresRows.each(function (i, el) { 1387 let inputLengthValue = $(el).find('.calc-comp__square-input_length').val(),
1388 inputWidthValue = $(el).find('.calc-comp__square-input_width').val(), 1389 inputHeightValue = $(el).find('.calc-comp__square-input_height').val(), 1390 length = parseFloat(inputLengthValue || 0), 1391 width = parseFloat(inputWidthValue || 0), 1392 height = parseFloat(inputHeightValue || 0); 1393 1394 squareTotal += 2 * (length * height) + 2 * (height * width); 1395 }); 1396 1397 return squareTotal; 1398 }, 1399 1400 getResultWallpaper: function () { 1401 const wallpaperType = this.wallpaperType.find(wallpaper => wallpaper.active); 1402 if (wallpaperType?.type === 'wall') { 1403 const square = this.calcSquare(); 1404 const countWallpaper = Math.ceil(square / this.items[0].SQURE_RULON); 1405 this.items[0].itemsUsed = countWallpaper; 1406 } 1407 this.showResultWallpaper(); 1408 }, 1409 1410 showResultWallpaper: function () { 1411 this.items.forEach(item => { 1412 if (item.itemsUsed) { 1413 this.tinsList.push({ 1414 used: item.itemsUsed, 1415 volume: item.VOLUME 1416 }); 1417 this.totalPrice += item.PRICE * item.itemsUsed; 1418 } 1419 }); 1420 }, 1421 1422 buyCheaper: function () { 1423 const element = document.querySelector('[data-block="line-block-price"]'); 1424 if (element) { 1425 const topPosition = element.getBoundingClientRect().top + window.scrollY - 150; 1426 window.scroll({ top: topPosition, behavior: 'smooth' }); 1427 $('.help-text').addClass('active'); 1428 } 1429 }, 1430 1431 magnifiedZoom: function () { 1432 if (this.isOboi && !this.isSmallScreen) { 1433 magnify("magnificZoom", 1.7); 1434 } 1435 }, 1436 1437 isCashBack() { 1438 if (!this.currentSku?.MARKETING) return false; 1439 1440 for (const id in this.currentSku.MARKETING) { 1441 if (this.currentSku.MARKETING[id].CASH_BACK) return true; 1442 } 1443 return false; 1444 }, 1445 1446 // ÐпÑимизаÑиÑ: аÑÐ¸Ð½Ñ ÑÐ¾Ð½Ð½Ð°Ñ Ð¸Ð½Ð¸ÑиализаÑÐ¸Ñ 1447 async initializeAsync() { 1448 await this.requestReviews(); 1449 this.isDataLoaded = true; 1450 }, 1451 1452 // ÐеÑеноÑÐ¸Ñ Ñ Ð°ÑакÑеÑиÑÑики из ÑкÑÑÑого блока в Ñаб. 1453 // РазмеÑка ÑÑаÑиÑнаÑ, без Vue-диÑекÑив, поÑÑÐ¾Ð¼Ñ innerHTML безопаÑен. 1454 fillTechSpecs() { 1455 if (techHtmlCache === null) { 1456 const source = document.getElementById('techSpecsSource'); 1457 if (!source) { 1458 return; 1459 } 1460 techHtmlCache = source.innerHTML; 1461 source.remove(); 1462 } 1463 1464 const mount = document.getElementById('techSpecsMount'); 1465 if (mount && !mount.dataset.loaded) { 1466 mount.innerHTML = techHtmlCache; 1467 mount.dataset.loaded = '1'; 1468 } 1469 }, 1470 1471 // ÐеÑеноÑÐ¸Ñ ÑпиÑок оÑзÑвов из ÑкÑÑÑого блока в Ñаб â как 1472 // fillTechSpecs. СеÑÐ²ÐµÑ Ð¾ÑдаÑÑ ÑпиÑок ÑÑÐ°Ð·Ñ Ð² HTML (нÑжен Ð´Ð»Ñ 1473 // индекÑаÑии), ajax-запÑоÑа болÑÑе неÑ. 1474 // РазмеÑка ÑÑаÑиÑнаÑ, без Vue-диÑекÑив, поÑÑÐ¾Ð¼Ñ innerHTML безопаÑен. 1475 fillReviewsList() { 1476 if (reviewsHtmlCache === null) { 1477 const source = document.getElementById('reviewsListSource'); 1478 if (!source) { 1479 return; 1480 } 1481 reviewsHtmlCache = source.innerHTML; 1482 source.remove(); 1483 } 1484 1485 const mount = document.getElementById('reviewsListMount'); 1486 if (mount && !mount.dataset.loaded) { 1487 mount.innerHTML = reviewsHtmlCache; 1488 mount.dataset.loaded = '1'; 1489 } 1490 } 1491 }, 1492 1493 computed: { 1494 isDiscont() { 1495 if (this.isUpdating) return false;
1496 1497 const prices = this.currentSku?.new_price_set; 1498 if (!prices) return false; 1499 1500 let checked = false; 1501 1502 if (this.currentSku?.MARKETING && 1503 this.checkPriceDiscontPrice(prices.RRC?.OLD_VALUE, prices.RRC?.NEW_VALUE)) { 1504 checked = true; 1505 } 1506 1507 if (this.checkPriceDiscontPrice(prices.RRC?.OLD_VALUE, prices[this.getCurrentPriceType]?.NEW_VALUE) && 1508 this.getCurrentPriceType !== 'RRC' && 1509 !this.currentSku?.MARKETING && 1510 !checked) { 1511 checked = true; 1512 } 1513 1514 return checked; 1515 }, 1516 1517 getSkuBonus() { 1518 return this.currentSku?.new_price_set?.[this.getCurrentPriceType]?.BONUS_RUB || 0; 1519 }, 1520 1521 getReviewAllRating() { 1522 if (!this.reviews || !Object.keys(this.reviews).length) { 1523 const initialCount = Number(this.initialReviewCount) || 0; 1524 if (!initialCount) return false; 1525 1526 return { 1527 rating: Number(this.initialReviewRating || 0).toFixed(1), 1528 count: initialCount, 1529 countText: pluralForm(initialCount, ["оÑзÑв", "оÑзÑва", "оÑзÑвов"]) 1530 }; 1531 } 1532 1533 let finalRating = 0; 1534 let finalRatingCount = 0; 1535 1536 for (let idReview in this.reviews) { 1537 if (this.reviews[idReview]?.RATING_VALUE > 0) { 1538 finalRating += Number(this.reviews[idReview].RATING_VALUE); 1539 finalRatingCount++; 1540 } 1541 } 1542 1543 if (finalRatingCount) { 1544 const totalReviewCount = Number(this.initialReviewCount) || finalRatingCount; 1545 const totalReviewRating = Number(this.initialReviewRating) || (finalRating / finalRatingCount); 1546 1547 return { 1548 rating: totalReviewRating.toFixed(1), 1549 count: totalReviewCount, 1550 countText: pluralForm(totalReviewCount, ["оÑзÑв", "оÑзÑва", "оÑзÑвов"]) 1551 }; 1552 } 1553 return false; 1554 }, 1555 1556 getQuantityShop() { 1557 // доÑÑÑпнÑй оÑÑаÑок менÑÑе 1 ÑÑиÑаем нÑлевÑм â каÑÑоÑка Ð¿Ð¾ÐºÐ°Ð¶ÐµÑ Â«ÐалиÑие: под заказ» 1558 const quantity = Number(this.currentSku?.QUANTITY?.SHOP) || 0; 1559 if (quantity < 1) return 0; 1560 return quantity > 50 ? "болÑÑе 50" : quantity; 1561 }, 1562 1563 isRobotint() { 1564 return this.currentSku?.KOLERUETSYA; 1565 }, 1566 1567 isDominanta() { 1568 let url_string = location.href; 1569 let url = new URL(url_string); 1570 let domi = url.searchParams.get("domi"); 1571 return this.brand.NAME == "DOMINANTA" && 1572 ["132999", "133000", "132997"].includes(this.currentSku?.MF_COLOR) && 1573 this.currentSku?.KOLERUETSYA == 1; 1574 }, 1575 1576 // ÐпÑимизаÑиÑ: getCurrentPriceType без побоÑнÑÑ ÑÑÑекÑов 1577 getCurrentPriceType() { 1578 if (this.isUpdating) return this.PriceType?.PRICE_CODE || 'RRC'; 1579 1580 const summarRRC = this.calculateSummarRRC(); 1581 this._cachedSummarRRC = summarRRC; 1582 1583 let resultKeyPrice = "RRC"; 1584 const availablePrices = this.PriceType?.AVAILABLE_PRICES; 1585 1586 if (availablePrices) { 1587 for (let keyPrice in availablePrices) { 1588 if (summarRRC > availablePrices[keyPrice] && keyPrice !== "RRC") { 1589 resultKeyPrice = keyPrice; 1590 } 1591 } 1592 } 1593 1594 return resultKeyPrice; 1595 }, 1596 1597 getTopSideBar() { 1598 let marginTop = 220; 1599 if (this.scroll <= marginTop) return 0; 1600 return Math.min(this.scroll - marginTop, this.scrollMAX - 650); 1601 }, 1602 1603 getConsumption() { 1604 if (!this.Consumption?.FROM || !this.Consumption?.TO) return false;
1605 1606 this.Consumption.TYPE = this.getUnitType(); 1607 const digits = this.isOboi ? 0 : 2; 1608 1609 return { 1610 all: { 1611 title: this.Consumption.TYPE == "л" ? "1л" : "1кг", 1612 value: "= " + this.Consumption.FROM + "-" + this.Consumption?.TO + "ÐÐ.Ð." 1613 }, 1614 product: { 1615 title: (this.Consumption.TYPE == "л" ? this.getVolume + "л" : this.getVolume + "кг"), 1616 value: "= " + (this.Consumption.FROM * this.getVolume).toFixed(digits) + "-" + 1617 (this.Consumption?.TO * this.getVolume).toFixed(digits) + "ÐÐ.Ð." 1618 } 1619 }; 1620 }, 1621 1622 getDensity() { 1623 return this.density || false; 1624 }, 1625 1626 getRoboTintColor() { 1627 let Color = $('.title-tint-select').text(); 1628 return Color ? 'ÐÑбÑан ÑвеÑ: ' + Color : undefined; 1629 }, 1630 1631 getCurrentColor() { 1632 let propertiesFilter = this.propertiesFilter; 1633 for (let propKey in propertiesFilter) { 1634 if (propKey == "MF_COLOR") { 1635 for (let propValueKey in propertiesFilter[propKey]) { 1636 if (propertiesFilter[propKey][propValueKey].VALUE === this.getCurrentPropsFilter[propKey]?.VALUE) { 1637 return propertiesFilter[propKey][propValueKey]?.VALUE_PRINT?.VALUE; 1638 } 1639 } 1640 } 1641 } 1642 }, 1643 1644 getBASE_TYPE_INT() { 1645 let key = this.currentSku?.BASE; 1646 return key ? (this.baseRobotint[key]?.COLORATE?.[0] || 0) : 0; 1647 }, 1648 1649 getVolume() { 1650 if (this.currentSku?.OBEM_V_L) { 1651 return this.currentSku.OBEM_V_L.replace(',', "."); 1652 } 1653 return this.currentSku?.VES_V_KG?.replace(',', "."); 1654 }, 1655 1656 getTint() { 1657 let tint = { 1658 PRODUCT_ID: this.currentSku?.ID, 1659 PRODUCT_PRICE: this.currentSku?.PRICE_MATRIX?.PRC?.DISCOUNT_VALUE, 1660 VOLUME: Math.ceil(this.getVolume), 1661 BASE_TYPE_INT: this.getBASE_TYPE_INT, 1662 FROM: "Item", 1663 BARCODE: this.currentSku?.BARCODE, 1664 }; 1665 1666 let url_string = location.href; 1667 let url = new URL(url_string); 1668 let coler = url.searchParams.get("coler"); 1669 1670 if (this.brand.NAME == "DOMINANTA" && this.currentSku?.MF_COLOR == "132999" && 1671 this.currentSku?.KOLERUETSYA == 1 && coler == 'Y') { 1672 tint.BARCODE = '4607026569472'; 1673 } 1674 if (this.brand.NAME == "DOMINANTA" && this.currentSku?.MF_COLOR == "133000" && 1675 this.currentSku?.KOLERUETSYA == 1 && coler == 'Y') { 1676 tint.BARCODE = '4607026569496'; 1677 } 1678 return JSON.stringify(tint); 1679 }, 1680 1681 getDomi() { 1682 let BASE_TYPE_INT = this.currentSku?.MF_COLOR == 133000 ? 3 : 1; 1683 1684 let tint = { 1685 PRODUCT_ID: this.currentSku?.ID, 1686 BASE_TYPE_INT, 1687 COLLECTION_ID: 10000, 1688 COLLECTION_NAME: "Dominanta", 1689 COLLECTION_VENDOR_ID: 5, 1690 COLOR_ID: 127802, 1691 COLOR_SKU_ID: "163486", 1692 COLOR_NAME: "DM_С0008", 1693 COLOR_PRICE: "100", 1694 BASKET_ID: 0, 1695 VOLUME: Math.ceil(this.getVolume), 1696 BASE: this.currentSku?.MF_COLOR, 1697 BARCODE: this.currentSku?.BARCODE, 1698 }; 1699 return JSON.stringify(tint); 1700 }, 1701 1702 getCurrentImg() { 1703 return this.getColectionImg?.find(img => img.active === true) || false; 1704 }, 1705 1706 // ÐпÑимизаÑиÑ: кÑÑиÑование getColectionImg 1707 getColectionImg() { 1708 if (this._cachedCollectionImg && this._cachedSkuId === this.currentSku?.ID) { 1709 return this._cachedCollectionImg; 1710 } 1711 1712 let collectionImg = []; 1713 let collectionImgDop = this.img?.collectionImgOther ? [...this.img.collectionImgOther] : []; 1714 1715 if (this.img?.imgProduct?.srcBig) { 1716 collectionImg.unshift(this.img.imgProduct); 1717 } 1718 1719 if (this.currentSku?.ID && this.img?.imgSkus?.[this.currentSku.ID]?.srcBig) { 1720 collectionImg.splice(0, 1, this.img.imgSkus[this.currentSku.ID]); 1721 } 1722 1723 if (this.currentSku?.ID && this.img?.imgSkus?.[this.currentSku.ID]?.MORE_PICTURE) { 1724 for (const j in this.img.imgSkus[this.currentSku.ID].MORE_PICTURE) { 1725 collectionImg.push(this.img.imgSkus[this.currentSku.ID].MORE_PICTURE[j]); 1726 } 1727 } 1728 1729 const result = [...collectionImg, ...collectionImgDop]; 1730 1731 this._cachedCollectionImg = result; 1732 this._cachedSkuId = this.currentSku?.ID; 1733 1734 return result; 1735 }, 1736 1737 getCurrentPropsFilter() { 1738 if (!this.currentSku?.FILTER_PROPS) return {}; 1739 1740 if (this._cachedCurrentPropsFilter && this._lastSkuId === this.currentSku.ID) { 1741 return this._cachedCurrentPropsFilter; 1742 } 1743 1744 const result = {}; 1745 for (let prop in this.currentSku.FILTER_PROPS) { 1746 if (prop && this.currentSku.FILTER_PROPS[prop].VALUE) { 1747 result[prop] = this.currentSku.FILTER_PROPS[prop]; 1748 } 1749 } 1750 1751 this._cachedCurrentPropsFilter = result; 1752 this._lastSkuId = this.currentSku.ID; 1753 1754 return result; 1755 }, 1756 1757 getDolymiPrice: function () { 1758 let currentQuantity = this.dataSkuJs[this.currentSku?.ID]?.QUANTITY_DEFAULT; 1759 if (this.isSmallScreen) { 1760 currentQuantity = this.countItemMobile || 1; 1761 } 1762 1763 const totalPrice = (this.currentSku?.new_price_set?.[this.getCurrentPriceType]?.NEW_VALUE || 0) * currentQuantity; 1764 return Math.ceil(totalPrice / 4); 1765 }, 1766 1767 inBasketItems: function () { 1768 this.currentBasketItem = this.inBasket(); 1769 this.countItemMobile = this.currentBasketItem ? parseInt(this.currentBasketItem.QUANTITY) : 0; 1770 return this.currentBasketItem; 1771 }, 1772 1773 inBasketItemss: function () { 1774 this.currentBasketItem = this.inBasket(); 1775 return tobasket == 1 ? this.currentBasketItem : false;
1776 }, 1777 }, 1778 1779 mounted() { 1780 this.slideWidth = this.$refs.slider?.offsetWidth; 1781 1782 // ÐÑиÑиÑеÑÐºÐ°Ñ Ð¸Ð½Ð¸ÑиализаÑÐ¸Ñ 1783 this.iHeight = window.innerHeight / 10; 1784 this.iOffset = window.scrollY || document.documentElement.scrollTop; 1785 1786 // СлÑÑаÑели ÑобÑÑий 1787 window.addEventListener('scroll', this.handleScroll); 1788 window.addEventListener('resize', this.handleResize); 1789 document.addEventListener('keydown', this.handleKeyDown); 1790 1791 this._calcAddToCartHandler = (event) => this.handleCalcAddToCart(event); 1792 window.addEventListener('calc:add-to-cart', this._calcAddToCartHandler); 1793 1794 // ÐÑÐ¸Ð½Ñ ÑÐ¾Ð½Ð½Ð°Ñ Ð¸Ð½Ð¸ÑиализаÑÐ¸Ñ Ð½ÐµÐºÑиÑиÑеÑÐºÐ¸Ñ Ð´Ð°Ð½Ð½ÑÑ 1795 this.$nextTick(() => { 1796 this.pushEcommerceDetail(); 1797 this.getCurrentDiscontLable(); 1798 this.initSlider(); 1799 this.magnifiedZoom();
1800 this.getSkuDataPrice(); 1801 1802 // Ð¦Ð²ÐµÑ Ð¸Ð· адÑеÑа должен вÑÑаÑÑ ÑÑазÑ, а не поÑле пÑокÑÑÑки. 1803 // ÐдÑм еÑÑ Ð¾Ð´Ð¸Ð½ Ñик: ÑÑÑока ÑÐµÐ½Ñ Ðº ÑÑÐ¾Ð¼Ñ Ð¼Ð¾Ð¼ÐµÐ½ÑÑ Ð¾ÑÑиÑована, 1804 // инаÑе Ñлагаемое oldprice ÑиÑаеÑÑÑ ÐºÐ°Ðº NaN. 1805 if (window.fromColers) { 1806 this.$nextTick(() => this.applyTintPrice()); 1807 } 1808 1809 // ÐÑÐ»Ð¾Ð¶ÐµÐ½Ð½Ð°Ñ Ð·Ð°Ð³ÑÑзка оÑзÑвов 1810 if (this.tabActive === 'review') { 1811 this.initializeAsync(); 1812 this.fillReviewsList(); 1813 } 1814 if (this.tabActive === 'tech') { 1815 this.fillTechSpecs(); 1816 } 1817 }); 1818 }, 1819 1820 unmounted() { 1821 if (this._calcAddToCartHandler) { 1822 window.removeEventListener('calc:add-to-cart', this._calcAddToCartHandler); 1823 } 1824 window.removeEventListener('scroll', this.handleScroll); 1825 window.removeEventListener('resize', this.handleResize); 1826 document.removeEventListener('keydown', this.handleKeyDown); 1827 }, 1828 1829 watch: { 1830 currentSku(newVal, oldVal) { 1831 if (this.isUpdating || !newVal) return; 1832 this.isUpdating = true; 1833 1834 this.setLocalStoregeSkuCurrent(newVal); 1835 this.changeUrlSku(newVal); 1836 1837 // СбÑаÑÑваем кÑÑи пÑи Ñмене SKU 1838 this._cachedCollectionImg = null; 1839 this._cachedSkuId = null; 1840 this._cachedCurrentPropsFilter = null; 1841 1842 this.$nextTick(() => { 1843 this.getCurrentDiscontLable();
1844 this.getSkuDataPrice(); 1845 this.isUpdating = false; 1846 }); 1847 }, 1848 1849 _cachedSummarRRC(newVal) { 1850 if (newVal) { 1851 this.$nextTick(() => { 1852 obDetailProduct.setSlider(parseFloat(newVal)); 1853 }); 1854 } 1855 } 1856 }, 1857};
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.