Повышение цен с 16 декабря

Успейте купить салюты выгодно!

--д : --ч : --м : --с

Мелкие салюты | 0.2 - 0.7"

Сортировать по:
Фильтр

Товар закончился

Товар закончился

Товар закончился

Товар закончился

Товар закончился

Товар закончился

Товар закончился

Товар закончился

Товар закончился

Товар закончился

Товар закончился

(function () { function toNum(v) { return Number(String(v ?? '').replace(/\s+/g, '').replace(',', '.')) || 0; } function formatMoney(n) { n = Number(n) || 0; return n.toLocaleString('ru-RU'); } // Купон считаем активным только если в инпуте есть код function hasCouponApplied() { const inp = document.querySelector('#fn_cart_coupon input.fn_coupon'); return !!(inp && inp.value && inp.value.trim().length > 0); } // Берём absoluteDiscount именно у строки скидки "Купон" function getCouponAbsoluteDiscount() { const items = Array.from(document.querySelectorAll('#fn_cart_coupon .purchase_detail__item[data-discount-abs]')); // 1) по data-discount-name for (const it of items) { const name = (it.getAttribute('data-discount-name') || '').toLowerCase(); if (name.includes('купон') || name.includes('coupon')) { const abs = toNum(it.getAttribute('data-discount-abs')); return abs > 0 ? abs : null; } } // 2) запасной: по видимому тексту for (const it of items) { const nameEl = it.querySelector('.purchase_detail__name'); if (!nameEl) continue; const name = nameEl.textContent.trim().toLowerCase(); if (name.includes('купон') || name.includes('coupon')) { const abs = toNum(it.getAttribute('data-discount-abs')); return abs > 0 ? abs : null; } } return null; } function setRowToRegular(wrap) { const elNew = wrap.querySelector('.fn_price_new'); const elOld = wrap.querySelector('.fn_price_old'); const elReg = wrap.querySelector('.fn_price_regular'); if (elNew) elNew.classList.add('hidden'); if (elOld) elOld.classList.add('hidden'); if (elReg) elReg.classList.remove('hidden'); // возвращаем line total к серверному отображению const vid = wrap.getAttribute('data-variant-id'); const totalEl = document.querySelector('.fn_line_total[data-variant-id="' + vid + '"]'); const serverLineTotal = toNum(wrap.getAttribute('data-server-line-total')); if (totalEl && serverLineTotal > 0) { totalEl.childNodes[0].nodeValue = formatMoney(serverLineTotal) + ' '; } } function applyCouponDistributed() { // Если купона нет — показываем обычные цены if (!hasCouponApplied()) { document.querySelectorAll('.fn_unit_price_wrap').forEach(setRowToRegular); return; } const absDiscount = getCouponAbsoluteDiscount(); if (!absDiscount) { // Купон введён, но строку скидки "Купон" не нашли — не рисуем ничего, чтобы не врать document.querySelectorAll('.fn_unit_price_wrap').forEach(setRowToRegular); return; } const wraps = Array.from(document.querySelectorAll('.fn_unit_price_wrap')); if (!wraps.length) return; // Собираем строки товаров const rows = wraps.map(wrap => { const oldUnit = toNum(wrap.getAttribute('data-old-unit')); const amount = Math.max(1, parseInt(wrap.getAttribute('data-amount'), 10) || 1); const oldTotal = toNum(wrap.getAttribute('data-old-total')); return { wrap, oldUnit, amount, oldTotal }; }).filter(x => x.oldTotal > 0); const subtotal = rows.reduce((s, x) => s + x.oldTotal, 0); if (subtotal <= 0) return; // Ограничиваем скидку, чтобы не уйти ниже нуля const target = Math.min(absDiscount, subtotal); // Пропорционально распределяем скидку по строкам const parts = rows.map(x => { const ideal = (x.oldTotal / subtotal) * target; const base = Math.floor(ideal); // округляем вниз до тенге const frac = ideal - base; return { ...x, ideal, base, frac, alloc: base }; }); // Раздаём остаток (чтобы сумма скидки ровно совпала с absoluteDiscount) let remainder = target - parts.reduce((s, x) => s + x.base, 0); parts.sort((a, b) => b.frac - a.frac); for (let i = 0; i < parts.length && remainder > 0; i++) { parts[i].alloc += 1; remainder -= 1; } // Применяем к UI parts.forEach(x => { const newTotal = Math.max(0, x.oldTotal - x.alloc); const newUnit = x.amount > 0 ? (newTotal / x.amount) : x.oldUnit; const elNew = x.wrap.querySelector('.fn_price_new'); const elOld = x.wrap.querySelector('.fn_price_old'); const elReg = x.wrap.querySelector('.fn_price_regular'); if (elNew) { elNew.classList.remove('hidden'); elNew.childNodes[0].nodeValue = formatMoney(newUnit) + ' '; } if (elOld) { elOld.classList.remove('hidden'); elOld.childNodes[0].nodeValue = formatMoney(x.oldUnit) + ' '; } if (elReg) elReg.classList.add('hidden'); const vid = x.wrap.getAttribute('data-variant-id'); const totalEl = document.querySelector('.fn_line_total[data-variant-id="' + vid + '"]'); if (totalEl) totalEl.childNodes[0].nodeValue = formatMoney(newTotal) + ' '; }); } // Автоперезапуск после AJAX-перерисовок function setupObservers() { const root = document.querySelector('.cart_body') || document.body; if (!root) return; let t = null; const obs = new MutationObserver(() => { clearTimeout(t); t = setTimeout(applyCouponDistributed, 80); }); obs.observe(root, { childList: true, subtree: true }); } document.addEventListener('DOMContentLoaded', function () { applyCouponDistributed(); setupObservers(); }); if (document.readyState !== 'loading') { applyCouponDistributed(); setupObservers(); } })();