Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/rospirotorg.ru/bitrix/templates/aspro_next/js/ |
Upload File : |
/* You can use this file with your scripts. It will not be overwritten when you upgrade solution. */ /* wbs24 - add sale stickers */ function wbs24SaleSticker() { const debug = true; function getItems(css) { const items = document.querySelectorAll(css); if (!items) items = []; return items; } function getDiscount(item) { let discount = 0; const priceElement = item.querySelector('.price'); const priceDiscountElement = item.querySelector('.price.discount'); if (priceElement && priceDiscountElement) { const price = priceElement.dataset.value; const priceDiscount = priceDiscountElement.dataset.value; const deltaPrice = priceDiscount - price; discount = Math.round(deltaPrice / (priceDiscount / 100)); } return discount; } function setSticker(item, stickerClass, discount) { if (!discount) return; const stickersElement = item.querySelector('.stickers'); if (isAllowAddSticker(stickersElement, stickerClass)) { let div = document.createElement('div'); div.className = 'wrap_mark_sale'; div.innerHTML = `<div class="${stickerClass}">-${discount}%</div>`; stickersElement.append(div); } } function isAllowAddSticker(stickersElement, stickerClass) { if (!stickersElement) return false; const stickerElement = stickersElement.querySelector('.' + stickerClass); return stickerElement ? false : true; } function run(css) { let items = getItems(css); items.forEach(item => { let discount = getDiscount(item); setSticker(item, 'mark_sale', discount); }); } function action() { run('.catalog .item, .tabs_content .item'); run('.catalog_detail, .fast_view_frame'); } function observer(css) { let catalogElement = document.querySelector(css); if (catalogElement) { let catalogElementObserver = new MutationObserver(mutationRecords => { if (debug) console.log('catalogElementObserver found mutation'); action(); }); catalogElementObserver.observe(catalogElement, { childList: true, subtree: true, }); } } action(); observer('.catalog'); observer('#popup_iframe_wrapper'); } document.addEventListener('DOMContentLoaded', wbs24SaleSticker); /* wbs24 - buy services */ function wbs24BuyServices() { const debug = true; const protocol = location.protocol+'//'; const domain = location.host; let basketContainerCss; let basketItemsCss; let basketItemFormPlaceSubCss; let mode = 'basket'; let previousBasketSum; const formClass = 'form-services'; const formSubCss = '.' + formClass; const ajaxUrl = '/local/services/ajax.php'; function init() { // basket mode basketContainerCss = '.basket-items-list'; basketItemsCss = basketContainerCss + ' .basket-items-list-item-container'; basketItemFormPlaceSubCss = '.basket-item-block-info'; // detail mode if (!document.querySelector(basketContainerCss)) { basketContainerCss = '.catalog_detail'; basketItemsCss = basketContainerCss + ' .item_main_info'; basketItemFormPlaceSubCss = '.middle_info'; mode = 'detail'; } } function action() { let items = getItems(basketItemsCss); let sum = getBasketSum(); addFormToItems(items); if (mode == 'basket' && sum != previousBasketSum) { previousBasketSum = sum; delUnbound(); } } function observer(css) { let basketContainer = document.querySelector(css); if (basketContainer) { let basketContainerObserver = new MutationObserver(mutationRecords => { if (debug) console.log('basketContainerObserver found mutation'); action(); }); basketContainerObserver.observe(basketContainer, { childList: true, subtree: true, }); } } function getItems(css) { let items = document.querySelectorAll(css); return items ? items : []; } function addFormToItems(items) { items.forEach(item => { addForm(item); }); } async function addForm(item) { let productId = getItemProductId(item); if (!productId) return; let itemIsSevice = getItemParentProductId(item); if (itemIsSevice) return; const basketItemFormPlace = item.querySelector(basketItemFormPlaceSubCss); if (needAddForm(basketItemFormPlace)) { if (debug) console.log('attend add service form'); let formHtml = await getFormAsHtml(productId); if (formHtml && needAddForm(basketItemFormPlace)) { if (debug) console.log('add service form'); let div = document.createElement('div'); div.innerHTML = formHtml; basketItemFormPlace.append(div); activateForm(basketItemFormPlace) } } } function getItemProductId(item) { // basket mode let productId = item.dataset.productId; // need data-product-id in item // detail mode if (!productId && mode == 'detail') { let itemId = item.id; let array = itemId.split('_'); productId = array[array.length - 1]; } return productId } function getItemParentProductId(item) { const parentProductId = item.dataset.serviceofproductid; return parentProductId !== undefined ? parentProductId : false; } function needAddForm(place) { if (!place) return false; const form = place.querySelector(formSubCss); return !form ? true : false; } async function getFormAsHtml(productId) { let servicesHtml = await getServicesAsHtml(productId); let formHtml = `<div class='${formClass}'>${servicesHtml}</div>`; return formHtml; } async function getServicesAsHtml(productId) { let html = ''; let services = await getServices(productId); services.forEach(function(service) { let formattedPrice = formatPrice(service.price); html += `<div class='service-item'> <div class='service-item__button'> <div class='btn-onoff js-buy-service' data-product-id='${productId}' data-service-id='${service.id}' data-service-price='${service.price}'> </div> </div> <div class='service-item__name'>${service.name}</div> <div class='service-item__price'>${formattedPrice}</div> </div>`; }); return html; } async function getServices(productId) { let services = await request({ action: 'getServices', productId: productId, }); return services; } function activateForm(formPlace) { let buyButtons = formPlace.querySelectorAll('.js-buy-service'); for (let button of buyButtons) { addBuyButtonHandlers(button); activateSelectedServices(button); } } function addBuyButtonHandlers(button) { button.addEventListener('click', switchBuyButton); } async function activateSelectedServices(button) { let productId = button.dataset.productId; let serviceId = button.dataset.serviceId; let exist = await checkInBasket(productId, serviceId); if (exist) { button.classList.add('active'); } } function switchBuyButton(event) { let button = event.target; let productId = button.dataset.productId; let serviceId = button.dataset.serviceId; let servicePrice = button.dataset.servicePrice; if (button.classList.contains('active')) { delFromBasket(productId, serviceId, servicePrice); } else { addToBasket(productId, serviceId, servicePrice); } button.classList.toggle('active'); } function formatPrice(price) { let formattedPrice = price.toLocaleString('ru-RU'); formattedPrice += ' ₽'; return formattedPrice; } // BASKET async function addToBasket(productId, serviceId, price) { let response = await request({ action: 'addToBasket', productId: productId, serviceId: serviceId, }); if (response.result = 'success') { recalcBasket(); recalcMiniBasket(1, price); } } async function delFromBasket(productId, serviceId, price = 0) { let response = await request({ action: 'delFromBasket', productId: productId, serviceId: serviceId, }); if (response.result = 'success') { recalcBasket(); if (price) recalcMiniBasket(-1, -price); } } async function checkInBasket(productId, serviceId) { let exist = false; let response = await request({ action: 'checkInBasket', productId: productId, serviceId: serviceId, }); if (response.result == 'exist') { exist = true; } return exist; } async function delUnbound() { let response = await request({ action: 'delUnbound', }); if (response.result == 'recalc') { recalcBasket(); } } async function recalcBasket() { if (!BX.Sale || !BX.Sale.BasketComponent) return; let param = { sessid: BX.bitrix_sessid(), site_id: BX.message('SITE_ID'), action_var: 'basketAction', select_props: 'NAME,DISCOUNT,PROPS,DELETE,DELAY,TYPE,PRICE,QUANTITY,SUM', offers_props: 'SIZES,COLOR_REF,SERVICEOFPRODUCTID', quantity_float: 'N', count_discount_4_all_quantity: 'Y', price_vat_show_value: 'Y', hide_coupon: 'Y', use_prepayment: 'N', basketAction: 'recalculate', }; let result = await requestToSaleBasket(param); applyBasketResult(result); } function getBasketSum() { if (!BX.Sale || !BX.Sale.BasketComponent) return; let bc = BX.Sale.BasketComponent; return bc.result.allSum; } function applyBasketResult(result) { let bc = BX.Sale.BasketComponent; bc.actionPool.doProcessing(false); if (!BX.type.isPlainObject(result)) return; bc.actionPool.setRefreshStatus(result.BASKET_REFRESHED); if (result.RESTORED_BASKET_ITEMS) { bc.restoreBasketItems(result.RESTORED_BASKET_ITEMS); } if (result.DELETED_BASKET_ITEMS) { bc.deleteBasketItems(result.DELETED_BASKET_ITEMS, bc.params.SHOW_RESTORE === 'Y'); } if (result.MERGED_BASKET_ITEMS) { bc.deleteBasketItems(result.MERGED_BASKET_ITEMS, false, true); } bc.applyBasketResult(result.BASKET_DATA); bc.editBasketItems(bc.getItemsToEdit()); bc.editTotal(); //bc.applyPriceAnimation(); bc.editWarnings(); bc.actionPool.switchTimer(); } // MINI BASKET function recalcMiniBasket(deltaQuantity, deltaSum) { let quantity = getMiniBasketQuantity(); if (quantity !== false) { quantity += Number(deltaQuantity); setMiniBasketQuantity(quantity); } let sum = getMiniBasketSum(); if (sum !== false) { sum += Number(deltaSum); setMiniBasketSum(sum); } } function getMiniBasketQuantity() { let quantity = false; let quantityElement = document.querySelector('.basket.basket-count .js-basket-block > .count'); if (quantityElement) { quantity = Number(quantityElement.innerHTML); } return quantity; } function getMiniBasketSum() { let sum = false; let sumElement = document.querySelector('.basket.basket-count .js-basket-block .prices'); if (sumElement) { let value = sumElement.innerHTML; value = value.replace(' ', '', value); value = value.replace(' ', '', value); value = value.replace('₽', '', value); sum = Number(value); } return sum; } function setMiniBasketQuantity(quantity) { let quantityElements = document.querySelectorAll('.basket.basket-count .js-basket-block > .count'); for (let quantityElement of quantityElements) { quantityElement.innerHTML = quantity; } } function setMiniBasketSum(sum) { let sumElements = document.querySelectorAll('.basket.basket-count .js-basket-block .prices'); for (let sumElement of sumElements) { let formattedSum = formatPrice(sum); sumElement.innerHTML = formattedSum; } } // REQUESTS async function request(param) { let result = []; let response = await fetch(ajaxUrl, { method: 'POST', headers: { 'Content-Type': 'application/json;charset=utf-8' }, body: JSON.stringify(param) }); if (response.ok) { result = await response.json(); } else { if (debug) console.error('request error'); } return result; } async function requestToSaleBasket(param) { let result = false; let url = new URL(protocol+domain+'/bitrix/components/bitrix/sale.basket.basket/ajax.php'); for(let paramElement in param) { url.searchParams.append(paramElement, param[paramElement]); } let response = await fetch("/bitrix/components/bitrix/sale.basket.basket/ajax.php", { headers: { "accept": "*/*", "accept-language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7", "bx-ajax": "true", "content-type": "application/x-www-form-urlencoded", }, "referrer": protocol+domain+"/basket/", "referrerPolicy": "no-referrer-when-downgrade", "body": url.search.replace('?', ''), "method": "POST", "mode": "cors", "credentials": "include", }); if (response.ok) { result = await response.json(); } else { if (debug) console.error('request error'); } return result; } // INIT init(); action(); observer(basketContainerCss); } document.addEventListener('DOMContentLoaded', wbs24BuyServices);