(function () { const tbody = document.querySelector('#produkty-body'); const celInput = document.querySelector('#cel'); const box = document.querySelector('#celSyncBox'); const msg = document.querySelector('#celSyncMsg'); const btn = document.querySelector('#btnApplyCelFromSum'); if (!tbody || !celInput || !box || !msg || !btn) return; const EPS = 0.01; // tolerancja porównania function parsePrice(raw) { if (!raw) return NaN; const s = String(raw).trim().replace(/\s+/g, '').replace(',', '.'); const n = Number(s); return Number.isFinite(n) && n >= 0 ? n : NaN; } function getRows() { return Array.from(tbody.querySelectorAll('tr')); } function computeSum() { const rows = getRows(); let hasNamed = false; let sumAll = 0; // suma ze wszystkich wierszy z nazwą i poprawną ceną let sumToBuy = 0; // suma tylko z wierszy NIE oznaczonych jako "Kupione" for (const tr of rows) { const nameInput = tr.querySelector('input[name="item_nazwa[]"]'); const priceInput = tr.querySelector('input[name="item_cena[]"]'); const kupioneSwitch = tr.querySelector('.kupione-switch'); const name = nameInput ? nameInput.value.trim() : ''; if (!name) continue; // ignoruj puste wiersze bez nazwy hasNamed = true; const priceVal = priceInput ? parsePrice(priceInput.value) : NaN; if (Number.isNaN(priceVal)) continue; // zawsze dolicz do sumy wszystkich sumAll += priceVal; // do sumy do-kupienia tylko jeśli nie jest oznaczone jako kupione if (!(kupioneSwitch && kupioneSwitch.checked)) { sumToBuy += priceVal; } } return { hasNamed, sumAll, sumToBuy }; } function readCel() { const v = parsePrice(celInput.value); return Number.isNaN(v) ? null : v; } function formatPln(n) { // Nie narzucamy locale – prosto 2 miejsca return n.toFixed(2); } function updateUI() { const { hasNamed, sumAll, sumToBuy } = computeSum(); // Brak produktów (brak nazw) lub obie sumy = 0 → nic nie pokazuj if (!hasNamed || (sumAll <= 0 && sumToBuy <= 0)) { box.classList.add('d-none'); btn.classList.add('d-none'); box.classList.remove('alert-success', 'alert-info'); msg.textContent = ''; return; } const cel = readCel(); const target = sumToBuy; // porównujemy do kwoty POZOSTAŁE DO KUPIENIA // Jeśli cel nie ustawiony lub NaN → zaproponuj ustawienie celu = sumToBuy if (cel === null) { box.classList.remove('d-none'); box.classList.remove('alert-success'); box.classList.add('alert-info'); // pokazujemy obie sumy w komunikacie msg.innerHTML = `
Wszystkie: ${formatPln(sumAll)} PLN · Do kupienia: ${formatPln(sumToBuy)} PLN
Możesz ustawić cel na kwotę do kupienia.
`; btn.textContent = `Ustaw cel = ${formatPln(target)} PLN`; btn.classList.remove('d-none'); return; } // Mamy cel — porównanie do sumy do-kupienia if (Math.abs(cel - target) <= EPS) { box.classList.remove('d-none'); box.classList.remove('alert-info'); box.classList.add('alert-success'); msg.innerHTML = ` Suma do kupienia (${formatPln(target)} PLN) jest równa celowi.
Wszystkie: ${formatPln(sumAll)} PLN · Do kupienia: ${formatPln(sumToBuy)} PLN
`; btn.classList.add('d-none'); } else { box.classList.remove('d-none'); box.classList.remove('alert-success'); box.classList.add('alert-info'); msg.innerHTML = `
Wszystkie: ${formatPln(sumAll)} PLN · Do kupienia: ${formatPln(sumToBuy)} PLN
Cel: ${formatPln(cel)} PLN
`; btn.textContent = `Zaktualizuj cel do ${formatPln(target)} PLN`; btn.classList.remove('d-none'); } } btn.addEventListener('click', (e) => { e.preventDefault(); const { sumToBuy } = computeSum(); if (sumToBuy > 0) { celInput.value = formatPln(sumToBuy); celInput.dispatchEvent(new Event('input', { bubbles: true })); celInput.dispatchEvent(new Event('change', { bubbles: true })); updateUI(); } }); // Reaguj na zmiany cen/nazw tbody.addEventListener('input', (e) => { const name = e.target.getAttribute('name'); if (name === 'item_nazwa[]' || name === 'item_cena[]') { updateUI(); } }); // Reaguj na zmiany celu celInput.addEventListener('input', updateUI); celInput.addEventListener('change', updateUI); // Obserwuj dodawanie/usuwanie wierszy przez inne skrypty const mo = new MutationObserver(() => updateUI()); mo.observe(tbody, { childList: true, subtree: true }); // Init po załadowaniu document.addEventListener('DOMContentLoaded', updateUI); // i jedno wywołanie na starcie (gdy DOMContentLoaded już był) updateUI(); })();