/* * AGS 92 B2B – faktúry po splatnosti: upozornenie + blokácia odoslania objednávky * Súbor: /buxus/docs/splatnost.js.txt (načítaný v pätičke, Container 22 → Content after) * * Nastavenie (bez zásahu do kódu): BUXUS → Špeciálne stránky → „Blokácia objednávok – nastavenie (NEMAZAŤ)“ (page_id 652538) * - META title = počet dní po splatnosti, od ktorého sa blokuje (napr. 7) * - Titulok / Text SK, CZ, PL, EN, HU = nadpis a text upozornenia * Ak sa stránka s nastavením nedá načítať, platia predvolené hodnoty nižšie. * * ENFORCE = false → nasadená je zatiaľ len oprava hlavičky, farieb a filtrov; upozornenie a blokácia sa zapnú prepnutím na true. * * Logika: * - posudzujú sa všetky faktúry (od 1. 1. 2000), dobropisy (riadok .invoice-type-dobropis) sa ignorujú * - faktúra je po splatnosti, ak nezaplatená suma > 0 a dnešný dátum > dátum splatnosti * - upozornenie: od splatnosti + 1 deň (pás na každej stránke + okno po prihlásení) * - blokácia: od splatnosti + N dní (N z nastavenia) – tlačidlo OBJEDNAŤ v Súhrne objednávky je vypnuté * - ak sa stav faktúr nepodarí zistiť (výpadok), objednávka sa NEBLOKUJE (fail-open) */ (function () { 'use strict'; if (window.__agsSplatnostLoaded) return; window.__agsSplatnostLoaded = true; var SETTINGS_PAGE = 652538; var INVOICES_PAGE = 257; var DEFAULT_DAYS = 7; var CACHE_MIN = 20; // ako dlho platí zistený stav mimo Súhrnu objednávky (min) var PER_PAGE = 48; var MAX_PAGES = 20; // Upozornenie (pás, okno) a blokácia odoslania objednávky. false = beží len prepočet hlavičky, farby a filtre faktúr. var ENFORCE = false; var lang = (location.pathname.split('/')[1] || '').toLowerCase(); if (!/^(sk|cz|hu|pl|com)$/.test(lang)) return; var L = lang === 'com' ? 'en' : lang; var firmaEl = document.querySelector('.header-basic-info h3'); if (!firmaEl) return; // neprihlásený – nič nerobiť (na prihlasovaciu stránku nikdy nesiahame) var UI = { sk: { title: 'Faktúry po splatnosti', blocked: 'Odosielanie objednávok je pozastavené, kým nebudú faktúry po splatnosti uhradené.', grace: 'Objednávky je možné odoslať ešte do {d}. Od {b} bude odosielanie objednávok pozastavené.', inv: 'Faktúra', due: 'Splatnosť', unpaid: 'Nezaplatené', qr: 'QR platba', more: 'a ďalšie ({n})', list: 'Zobraziť moje faktúry', detail: 'Zobraziť celé upozornenie', close: 'Zavrieť', checking: 'Overujem stav faktúr…', btn: 'Objednávku nie je možné odoslať – evidujeme faktúry po splatnosti.' }, cz: { title: 'Faktury po splatnosti', blocked: 'Odesílání objednávek je pozastaveno, dokud nebudou faktury po splatnosti uhrazeny.', grace: 'Objednávky je možné odeslat ještě do {d}. Od {b} bude odesílání objednávek pozastaveno.', inv: 'Faktura', due: 'Splatnost', unpaid: 'Neuhrazeno', qr: 'QR platba', more: 'a další ({n})', list: 'Zobrazit moje faktury', detail: 'Zobrazit celé upozornění', close: 'Zavřít', checking: 'Ověřuji stav faktur…', btn: 'Objednávku nelze odeslat – evidujeme faktury po splatnosti.' }, hu: { title: 'Lejárt számlák', blocked: 'A rendelések leadása a lejárt számlák kiegyenlítéséig szünetel.', grace: 'Rendelést még {d}-ig lehet leadni. {b}-tól a rendelések leadása szünetel.', inv: 'Számla', due: 'Fizetési határidő', unpaid: 'Kiegyenlítetlen', qr: 'QR fizetés', more: 'és további ({n})', list: 'Számláim megtekintése', detail: 'Teljes értesítés', close: 'Bezárás', checking: 'Számlák ellenőrzése…', btn: 'A rendelés nem adható le – lejárt számlákat tartunk nyilván.' }, pl: { title: 'Faktury po terminie płatności', blocked: 'Składanie zamówień jest wstrzymane do czasu opłacenia zaległych faktur.', grace: 'Zamówienia można składać jeszcze do {d}. Od {b} składanie zamówień zostanie wstrzymane.', inv: 'Faktura', due: 'Termin płatności', unpaid: 'Do zapłaty', qr: 'Płatność QR', more: 'i kolejne ({n})', list: 'Pokaż moje faktury', detail: 'Pokaż pełny komunikat', close: 'Zamknij', checking: 'Sprawdzanie faktur…', btn: 'Nie można złożyć zamówienia – posiadają Państwo faktury po terminie płatności.' }, en: { title: 'Overdue invoices', blocked: 'Placing orders is suspended until the overdue invoices are paid.', grace: 'Orders can still be placed until {d}. From {b} placing orders will be suspended.', inv: 'Invoice', due: 'Due date', unpaid: 'Unpaid', qr: 'QR payment', more: 'and more ({n})', list: 'Show my invoices', detail: 'Show full notice', close: 'Close', checking: 'Checking invoices…', btn: 'The order cannot be placed – there are overdue invoices on your account.' } }[L]; var DEFAULT_TEXT = { sk: '

Vážený obchodný partner,

radi by sme Vás upozornili, že evidujeme neuhradené faktúry po splatnosti. Z tohto dôvodu bude dočasne pozastavená možnosť zadávať nové objednávky, až do vyrovnania všetkých záväzkov.

Prosíme Vás o úhradu faktúr v čo najkratšom termíne.

Prehľad vašich faktúr nájdete vo svojom zákazníckom účte.

Upozorňujeme, že proces spárovania platby môže trvať určitý čas, preto nebude objednávanie odblokované okamžite po úhrade.

Ďakujeme za pochopenie a spoluprácu.

', cz: '

Vážený obchodní partner,

rádi bychom Vás upozornili, že evidujeme neuhrazené faktury po splatnosti. Z tohoto důvodu bude dočasně pozastavena možnost zadávat nové objednávky, a to až do vyrovnání všech závazků.

Prosíme Vás o úhradu faktur v co nejkratším možném termínu.

Přehled Vašich faktur naleznete ve svém zákaznickém účtu.

Upozorňujeme, že proces spárování platby může trvat určitou dobu, proto nebude možnost objednávání odblokována okamžitě po úhradě.

Děkujeme za pochopení a spolupráci.

', hu: '

Tisztelt Üzleti Partnerünk,

szeretnénk felhívni a figyelmét arra, hogy nyilvántartásunk szerint lejárt, ki nem egyenlített számlák vannak. Ennek következtében az új rendelések leadásának lehetősége ideiglenesen felfüggesztésre kerül mindaddig, amíg valamennyi tartozás kiegyenlítésre nem kerül.

Kérjük, hogy a számlák kiegyenlítéséről a lehető legrövidebb időn belül gondoskodjon.

Számlái áttekintését a saját ügyfélfiókjában találja meg.

Felhívjuk figyelmét, hogy a befizetések párosításának folyamata bizonyos időt vehet igénybe, ezért a rendelési lehetőség nem kerül azonnal feloldásra a befizetést követően.

Köszönjük megértését és együttműködését.

', pl: '

Szanowny Partnerze Handlowy,

uprzejmie informujemy, że odnotowaliśmy nieopłacone faktury po terminie płatności. W związku z tym możliwość składania nowych zamówień zostanie czasowo wstrzymana do momentu uregulowania wszystkich zobowiązań.

Prosimy o jak najszybsze opłacenie faktur.

Zestawienie Państwa faktur znajduje się na Państwa koncie klienta.

Informujemy, że zaksięgowanie płatności może potrwać pewien czas, dlatego możliwość składania zamówień nie zostanie odblokowana natychmiast po dokonaniu płatności.

Dziękujemy za zrozumienie i współpracę.

', en: '

Dear Business Partner,

we would like to inform you that we have recorded unpaid overdue invoices. For this reason, the possibility of placing new orders will be temporarily suspended until all outstanding amounts have been settled.

Please pay the invoices as soon as possible.

You can find an overview of your invoices in your customer account.

Please note that matching the payment may take some time, so ordering will not be unblocked immediately after payment.

Thank you for your understanding and cooperation.

' }[L]; // ---------- pomocné ---------- function hash(s) { var h = 0; for (var i = 0; i < s.length; i++) { h = ((h << 5) - h + s.charCodeAt(i)) | 0; } return (h >>> 0).toString(36); } function esc(s) { return String(s).replace(/[&<>"']/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c]; }); } function today() { var d = new Date(); d.setHours(0, 0, 0, 0); return d; } function addDays(d, n) { var x = new Date(d.getTime()); x.setDate(x.getDate() + n); return x; } function fmt(d) { return ('0' + d.getDate()).slice(-2) + '.' + ('0' + (d.getMonth() + 1)).slice(-2) + '.' + d.getFullYear(); } function lsGet(k) { try { return JSON.parse(localStorage.getItem(k) || 'null'); } catch (e) { return null; } } function lsSet(k, v) { try { localStorage.setItem(k, JSON.stringify(v)); } catch (e) {} } function ssGet(k) { try { return sessionStorage.getItem(k); } catch (e) { return null; } } function ssSet(k, v) { try { sessionStorage.setItem(k, v); } catch (e) {} } var MONTHS = { jan: 1, feb: 2, mar: 3, apr: 4, may: 5, jun: 6, jul: 7, aug: 8, sep: 9, oct: 10, nov: 11, dec: 12 }; function parseDate(s) { s = (s || '').trim(); var m = s.match(/^(\d{1,2})\.\s*([A-Za-z]{3}|\d{1,2})\.?\s*(\d{4})/); if (m) { var mo = /\d/.test(m[2]) ? +m[2] : MONTHS[m[2].toLowerCase()]; if (mo) return new Date(+m[3], mo - 1, +m[1]); } m = s.match(/^(\d{4})[.\-\/]\s*(\d{1,2})[.\-\/]\s*(\d{1,2})/); if (m) return new Date(+m[1], +m[2] - 1, +m[3]); return null; } function parseAmount(s) { s = (s || '').replace(/[^\d,.\-]/g, ''); if (s.indexOf(',') > -1 && s.indexOf('.') > -1) s = s.replace(/,/g, ''); else s = s.replace(',', '.'); var v = parseFloat(s); return isNaN(v) ? 0 : v; } var emailM = (document.querySelector('.header-basic-info') || {}).textContent || ''; emailM = (emailM.match(/[\w.+-]+@[\w.-]+\.\w+/) || [''])[0]; var ACC = hash(firmaEl.textContent.trim() + '|' + emailM); var CACHE_KEY = 'ags_splat_' + lang + '_' + ACC; var base = '/' + lang + '/buxus/generate_page.php?page_id='; // ---------- načítanie dát ---------- function loadSettings() { return fetch(base + SETTINGS_PAGE, { credentials: 'same-origin' }).then(function (r) { return r.text(); }).then(function (h) { var d = new DOMParser().parseFromString(h, 'text/html'); var days = parseInt(((d.title || '').match(/\d+/) || [''])[0], 10); var c = d.querySelector('main .content'); var title = '', text = ''; if (c) { var cl = c.cloneNode(true); var h1 = cl.querySelector('h1, h2'); if (h1) { title = h1.textContent.trim(); h1.remove(); } text = cl.innerHTML.trim(); } if (!/Vážen|Tisztelt|Szanown|Dear|partner/i.test(text)) text = ''; // stránka sa nenačítala správne return { days: isNaN(days) ? DEFAULT_DAYS : days, title: title, text: text }; }).catch(function () { return { days: DEFAULT_DAYS, title: '', text: '' }; }); } function loadInvoicePage(p) { var fd = new FormData(); fd.append('date_from', '01.01.2000'); fd.append('date_to', ''); fd.append('sort_by', 'unpaid'); fd.append('summary_filter_box_form', 'Zobraz'); return fetch(base + INVOICES_PAGE + '&results_per_page=' + PER_PAGE + '&page=' + p, { method: 'POST', body: fd, credentials: 'same-origin' }) .then(function (r) { return r.text(); }) .then(function (h) { var d = new DOMParser().parseFromString(h, 'text/html'); if (!d.querySelector('.header-basic-info h3')) throw new Error('not-logged'); if (!d.querySelector('[name="date_from"]')) throw new Error('no-invoice-page'); var rows = [].slice.call(d.querySelectorAll('table tr')).filter(function (r) { return r.querySelectorAll('td').length >= 8; }); return rows.map(function (r) { var c = r.cells; var pdfA = r.querySelector('a[href*="invoice_id="]'); return { no: c[0].textContent.trim(), pdf: pdfA ? pdfA.href : '', due: c[3].textContent.trim(), unpaidTxt: c[7].textContent.trim(), unpaid: parseAmount(c[7].textContent), credit: /dobropis/i.test(r.className) }; }); }); } function loadInvoices() { var all = []; function next(p) { return loadInvoicePage(p).then(function (rows) { all = all.concat(rows); var last = rows[rows.length - 1]; // zoradené podľa nezaplatenej sumy zostupne → ďalšia strana len ak sú na tejto ešte nezaplatené if (rows.length >= PER_PAGE && last && last.unpaid > 0 && p < MAX_PAGES) return next(p + 1); return all; }); } return next(1); } function evaluate(invoices, days) { var t = today(), overdue = []; var sums = { unpaidCount: 0, unpaidSum: 0, overdueCount: 0, overdueSum: 0, cur: '', dec: 2 }; invoices.forEach(function (i) { if (i.credit || !(i.unpaid > 0)) return; sums.unpaidCount++; sums.unpaidSum += i.unpaid; if (!sums.cur) { sums.cur = (i.unpaidTxt.match(/[^\d\s.,\-]+\.?$/) || [''])[0]; sums.dec = /[.,]\d{2}\s*\D*$/.test(i.unpaidTxt) ? 2 : 0; } var due = parseDate(i.due); if (!due) return; if (t > due) { overdue.push({ no: i.no, pdf: i.pdf || '', due: fmt(due), dueTs: due.getTime(), unpaidTxt: i.unpaidTxt }); sums.overdueCount++; sums.overdueSum += i.unpaid; } }); overdue.sort(function (a, b) { return a.dueTs - b.dueTs; }); if (!overdue.length) return { state: 'ok', overdue: [], sums: sums }; var blockDate = addDays(new Date(overdue[0].dueTs), days); return { state: t >= blockDate ? 'blocked' : 'warn', overdue: overdue, sums: sums, blockDate: fmt(blockDate), lastDay: fmt(addDays(blockDate, -1)) }; } function getStatus(fresh) { var c = lsGet(CACHE_KEY); if (!fresh && c && c.v === 2 && c.t && (Date.now() - c.t) < CACHE_MIN * 60000 && c.day === fmt(today())) return Promise.resolve(c); var settingsP = (c && c.settings && (Date.now() - c.t) < CACHE_MIN * 60000) ? Promise.resolve(c.settings) : loadSettings(); return Promise.all([settingsP, loadInvoices()]).then(function (res) { var s = res[0], ev = evaluate(res[1], s.days); var out = { v: 2, t: Date.now(), day: fmt(today()), settings: s, state: ev.state, overdue: ev.overdue, sums: ev.sums, blockDate: ev.blockDate, lastDay: ev.lastDay }; lsSet(CACHE_KEY, out); return out; }); } // ---------- zobrazenie ---------- var CSS = '' + '.ags-splat-bar{margin:0;padding:12px 16px;font:14px/1.45 Arial,Helvetica,sans-serif;color:#fff;position:relative;z-index:50}' + '.ags-splat-bar.warn{background:#d9822b}.ags-splat-bar.blocked{background:#c0392b}' + '.ags-splat-bar .in{max-width:1170px;margin:0 auto}' + '.ags-splat-bar b.t{font-size:15px;display:block;margin-bottom:2px}' + '.ags-splat-bar table{border-collapse:collapse;margin:6px 0;background:rgba(255,255,255,.12)}' + '.ags-splat-bar td,.ags-splat-bar th{padding:2px 12px 2px 0;text-align:left;font-size:13px;color:#fff}' + '.ags-splat-bar td:first-child,.ags-splat-bar th:first-child{padding-left:8px}' + '.ags-splat-bar a{color:#fff;text-decoration:underline;margin-right:16px;cursor:pointer}' + '.ags-splat-md a.ags-splat-qr{color:#1c84c6;cursor:pointer;font-weight:bold;white-space:nowrap}.ags-splat-bar a.ags-splat-qr{margin:0;font-weight:bold}' + '.ags-splat-ov{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:100000;display:flex;align-items:center;justify-content:center;padding:16px}' + '.ags-splat-md{background:#fff;color:#222;max-width:620px;width:100%;max-height:90vh;overflow:auto;border-radius:6px;box-shadow:0 10px 40px rgba(0,0,0,.3);font:14px/1.5 Arial,Helvetica,sans-serif}' + '.ags-splat-md h3{margin:0;padding:14px 20px;color:#fff;font-size:17px}' + '.ags-splat-md.warn h3{background:#d9822b}.ags-splat-md.blocked h3{background:#c0392b}' + '.ags-splat-md .bd{padding:16px 20px}.ags-splat-md .st{font-weight:bold;margin:0 0 10px}' + '.ags-splat-md table{border-collapse:collapse;width:100%;margin:10px 0}' + '.ags-splat-md td,.ags-splat-md th{border-bottom:1px solid #eee;padding:4px 6px;text-align:left;font-size:13px}' + '.ags-splat-md .ft{padding:0 20px 16px;text-align:right}' + '.ags-splat-md .ft a,.ags-splat-md .ft button{display:inline-block;margin-left:8px;padding:7px 14px;border-radius:4px;border:0;font-size:13px;cursor:pointer;text-decoration:none}' + '.ags-splat-md .ft a{background:#1c84c6;color:#fff}.ags-splat-md .ft button{background:#e5e5e5;color:#222}' + '.ags-splat-note{clear:both;display:block;margin:8px 0 0;padding:10px 12px;background:#fdecea;color:#c0392b;border:1px solid #f5c6cb;border-radius:4px;font-weight:bold;text-align:left}' + '.ags-splat-note.chk{background:#f4f4f4;color:#555;border-color:#ddd;font-weight:normal}'; function injectCss() { if (document.getElementById('ags-splat-css')) return; var s = document.createElement('style'); s.id = 'ags-splat-css'; s.textContent = CSS; document.head.appendChild(s); } function statusLine(st) { return st.state === 'blocked' ? UI.blocked : UI.grace.replace('{d}', st.lastDay).replace('{b}', st.blockDate); } // QR platba / náhľad – ak beží skript faktury-nahlad.js.txt (window.agsFaktura) function invTable(st, max) { var hasFx = !!(window.agsFaktura && window.agsFaktura.openQR); var rows = st.overdue.slice(0, max).map(function (i) { var act = hasFx && i.pdf ? '' + esc(UI.qr) + '' : ''; return '' + esc(i.no) + '' + esc(i.due) + '' + esc(i.unpaidTxt) + '' + act + ''; }).join(''); var more = st.overdue.length > max ? '' + esc(UI.more.replace('{n}', st.overdue.length - max)) + '' : ''; return '' + (hasFx ? '' : '') + '' + rows + more + '
' + UI.inv + '' + UI.due + '' + UI.unpaid + '
'; } function bindQr(root) { [].forEach.call(root.querySelectorAll('a.ags-splat-qr'), function (a) { a.addEventListener('click', function (e) { e.preventDefault(); window.agsFaktura.openQR(a.getAttribute('data-pdf'), a.getAttribute('data-no'), a.getAttribute('data-amt')); }); }); } function showBar(st) { var old = document.getElementById('ags-splat-bar'); if (old) old.remove(); if (st.state === 'ok') return; var bar = document.createElement('div'); bar.id = 'ags-splat-bar'; bar.className = 'ags-splat-bar ' + st.state; bar.setAttribute('role', 'alert'); bar.innerHTML = '
' + esc(st.settings.title || UI.title) + '' + esc(statusLine(st)) + invTable(st, 5) + '' + UI.list + '' + UI.detail + '
'; bar.querySelector('.ags-splat-open').addEventListener('click', function () { showModal(st); }); bindQr(bar); document.body.insertBefore(bar, document.body.firstChild); } function showModal(st) { if (document.getElementById('ags-splat-ov')) return; var ov = document.createElement('div'); ov.id = 'ags-splat-ov'; ov.className = 'ags-splat-ov'; ov.innerHTML = ''; function close() { ov.remove(); } ov.querySelector('button').addEventListener('click', close); ov.addEventListener('click', function (e) { if (e.target === ov) close(); }); bindQr(ov); document.body.appendChild(ov); } // ---------- blokácia odoslania (Súhrn objednávky) ---------- var summaryForm = !ENFORCE ? null : (function () { var h = document.querySelector('input[name="b2_b_summary_form"]'); return h ? h.form || h.closest('form') : null; })(); var submitState = 'checking'; var note = null; function setNote(cls, txt) { if (!summaryForm) return; if (!note) { note = document.createElement('div'); summaryForm.appendChild(note); } note.className = 'ags-splat-note ' + cls; note.textContent = txt; note.style.display = txt ? '' : 'none'; } function setButtons(disabled) { if (!summaryForm) return; [].forEach.call(summaryForm.querySelectorAll('input[type=submit],button[type=submit],button:not([type])'), function (b) { b.disabled = disabled; b.style.opacity = disabled ? '.45' : ''; b.style.cursor = disabled ? 'not-allowed' : ''; }); } if (summaryForm) { setButtons(true); setNote('chk', UI.checking); summaryForm.addEventListener('submit', function (e) { if (submitState !== 'ok') { e.preventDefault(); e.stopImmediatePropagation(); if (submitState === 'blocked') { var c = lsGet(CACHE_KEY); if (c) showModal(c); } } }, true); } // ---------- hlavička + zoznam faktúr: prepočet, farby, filtre ---------- var FUI = { sk: { all: 'Všetky', paid: 'Zaplatené', unpaid: 'V splatnosti', overdue: 'Po splatnosti', due: 'V splatnosti', credit: 'Dobropis', none: 'Pre tento filter nie sú žiadne faktúry.', more: 'Zobrazených je prvých {n} nezaplatených faktúr – ďalšie nájdete na ďalšej strane.', paidNote: 'Filter „Zaplatené“ platí pre práve zobrazenú stranu a obdobie.' }, cz: { all: 'Všechny', paid: 'Zaplacené', unpaid: 'Ve splatnosti', overdue: 'Po splatnosti', due: 'Ve splatnosti', credit: 'Dobropis', none: 'Pro tento filtr nejsou žádné faktury.', more: 'Zobrazeno je prvních {n} nezaplacených faktur – další najdete na další straně.', paidNote: 'Filtr „Zaplacené“ platí pro právě zobrazenou stranu a období.' }, hu: { all: 'Összes', paid: 'Kifizetett', unpaid: 'Nem lejárt', overdue: 'Lejárt', due: 'Nem lejárt', credit: 'Jóváírás', none: 'Ehhez a szűrőhöz nincs számla.', more: 'Az első {n} kifizetetlen számla látható – a többi a következő oldalon.', paidNote: 'A „Kifizetett” szűrő az aktuális oldalra és időszakra vonatkozik.' }, pl: { all: 'Wszystkie', paid: 'Opłacone', unpaid: 'W terminie', overdue: 'Po terminie', due: 'W terminie', credit: 'Korekta', none: 'Brak faktur dla tego filtra.', more: 'Wyświetlono pierwsze {n} nieopłaconych faktur – kolejne na następnej stronie.', paidNote: 'Filtr „Opłacone” dotyczy bieżącej strony i okresu.' }, en: { all: 'All', paid: 'Paid', unpaid: 'Not yet due', overdue: 'Overdue', due: 'Not yet due', credit: 'Credit note', none: 'No invoices match this filter.', more: 'The first {n} unpaid invoices are shown – see the next page for more.', paidNote: 'The “Paid” filter applies to the current page and period.' } }[L]; var FILTER_KEY = 'ags_inv_filter'; var FILTER_SUBMIT_KEY = 'ags_inv_filter_submitted'; var FROM_ALL = '01.01.2000'; var CSS2 = '' + 'tr.ags-inv-paid>td:not(:last-child){color:#1e7e34!important}' + 'tr.ags-inv-due>td:not(:last-child){color:#d9822b!important}' + 'tr.ags-inv-overdue>td:not(:last-child){color:#c0392b!important;font-weight:bold}' + 'tr.ags-inv-hidden,tr.ags-inv-hidden+tr.ags-inv-detail{display:none!important}' + '.ags-inv-filters{clear:both;display:block;width:100%;float:none;box-sizing:border-box;padding:18px 15px 6px;margin:0;font:13px/1.4 Arial,Helvetica,sans-serif}' + '.ags-inv-filters a{float:none!important;position:static!important;display:inline-block;margin:0 6px 6px 0;padding:5px 12px;border:1px solid #c9d6e2;border-radius:14px;background:#fff;color:#333;cursor:pointer;text-decoration:none}' + '.ags-inv-filters a.ags-on{background:#1c84c6;border-color:#1c84c6;color:#fff}' + '.ags-inv-filters i{display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:6px;vertical-align:0}' + '.header-invoices .row.ags-h-paid,.header-invoices .row.ags-h-paid *{color:#1e7e34!important}' + '.header-invoices .row.ags-h-unpaid,.header-invoices .row.ags-h-unpaid *{color:#d9822b!important}' + '.header-invoices .row.ags-h-overdue,.header-invoices .row.ags-h-overdue *{color:#c0392b!important;font-weight:bold}' + '.header-invoices .row a{cursor:pointer}' + '.ags-inv-msg{padding:4px 0 0;color:#555;font-style:italic}'; var DOT = { paid: '#1e7e34', due: '#d9822b', overdue: '#c0392b', credit: '#0000aa', unpaid: '#d9822b', all: '#999' }; function injectCss2() { if (document.getElementById('ags-splat-css2')) return; var s = document.createElement('style'); s.id = 'ags-splat-css2'; s.textContent = CSS2; document.head.appendChild(s); } function fmtMoney(v, cur, dec) { var s = v.toFixed(dec), parts = s.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ' '); return parts.join('.') + (cur ? ' ' + cur : ''); } function invoicesHref() { var a = document.querySelector('.header-invoices h4 a, .header-invoices a'); return a ? a.getAttribute('href').split('#')[0] : base + INVOICES_PAGE; } // filter z odkazu v hlavičke (#ags-f=overdue …) function takeHashFilter() { var m = (location.hash || '').match(/ags-f=(all|paid|unpaid|overdue)/); if (!m) return false; ssSet(FILTER_KEY, m[1]); ssSet(FILTER_KEY + '_ts', String(Date.now())); try { sessionStorage.removeItem(FILTER_SUBMIT_KEY); } catch (e) {} try { history.replaceState(null, '', location.pathname + location.search); } catch (e) {} return true; } function goFilter(f) { ssSet(FILTER_KEY, f); ssSet(FILTER_KEY + '_ts', String(Date.now())); try { sessionStorage.removeItem(FILTER_SUBMIT_KEY); } catch (e) {} var target = invoicesHref(); var here = location.pathname.replace(/\/$/, ''); var tp = target.replace(/^https?:\/\/[^\/]+/, '').split('?')[0].replace(/\/$/, ''); if (invForm && here === tp) { applyInvoiceFilter(); return; } if (f === 'unpaid' || f === 'overdue') { // rovno POST s filtrom (celé obdobie, zoradené podľa nezaplatenej sumy) – jedno načítanie, bez preteku s iným skriptom ssSet(FILTER_SUBMIT_KEY, f); var fm = document.createElement('form'); fm.method = 'post'; fm.action = target.split('#')[0].split('?')[0] + '?results_per_page=' + PER_PAGE; fm.style.display = 'none'; [['date_from', FROM_ALL], ['date_to', ''], ['sort_by', 'unpaid'], ['summary_filter_box_form', 'Zobraz']].forEach(function (kv) { var i = document.createElement('input'); i.type = 'hidden'; i.name = kv[0]; i.value = kv[1]; fm.appendChild(i); }); document.body.appendChild(fm); HTMLFormElement.prototype.submit.call(fm); return; } location.href = target; } // kliknutie v hlavičke zachytíme skôr ako iné skripty stránky (capture fáza) var HDR_MAP = ['all', 'paid', 'unpaid', 'overdue']; document.addEventListener('click', function (e) { if (e.button !== 0 || e.ctrlKey || e.metaKey || e.shiftKey) return; var a = e.target && e.target.closest ? e.target.closest('.header-invoices .row a') : null; if (!a) return; var row = a.closest('.row'); var idx = [].indexOf.call(document.querySelectorAll('.header-invoices .row'), row); var f = HDR_MAP[idx]; if (!f) return; e.preventDefault(); e.stopImmediatePropagation(); goFilter(f); }, true); // hlavička: Nezaplatené a Po splatnosti cez všetky roky + funkčné odkazy function patchHeader(st) { var box = document.querySelector('.header-invoices'); if (!box) return; var rows = box.querySelectorAll('.row'); var map = ['all', 'paid', 'unpaid', 'overdue']; [].forEach.call(rows, function (row, idx) { var f = map[idx]; if (!f) return; if (f !== 'all') row.classList.add('ags-h-' + f); // odkaz nesie filter v #hashi – funguje aj bez obsluhy kliknutia [].forEach.call(row.querySelectorAll('a'), function (a) { var h = (a.getAttribute('href') || invoicesHref()).split('#')[0]; a.setAttribute('href', h + '#ags-f=' + f); }); if (!st || !st.sums) return; // V splatnosti = nezaplatené mínus po splatnosti (kategórie sa neprekrývajú) var cnt = f === 'unpaid' ? st.sums.unpaidCount - st.sums.overdueCount : f === 'overdue' ? st.sums.overdueCount : null; if (cnt === null) return; var sum = Math.max(0, Math.round(((f === 'unpaid' ? st.sums.unpaidSum - st.sums.overdueSum : st.sums.overdueSum)) * 100) / 100); var lab = row.querySelector('span') || row.querySelector('b') || row.querySelector('a'); if (lab) { if (f === 'unpaid') lab.textContent = FUI.unpaid + ' (' + cnt + ')'; else lab.innerHTML = lab.innerHTML.replace(/\(\s*\d+\s*\)/, '(' + cnt + ')'); } var amt = row.querySelector('.text-right'); if (amt) { // mena a počet desatinných miest podľa nezaplatených faktúr, inak podľa riadku „Celkom“ v hlavičke (HU: bez desatinných miest) var ref = ((rows[0] && rows[0].querySelector('.text-right')) || amt).textContent.trim(); var cur = st.sums.cur || ((ref.match(/[^\d\s.,\-]+\.?$/) || [''])[0]); var dec = st.sums.cur ? st.sums.dec : (/[.,]\d{2}\s*\D*$/.test(ref) ? 2 : 0); amt.textContent = fmtMoney(sum, cur, dec); } }); } // zoznam faktúr: 4 farby + filter var invForm = (function () { var s = document.querySelector('[name="summary_filter_box_form"]'); return s ? s.form || s.closest('form') : null; })(); function invRows() { var t = invForm && (invForm.parentNode.querySelector('table') || document.querySelector('main table')); if (!t) { var all = document.querySelectorAll('table'); for (var i = 0; i < all.length; i++) if (/splatnost|splatnosť|határid|termin|due/i.test(all[i].textContent.slice(0, 400))) { t = all[i]; break; } } if (!t) return []; return [].slice.call(t.querySelectorAll('tr')).filter(function (r) { return r.cells.length >= 8 && r.querySelector('td') && !/ags-inv-detail/.test(r.className); }); } function rowStatus(r) { if (/dobropis/i.test(r.className)) return 'credit'; var unpaid = parseAmount(r.cells[7].textContent); if (!(unpaid > 0)) return 'paid'; var due = parseDate(r.cells[3].textContent); return due && today() > due ? 'overdue' : 'due'; } function colorRows() { invRows().forEach(function (r) { var s = rowStatus(r); r.__agsS = s; r.classList.remove('ags-inv-paid', 'ags-inv-due', 'ags-inv-overdue'); if (s !== 'credit') r.classList.add('ags-inv-' + s); }); } var filterBar = null; function renderFilterBar(active) { if (!invForm) return; if (!filterBar) { filterBar = document.createElement('div'); filterBar.className = 'ags-inv-filters'; invForm.parentNode.insertBefore(filterBar, invForm.nextSibling); } var btns = ['all', 'unpaid', 'overdue', 'paid'].map(function (f) { return '' + (f !== 'all' ? '' : '') + FUI[f] + ''; }).join(''); filterBar.innerHTML = btns + ''; [].forEach.call(filterBar.querySelectorAll('a[data-f]'), function (a) { a.addEventListener('click', function () { goFilter(a.getAttribute('data-f')); }); }); } function applyInvoiceFilter() { if (!invForm) return; var f = ssGet(FILTER_KEY) || 'all'; var df = invForm.querySelector('[name="date_from"]'), sb = invForm.querySelector('[name="sort_by"]'); var dt = invForm.querySelector('[name="date_to"]'); // Nezaplatené / Po splatnosti: celé obdobie, zoradené podľa nezaplatenej sumy → všetky nezaplatené sú na 1. strane if ((f === 'unpaid' || f === 'overdue') && !(df && df.value === FROM_ALL && sb && sb.value === 'unpaid' && (!dt || !dt.value))) { if (ssGet(FILTER_SUBMIT_KEY) !== f) { ssSet(FILTER_SUBMIT_KEY, f); if (df) df.value = FROM_ALL; if (dt) dt.value = ''; if (sb) sb.value = 'unpaid'; invForm.setAttribute('action', location.pathname + '?results_per_page=' + PER_PAGE); var btn = invForm.querySelector('[name="summary_filter_box_form"]'); var hid = document.createElement('input'); hid.type = 'hidden'; hid.name = 'summary_filter_box_form'; hid.value = btn ? btn.value : 'Zobraz'; invForm.appendChild(hid); HTMLFormElement.prototype.submit.call(invForm); return; } } try { sessionStorage.removeItem(FILTER_SUBMIT_KEY); } catch (e) {} renderFilterBar(f); var rows = invRows(), shown = 0; rows.forEach(function (r) { var s = r.__agsS || rowStatus(r); var ok = f === 'all' || (f === 'paid' && s === 'paid') || (f === 'unpaid' && s === 'due') || (f === 'overdue' && s === 'overdue'); r.classList.toggle('ags-inv-hidden', !ok); if (ok) shown++; }); var msg = filterBar.querySelector('.ags-inv-msg'); var txt = ''; if (f !== 'all' && !shown) txt = FUI.none; else if ((f === 'unpaid' || f === 'overdue') && rows.length >= PER_PAGE && rows[rows.length - 1] && parseAmount(rows[rows.length - 1].cells[7].textContent) > 0) txt = FUI.more.replace('{n}', rows.length); else if (f === 'paid') txt = FUI.paidNote; msg.textContent = txt; msg.style.display = txt ? '' : 'none'; } function initInvoicePage() { if (!invForm) return; // filter platí len pri príchode cez naše odkazy (hlavička / tlačidlá) alebo pri stránkovaní; // otvorenie „Moje faktúry“ z menu ukáže všetky faktúry var fresh = Date.now() - (+ssGet(FILTER_KEY + '_ts') || 0) < 15000; if (!fresh) ssSet(FILTER_KEY, 'all'); document.addEventListener('click', function (e) { var a = e.target && e.target.closest ? e.target.closest('a[href*="page="], a[href*="results_per_page="]') : null; if (a) ssSet(FILTER_KEY + '_ts', String(Date.now())); }, true); takeHashFilter(); window.addEventListener('hashchange', function () { if (takeHashFilter()) applyInvoiceFilter(); }); colorRows(); // ručné použitie filtra dátumov (tlačidlo Zobraz) zruší náš filter invForm.addEventListener('submit', function (e) { if (e.isTrusted) { ssSet(FILTER_KEY, 'all'); } }); applyInvoiceFilter(); // riadky „Položky“ pridáva reklamačný skript dodatočne – farby udržať var t = invRows()[0]; t = t && t.closest('table'); if (t && window.MutationObserver) new MutationObserver(function () { colorRows(); }).observe(t, { childList: true, subtree: true }); } // ---------- štart ---------- injectCss(); injectCss2(); var cached = lsGet(CACHE_KEY); if (cached && cached.v === 2 && cached.day === fmt(today())) { patchHeader(cached); if (ENFORCE && !summaryForm) showBar(cached); } else patchHeader(null); initInvoicePage(); var loginRef = /vazeni-navstevnici|prihlaseni|kedves-latogatok|logowanie|login/i.test(document.referrer || ''); var seenKey = 'ags_splat_seen_' + ACC; function run(attempt) { getStatus(!!summaryForm).then(function (st) { patchHeader(st); if (!ENFORCE) return; showBar(st); if (st.state !== 'ok' && (loginRef || !ssGet(seenKey) || (summaryForm && st.state === 'blocked'))) { ssSet(seenKey, '1'); showModal(st); } if (summaryForm) { submitState = st.state === 'blocked' ? 'blocked' : 'ok'; setButtons(submitState === 'blocked'); setNote('', submitState === 'blocked' ? UI.btn : ''); } }).catch(function (err) { if (attempt < 1) return setTimeout(function () { run(attempt + 1); }, 1500); if (window.console) console.warn('[AGS splatnosť] stav faktúr sa nepodarilo zistiť – objednávka sa neblokuje', err); if (summaryForm) { submitState = 'ok'; setButtons(false); setNote('', ''); } }); } run(0); })();