/* ags 92 – B2B reklamačný modul (SK/CZ/HU) * Umiestnenie: /buxus/docs/reklamacia.js.txt (BUXUS neprijíma .js, text/plain sa v prehliadačoch spúšťa), načítané v pätičke (Content after kontajnera 22) * Čo robí: * 1. Presmerovanie po prihlásení: URL ?goto=reklamacia&zdroj=...&objednavka=... sa uloží (30 min) * a po prihlásení sa partner presmeruje na stránku Reklamácie (page_id 652491). * 2. Na stránke Reklamácie (div#ags-reklamacia-app): značka → produkt (z XML feedu) → kód + EAN, * vyhľadanie faktúry v PDF faktúrach partnera (24 mesiacov, na vyžiadanie 48) → otvorenie Tally formulára s predvyplnenými poľami. * 3. (verzia g, 29. 9. 2026) „Moje reklamácie“: zoznam odoslaných reklamácií s termínom voči koncovému zákazníkovi * (SK/CZ 30 dní, HU 15/30 dní od dátumu reklamácie zákazníka), partner si sám označí „vybavené“. * Uložené LEN v prehliadači partnera (localStorage ags_rekl_moje_{trh}_{účet}), export/import CSV. Dátum zákazníka ide do Tally ako `prijate`. * Oprava: PSČ/mesto z hlavičky podľa formátu trhu (SK/CZ 5 číslic, HU 4). * 4. (verzia h, 29. 9. 2026) Krok 4: „Kto reklamuje“ (zákazník / vada na sklade), dátum kúpy zákazníkom → Tally `kupa`, `typ`; * 5. (verzia i, 30. 9. 2026) Moje reklamácie → „Zobraziť“: kópia odpovedí z Tally (uložená pri odoslaní, iba v prehliadači), tlač/PDF; * IČO/DIČ partnera bez identifikátorov AGS 92 z pätičky (+ z faktúry „Odberateľ“), PSČ na samostatnom riadku, HU formát dátumu v zozname produktov, * dátum slovom pod dátumovými poľami (jednoznačné v každom jazyku prehliadača), HU „bejelentésének dátuma“ namiesto „átvételének“. * 6. (verzia j, 30. 9. 2026) Medzi vlastné identifikátory AGS 92 doplnené IČO a IČ DPH organizačnej zložky Senica (sú na HU faktúrach). * 7. (verzia m, 9. 10. 2026) Krok „Adresa prevádzky“: predvolí dodaciu adresu zo zvolenej faktúry (blok DODACIA ADRESA v PDF z Money), * ponúkne prevádzky z faktúr (2+ dodávky), z Dodacích údajov v košíku (cache) a fakturačnú adresu; „Iná adresa“ ručne. * Do Tally ide ulica/psc/mesto/krajina zvolenej prevádzky + skryté pole `prevadzka` = „firma – kontakt prevádzky“ (meno v sekcii 6). * 8. (verzia n, 9. 10. 2026) Kód reklamácie `rid` (náhodný, 22 znakov) → Tally skryté pole `rid` → Most v0.7 (list B2B). * „Pokračovať na mobile“: QR kód s krátkym odkazom Mosta (?a=m&r=rid) na ten istý predvyplnený formulár (fotky a video z telefónu). * „Moje reklamácie“: stav z Mosta (?a=st) – odoslané, číslo a stav reklamácie v servise, súbory (fotky, video) aj pri odoslaní z mobilu. * Interné poznámky servisu sa nečítajú. Bez Mosta (MOST = '') sa správa ako verzia m. * Verzia l (9. 10.): predvolenie až po načítaní PDF, HU bez načítania košíka (predvolí adresu z faktúry), CZ cesta /cz/dodacie-udaje. * Verzia m (9. 10.): krajina z PDF (napr. „Hungary“) sa pri vlastnej krajine trhu nahradí názvom z účtu partnera. * upozornenie po 24 mesiacoch od kúpy; doklad o kúpe nahráva partner v Tally (povinné, skryté pri typ=sklad). * 9. (verzia o, 10. 10. 2026) Fotky a video z telefónu (Most v0.8): v kroku 6 partner zvolí „Odfotím telefónom“ (predvolené) alebo „Nahrám z počítača“. * Telefón: Tally dostane skryté pole media=mobil (sekcia 5, doklad a foto štítku skryté) → po odoslaní textu sa zobrazí QR kód (Most ?a=m&r=rid): * telefón prevedie krokmi FOTO 1, FOTO 2, ŠTÍTOK, DOKLAD (mini-formulár Tally) a VIDEO (stránka Mosta) → Most hneď odošle všetko do servisu. * Bez fotiek sa reklamácia do servisu neodošle – zoznam ukazuje „čaká na fotky“ + QR znova; po 7 dňoch „nedokončená“. Bez Mosta = len cesta cez počítač. * Verzia p (10. 10., po teste na Fiktívnej firme, servis 2604/2026): po prijatí fotiek veľký panel „Reklamácia je odoslaná“ so zoznamom prijatého * (FOTO 1, FOTO 2, štítok, doklad, video) namiesto dvoch pásikov; pod QR odkaz „nahrajte fotky z tohto počítača“ (ten istý postup v prehliadači PC); * prijaté súbory aj v detaile v zozname. Krok 6 bez predvoľby – partner si musí vybrať. * Verzia q (10. 10.): prázdny zoznam faktúr sa už NEukladá do cache na 6 h (jeden výpadok načítania = partner 6 h vidí „nemáte faktúry“, zistené * na Fiktívnej firme) – prázdny výsledok sa ukladá len na 2 min a ak cache tvrdí „0 faktúr“, pri ďalšom otvorení sa načíta znova. * Verzia r (10. 10.): zelený panel „Reklamácia je odoslaná“ už neopakuje značku pred názvom produktu („KINDERKRAFT KINDERKRAFT Kočík…“) – jediná zmena. */ (function () { 'use strict'; if (window.__agsReklamaciaLoaded) { return; } window.__agsReklamaciaLoaded = true; var PAGE_ID_REKLAMACIE = 652491; var PAGE_ID_FAKTURY = 257; var PAGE_ID_UCET = 220; var MONTHS_BACK = 24; /* predvolene */ var MONTHS_MAX = 48; /* na vyžiadanie tlačidlom „staršie faktúry“ */ var MAX_INVOICES = 1000; var GOTO_KEY = 'ags_rekl_goto'; var GOTO_TTL = 30 * 60 * 1000; var FEED_TTL = 24 * 60 * 60 * 1000; var MOST = 'https://script.google.com/macros/s/AKfycbyxeB8af_7zgvWCQW-i1jNKo2V2dbZx4D7oyw306CVpP1_uHGhcC7zfTcZgVGPVf9H8/exec'; /* web app Mosta v0.8 (samostatné nasadenie); prázdne = bez QR a bez stavu zo servisu */ var QRJS = 'https://cdnjs.cloudflare.com/ajax/libs/qrcode-generator/1.4.4/qrcode.min.js'; var ST_EVERY = 3 * 60 * 1000; /* stav z Mosta najviac raz za 3 min na zariadenie */ var MEDIA_DEFAULT = ''; /* v o: predvoľba v kroku 6 – '' = partner si musí vybrať (Peter 10. 10.), inak 'mobil' alebo 'pc' */ var WATCH_EVERY = 8000, WATCH_MAX = 45 * 60 * 1000; /* v o: kým partner fotí telefónom, PC sa pýta na stav každých 8 s, max. 45 min */ var PDFJS = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js'; var PDFJS_WORKER = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js'; var CFG = { sk: { formId: '9qV4YY', feed: 'https://data.ags92.com/xml/sk/all111/SK_VO_NEW_ALL.xml', brandTag: 'BRAND', codeTag: 'CODE', country: 'Slovensko', trh: 'SK' }, cz: { formId: 'gD2zPd', feed: 'https://data.ags92.com/data/all02/CZ_VO_NEW_ALL.xml', brandTag: 'ZNACKA', codeTag: 'CODE', country: 'Česká republika', trh: 'CZ' }, hu: { formId: 'GxWoGL', feed: 'https://data.ags92.com/xml/hu/hu_vo/HU_VO_NEW_ALL.xml', brandTag: 'BRAND', codeTag: 'ITEM_ID', country: 'Magyarország', trh: 'HU' } }; var T = { sk: { step1: '1. Vyberte reklamovaný produkt', srcInv: 'Z vašich faktúr', srcCat: 'Z aktuálneho katalógu', srcManual: 'Zadať ručne', boughtFilterPh: 'Hľadať v nakúpených produktoch (názov alebo kód)…', boughtLoading: 'Načítavam vaše faktúry…', boughtParsing: 'Načítavam položky z faktúr… {n}/{m} (zostáva cca {eta} min, zoznam sa priebežne dopĺňa; nabudúce už okamžite)', first400: 'zobrazených prvých 400 – spresnite hľadanie', more: 'Nenašli ste produkt? Prehľadať aj staršie faktúry (25 – 48 mesiacov)', moreLoading: 'Načítavam staršie faktúry…', moreDone: 'Prehľadané faktúry za posledných 48 mesiacov.', boughtEmpty: 'Za posledných 24 mesiacov nemáte faktúry – vyberte z katalógu alebo zadajte ručne.', step2: '2. Vyberte produkt', filterPh: 'Hľadať podľa názvu, kódu alebo EAN…', productPh: '– vyberte produkt –', brandPh: '– všetky značky –', count: '{n} produktov', code: 'Katalógový kód', ean: 'EAN kód', name: 'Presný názov produktu', brand: 'Značka', notFound: 'Produkt som nenašiel – zadám ho ručne', backToList: 'Späť na výber zo zoznamu', step3: '3. Faktúra', pickProductFirst: 'Najprv vyberte produkt.', searching: 'Prehľadávam vaše faktúry za posledných {mo} mesiacov… {n}/{m}', found: 'Produkt sme našli na týchto faktúrach – vyberte tú správnu:', none: 'Produkt sme na vašich faktúrach za posledných {mo} mesiacov nenašli. Zadajte číslo faktúry ručne.', invoicesError: 'Faktúry sa nepodarilo načítať – číslo faktúry zadajte ručne.', manualInvoice: 'Iná faktúra – zadajte číslo:', invoiceDate: 'zo dňa', feedLoading: 'Načítavam zoznam produktov…', feedError: 'Zoznam produktov sa nepodarilo načítať. Zadajte údaje ručne.', cont: 'Pokračovať na reklamačný formulár', validation: 'Vyplňte značku, názov produktu a katalógový kód.', openNew: 'Otvoriť formulár v novom okne', change: 'Zmeniť údaje', tabNew: 'Nová reklamácia', tabList: 'Moje reklamácie', stepA: '4. Adresa prevádzky', aHint: 'Tovar z faktúry {inv} bol dodaný na: {a}. Predvolili sme ju – ak je tovar inde, vyberte inú prevádzku.', aHint0: 'Vyberte prevádzku, kde sa reklamovaný tovar nachádza – na túto adresu vám vrátime vybavený tovar.', aInv: 'z tejto faktúry', aHq: 'fakturačná', aCnt: 'dodávky: {n}×', aOther: 'Iná adresa', aOtherSub: 'zadám ručne', aAll: 'Zobraziť všetky prevádzky ({n})', aLess: 'Zobraziť menej', aName: 'Názov prevádzky / kontakt', aStreet: 'Ulica a číslo', aZip: 'PSČ', aCity: 'Mesto', aFoot: 'Na túto adresu vám vrátime vybavený tovar. Vo formulári ju môžete ešte upraviť.', aLoading: 'Zisťujem adresu dodania z faktúry…', aMissing: 'Vyplňte ulicu, PSČ a mesto prevádzky.', step4: '5. Pre váš prehľad', custDate: 'Dátum prijatia reklamácie od vášho zákazníka', typLabel: 'Kto reklamuje?', typCust: 'Váš zákazník', typStock: 'Vada zistená u vás pred predajom (tovar na sklade)', kupa: 'Dátum kúpy zákazníkom (podľa dokladu)', receiptHint: 'Vo formulári priložíte fotografiu alebo scan dokladu o kúpe od zákazníka (pokladničný blok alebo faktúra, ktorú ste mu vystavili). Pripravte si ho.', kupaMissing: 'Vyplňte dátum kúpy podľa dokladu zákazníka.', kupaAfter: 'Dátum kúpy nemôže byť neskôr ako dátum prijatia reklamácie.', old24: 'Od kúpy uplynulo viac ako 24 mesiacov – reklamácia je pravdepodobne po záručnej dobe. Môžete ju odoslať, servis ju však môže zamietnuť.', stock: 'Sklad – bez lehoty', stockShort: 'Na sklade', bought: 'Kúpené {d}', note: 'Vaša poznámka (napr. číslo reklamácie zákazníka) – nepovinné', noteShort: 'Poznámka', custHint: 'Od tohto dňa plynie zákonná lehota 30 dní na vybavenie reklamácie zákazníkovi. Po odoslaní sa reklamácia uloží do zoznamu Moje reklamácie.', custFuture: 'Dátum nemôže byť v budúcnosti.', custMissing: 'Vyplňte dátum prijatia reklamácie od zákazníka.', listTitle: 'Moje odoslané reklamácie', listNote: 'Zoznam je uložený iba v tomto prehliadači na tomto počítači. Na inom zariadení ho neuvidíte – na prenos použite Export a Import.', doneHint: 'Stĺpec Vybavené je vaša vlastná evidencia. Keď zákazníkovi odovzdáte vybavenú reklamáciu, zaškrtnite ju tu a budete mať prehľad, čo je ešte otvorené. Spoločnosti AGS 92 sa tým nič neoznamuje.', fOpen: 'Otvorené', fDone: 'Vybavené', fAll: 'Všetky', cSent: 'Odoslané', cCust: 'Prijaté od zákazníka', cDl: 'Termín', cLeft: 'Zostáva', cProd: 'Produkt', cInv: 'Faktúra', cDone: 'Vybavené zákazníkovi', cDoneShort: 'Vybavené', daysLeft: 'zostáva {n}', overdue: 'po termíne {n}', today: 'termín je dnes', doneOn: 'vybavené {d}', hu15: '', pending: 'Neoverené – formulár ste otvorili v novom okne.', confirmSent: 'Áno, odoslal som', del: 'Zmazať', delSure: 'Naozaj zmazať?', edit: 'Upraviť', view: 'Zobraziť', dPicked: 'Zvolený dátum: {d}', dEmpty: 'Dátum vyberte v kalendári (ikona vpravo v poli).', detTitle: 'Odoslaná reklamácia', detSent: 'Odoslané {d}', detNo: 'Číslo podania', detPrint: 'Vytlačiť / uložiť ako PDF', detClose: 'Zavrieť', detOwn: 'Údaje z vášho prehľadu', detForm: 'Odpovede vo formulári', detNone: 'Pri tejto reklamácii nie sú uložené odpovede z formulára (bola odoslaná pred 30. 9. 2026, v inom prehliadači alebo pridaná ručne). Zobrazujeme údaje z vášho prehľadu.', detFiles: 'Súbory sú uložené v systéme AGS 92. Ak sa odkaz neotvorí, kontaktujte nás a uveďte číslo podania.', detLocal: 'Kópia odpovedí je uložená iba v tomto prehliadači.', detPrinted: 'Vytlačené z B2B portálu AGS 92 dňa {d}', add: 'Pridať reklamáciu odoslanú inak', save: 'Uložiť', cancel: 'Zrušiť', sentDate: 'Dátum odoslania', 'export': 'Export (CSV)', 'import': 'Import (CSV)', importDone: 'Pridané záznamy: {n}', importErr: 'Súbor sa nepodarilo načítať.', empty: 'Zatiaľ tu nemáte žiadnu reklamáciu. Po odoslaní reklamačného formulára sa sem pridá automaticky.', emptyFilter: 'V tomto filtri nie je žiadna reklamácia.', saved: 'Reklamácia bola odoslaná a pridaná do zoznamu Moje reklamácie.', another: 'Nahlásiť ďalšiu reklamáciu', showList: 'Zobraziť moje reklamácie', reqManual: 'Vyplňte aspoň názov produktu a dátum prijatia reklamácie od zákazníka.', mediaQ: 'Ako doplníte fotografie a video?', mediaMob: 'Odfotím produkt telefónom (aj video) – po odoslaní formulára sa zobrazí QR kód', mediaPc: 'Fotografie a video už mám v tomto počítači – nahrám ich vo formulári', mediaPick: 'Vyberte jednu z možností – podľa nej sa zobrazí formulár.', qrTitle: 'Teraz odfoťte produkt telefónom', qrHint: 'Naskenujte QR kód fotoaparátom telefónu. Telefón vás prevedie krokmi – nič netreba písať:', qrSteps: 'FOTO 1 celý produkt · FOTO 2 detail chyby · štítok s výrobným číslom · doklad od zákazníka · video (nepovinné)', qrRule: 'Bez fotografií sa reklamácia do servisu neodošle. Odkaz platí 7 dní.', qrLink: 'Odkaz pre telefón (môžete si ho poslať e-mailom):', qrShow: 'Zobraziť QR kód', qrHide: 'Skryť QR kód', textGot: 'Údaje sme prijali. Reklamácia odíde do servisu hneď, ako doplníte fotky.', doneTitle: 'Reklamácia je odoslaná do servisu', doneGot: 'Z telefónu sme prijali:', doneNext: 'Číslo a stav reklamácie zo servisu sa zobrazia v časti Moje reklamácie. Potvrdenie dostanete e-mailom zo servisu.', f1: 'FOTO 1 – celý produkt', f2: 'FOTO 2 – detail chyby', fsn: 'Štítok s výrobným číslom', fdk: 'Doklad o kúpe', fv: 'Video', fnone: 'bez videa', pcLink: 'Nemáte telefón po ruke? Nahrajte fotky z tohto počítača', wText: 'Odoslané – spracúva sa', wMedia: 'Čaká na fotky z telefónu', wVideo: 'Fotky prijaté – odosiela sa do servisu', wExpired: 'Nedokončená – chýbajú fotky, odkaz vypršal. Založte reklamáciu znova.', qrSentNow: 'Fotky prijaté – reklamácia je odoslaná do servisu.', mobBtn: 'Pokračovať na mobile', mobTitle: 'Dokončite reklamáciu v telefóne', mobHint: 'Naskenujte QR kód fotoaparátom telefónu. Otvorí sa ten istý formulár s vyplnenými údajmi – fotografie a video pridáte priamo z telefónu. Odkaz platí 7 dní.', mobLoading: 'Pripravujem QR kód…', mobErr: 'QR kód sa nepodarilo pripraviť. Použite formulár na tomto počítači.', mobDirect: 'Odkaz pre telefón (môžete si ho aj poslať e-mailom):', mobWait: 'Čaká na odoslanie z telefónu', mobSaved: 'Reklamácia čaká na odoslanie z telefónu. Po odoslaní sa tu zobrazí jej stav.', stSent: 'Prijaté – čaká na zaevidovanie v servise', stManual: 'Prijaté – servis zaeviduje ručne', stNo: 'Reklamácia č. {n}', stState: 'Stav v servise', stHandling: 'Spôsob vybavenia', stChecked: 'Posledná kontrola stavu', stClosed: 'uzavretá', stTitle: 'Stav reklamácie', stNum: 'Číslo reklamácie', stDesc: 'Popis problému', stFiles: 'Fotografie a video', stOffline: 'Stav sa nepodarilo načítať. Skúsime to znova pri ďalšej návšteve.', stVideoLink: 'Odkaz na video' }, cz: { step1: '1. Vyberte reklamovaný produkt', srcInv: 'Z vašich faktur', srcCat: 'Z aktuálního katalogu', srcManual: 'Zadat ručně', boughtFilterPh: 'Hledat v nakoupených produktech (název nebo kód)…', boughtLoading: 'Načítám vaše faktury…', boughtParsing: 'Načítám položky z faktur… {n}/{m} (zbývá cca {eta} min, seznam se průběžně doplňuje; příště už okamžitě)', first400: 'zobrazeno prvních 400 – upřesněte hledání', more: 'Nenašli jste produkt? Prohledat i starší faktury (25 – 48 měsíců)', moreLoading: 'Načítám starší faktury…', moreDone: 'Prohledány faktury za posledních 48 měsíců.', boughtEmpty: 'Za posledních 24 měsíců nemáte faktury – vyberte z katalogu nebo zadejte ručně.', step2: '2. Vyberte produkt', filterPh: 'Hledat podle názvu, kódu nebo EAN…', productPh: '– vyberte produkt –', brandPh: '– všechny značky –', count: '{n} produktů', code: 'Katalogové číslo', ean: 'EAN kód', name: 'Přesný název produktu', brand: 'Značka', notFound: 'Produkt jsem nenašel – zadám ho ručně', backToList: 'Zpět na výběr ze seznamu', step3: '3. Faktura', pickProductFirst: 'Nejprve vyberte produkt.', searching: 'Prohledávám vaše faktury za posledních {mo} měsíců… {n}/{m}', found: 'Produkt jsme našli na těchto fakturách – vyberte tu správnou:', none: 'Produkt jsme na vašich fakturách za posledních {mo} měsíců nenašli. Zadejte číslo faktury ručně.', invoicesError: 'Faktury se nepodařilo načíst – číslo faktury zadejte ručně.', manualInvoice: 'Jiná faktura – zadejte číslo:', invoiceDate: 'ze dne', feedLoading: 'Načítám seznam produktů…', feedError: 'Seznam produktů se nepodařilo načíst. Zadejte údaje ručně.', cont: 'Pokračovat na reklamační formulář', validation: 'Vyplňte značku, název produktu a katalogové číslo.', openNew: 'Otevřít formulář v novém okně', change: 'Změnit údaje', tabNew: 'Nová reklamace', tabList: 'Moje reklamace', stepA: '4. Adresa provozovny', aHint: 'Zboží z faktury {inv} bylo dodáno na: {a}. Předvybrali jsme ji – pokud je zboží jinde, vyberte jinou provozovnu.', aHint0: 'Vyberte provozovnu, kde se reklamované zboží nachází – na tuto adresu vám vrátíme vyřízené zboží.', aInv: 'z této faktury', aHq: 'fakturační', aCnt: 'dodávky: {n}×', aOther: 'Jiná adresa', aOtherSub: 'zadám ručně', aAll: 'Zobrazit všechny provozovny ({n})', aLess: 'Zobrazit méně', aName: 'Název provozovny / kontakt', aStreet: 'Ulice a číslo', aZip: 'PSČ', aCity: 'Město', aFoot: 'Na tuto adresu vám vrátíme vyřízené zboží. Ve formuláři ji můžete ještě upravit.', aLoading: 'Zjišťuji adresu dodání z faktury…', aMissing: 'Vyplňte ulici, PSČ a město provozovny.', step4: '5. Pro váš přehled', custDate: 'Datum přijetí reklamace od vašeho zákazníka', typLabel: 'Kdo reklamuje?', typCust: 'Váš zákazník', typStock: 'Vada zjištěná u vás před prodejem (zboží na skladě)', kupa: 'Datum nákupu zákazníkem (podle dokladu)', receiptHint: 'Ve formuláři přiložíte fotografii nebo sken dokladu o koupi od zákazníka (pokladní účtenka nebo faktura, kterou jste mu vystavili). Připravte si ho.', kupaMissing: 'Vyplňte datum nákupu podle dokladu zákazníka.', kupaAfter: 'Datum nákupu nemůže být pozdější než datum přijetí reklamace.', old24: 'Od nákupu uplynulo více než 24 měsíců – reklamace je pravděpodobně po záruční době. Můžete ji odeslat, servis ji však může zamítnout.', stock: 'Sklad – bez lhůty', stockShort: 'Na skladě', bought: 'Koupeno {d}', note: 'Vaše poznámka (např. číslo reklamace zákazníka) – nepovinné', noteShort: 'Poznámka', custHint: 'Od tohoto dne běží zákonná lhůta 30 dnů na vyřízení reklamace zákazníkovi. Po odeslání se reklamace uloží do seznamu Moje reklamace.', custFuture: 'Datum nemůže být v budoucnosti.', custMissing: 'Vyplňte datum přijetí reklamace od zákazníka.', listTitle: 'Moje odeslané reklamace', listNote: 'Seznam je uložený pouze v tomto prohlížeči na tomto počítači. Na jiném zařízení ho neuvidíte – pro přenos použijte Export a Import.', doneHint: 'Sloupec Vyřízeno je vaše vlastní evidence. Když zákazníkovi předáte vyřízenou reklamaci, zaškrtněte ji zde a budete mít přehled, co je ještě otevřené. Společnosti AGS 92 se tím nic neoznamuje.', fOpen: 'Otevřené', fDone: 'Vyřízené', fAll: 'Všechny', cSent: 'Odesláno', cCust: 'Přijato od zákazníka', cDl: 'Termín', cLeft: 'Zbývá', cProd: 'Produkt', cInv: 'Faktura', cDone: 'Vyřízeno zákazníkovi', cDoneShort: 'Vyřízeno', daysLeft: 'zbývá {n}', overdue: 'po termínu {n}', today: 'termín je dnes', doneOn: 'vyřízeno {d}', hu15: '', pending: 'Neověřeno – formulář jste otevřeli v novém okně.', confirmSent: 'Ano, odeslal jsem', del: 'Smazat', delSure: 'Opravdu smazat?', edit: 'Upravit', view: 'Zobrazit', dPicked: 'Zvolené datum: {d}', dEmpty: 'Datum vyberte v kalendáři (ikona vpravo v poli).', detTitle: 'Odeslaná reklamace', detSent: 'Odesláno {d}', detNo: 'Číslo podání', detPrint: 'Vytisknout / uložit jako PDF', detClose: 'Zavřít', detOwn: 'Údaje z vašeho přehledu', detForm: 'Odpovědi ve formuláři', detNone: 'U této reklamace nejsou uložené odpovědi z formuláře (byla odeslána před 30. 9. 2026, v jiném prohlížeči nebo přidána ručně). Zobrazujeme údaje z vašeho přehledu.', detFiles: 'Soubory jsou uložené v systému AGS 92. Pokud se odkaz neotevře, kontaktujte nás a uveďte číslo podání.', detLocal: 'Kopie odpovědí je uložená pouze v tomto prohlížeči.', detPrinted: 'Vytištěno z B2B portálu AGS 92 dne {d}', add: 'Přidat reklamaci odeslanou jinak', save: 'Uložit', cancel: 'Zrušit', sentDate: 'Datum odeslání', 'export': 'Export (CSV)', 'import': 'Import (CSV)', importDone: 'Přidané záznamy: {n}', importErr: 'Soubor se nepodařilo načíst.', empty: 'Zatím tu nemáte žádnou reklamaci. Po odeslání reklamačního formuláře se sem přidá automaticky.', emptyFilter: 'V tomto filtru není žádná reklamace.', saved: 'Reklamace byla odeslána a přidána do seznamu Moje reklamace.', another: 'Nahlásit další reklamaci', showList: 'Zobrazit moje reklamace', reqManual: 'Vyplňte alespoň název produktu a datum přijetí reklamace od zákazníka.', mediaQ: 'Jak doplníte fotografie a video?', mediaMob: 'Vyfotím produkt telefonem (i video) – po odeslání formuláře se zobrazí QR kód', mediaPc: 'Fotografie a video už mám v tomto počítači – nahraji je ve formuláři', mediaPick: 'Vyberte jednu z možností – podle ní se zobrazí formulář.', qrTitle: 'Nyní vyfoťte produkt telefonem', qrHint: 'Naskenujte QR kód fotoaparátem telefonu. Telefon vás provede kroky – nic není třeba psát:', qrSteps: 'FOTO 1 celý produkt · FOTO 2 detail vady · štítek s výrobním číslem · doklad od zákazníka · video (nepovinné)', qrRule: 'Bez fotografií se reklamace do servisu neodešle. Odkaz platí 7 dní.', qrLink: 'Odkaz pro telefon (můžete si ho poslat e-mailem):', qrShow: 'Zobrazit QR kód', qrHide: 'Skrýt QR kód', textGot: 'Údaje jsme přijali. Reklamace odejde do servisu hned, jak doplníte fotky.', doneTitle: 'Reklamace je odeslána do servisu', doneGot: 'Z telefonu jsme přijali:', doneNext: 'Číslo a stav reklamace ze servisu se zobrazí v části Moje reklamace. Potvrzení dostanete e-mailem ze servisu.', f1: 'FOTO 1 – celý produkt', f2: 'FOTO 2 – detail vady', fsn: 'Štítek s výrobním číslem', fdk: 'Doklad o koupi', fv: 'Video', fnone: 'bez videa', pcLink: 'Nemáte telefon po ruce? Nahrajte fotky z tohoto počítače', wText: 'Odesláno – zpracovává se', wMedia: 'Čeká na fotky z telefonu', wVideo: 'Fotky přijaty – odesílá se do servisu', wExpired: 'Nedokončená – chybí fotky, odkaz vypršel. Založte reklamaci znovu.', qrSentNow: 'Fotky přijaty – reklamace je odeslána do servisu.', mobBtn: 'Pokračovat na mobilu', mobTitle: 'Dokončete reklamaci v telefonu', mobHint: 'Naskenujte QR kód fotoaparátem telefonu. Otevře se tentýž formulář s vyplněnými údaji – fotografie a video přidáte přímo z telefonu. Odkaz platí 7 dní.', mobLoading: 'Připravuji QR kód…', mobErr: 'QR kód se nepodařilo připravit. Použijte formulář na tomto počítači.', mobDirect: 'Odkaz pro telefon (můžete si ho poslat i e-mailem):', mobWait: 'Čeká na odeslání z telefonu', mobSaved: 'Reklamace čeká na odeslání z telefonu. Po odeslání se zde zobrazí její stav.', stSent: 'Přijato – čeká na zaevidování v servisu', stManual: 'Přijato – servis zaeviduje ručně', stNo: 'Reklamace č. {n}', stState: 'Stav v servisu', stHandling: 'Způsob vyřízení', stChecked: 'Poslední kontrola stavu', stClosed: 'uzavřená', stTitle: 'Stav reklamace', stNum: 'Číslo reklamace', stDesc: 'Popis problému', stFiles: 'Fotografie a video', stOffline: 'Stav se nepodařilo načíst. Zkusíme to znovu při další návštěvě.', stVideoLink: 'Odkaz na video' }, hu: { step1: '1. Válassza ki a reklamált terméket', srcInv: 'A számláiból', srcCat: 'Az aktuális katalógusból', srcManual: 'Kézi megadás', boughtFilterPh: 'Keresés a vásárolt termékek között (név vagy cikkszám)…', boughtLoading: 'Számlák betöltése…', boughtParsing: 'Számlatételek betöltése… {n}/{m} (kb. {eta} perc van hátra, a lista folyamatosan bővül; legközelebb már azonnal)', first400: 'az első 400 látható – pontosítsa a keresést', more: 'Nem találja a terméket? Keresés a régebbi számlákban is (25–48 hónap)', moreLoading: 'Régebbi számlák betöltése…', moreDone: 'Az elmúlt 48 hónap számlái átnézve.', boughtEmpty: 'Az elmúlt 24 hónapban nincs számlája – válasszon a katalógusból vagy adja meg kézzel.', step2: '2. Válassza ki a terméket', filterPh: 'Keresés név, cikkszám vagy EAN alapján…', productPh: '– válasszon terméket –', brandPh: '– összes márka –', count: '{n} termék', code: 'Cikkszám', ean: 'EAN kód', name: 'A termék pontos neve', brand: 'Márka', notFound: 'Nem találom a terméket – kézzel adom meg', backToList: 'Vissza a listából való választáshoz', step3: '3. Számla', pickProductFirst: 'Először válassza ki a terméket.', searching: 'Az elmúlt {mo} hónap számláinak átnézése… {n}/{m}', found: 'A terméket a következő számlákon találtuk meg – válassza ki a megfelelőt:', none: 'A terméket nem találtuk az elmúlt {mo} hónap számláin. Adja meg a számlaszámot kézzel.', invoicesError: 'A számlákat nem sikerült betölteni – adja meg a számlaszámot kézzel.', manualInvoice: 'Másik számla – adja meg a számot:', invoiceDate: 'kelt', feedLoading: 'Terméklista betöltése…', feedError: 'A terméklistát nem sikerült betölteni. Adja meg az adatokat kézzel.', cont: 'Tovább a reklamációs űrlaphoz', validation: 'Töltse ki a márkát, a termék nevét és a cikkszámot.', openNew: 'Űrlap megnyitása új ablakban', change: 'Adatok módosítása', tabNew: 'Új reklamáció', tabList: 'Reklamációim', stepA: '4. A telephely címe', aHint: 'A(z) {inv} számlán szereplő árut erre a címre szállítottuk: {a}. Ezt előre kiválasztottuk – ha az áru máshol van, válasszon másik telephelyet.', aHint0: 'Válassza ki a telephelyet, ahol a reklamált áru található – erre a címre küldjük vissza a rendezett árut.', aInv: 'erről a számláról', aHq: 'számlázási', aCnt: 'szállítások: {n}×', aOther: 'Másik cím', aOtherSub: 'kézzel adom meg', aAll: 'Az összes telephely megjelenítése ({n})', aLess: 'Kevesebb', aName: 'Telephely neve / kapcsolattartó', aStreet: 'Utca, házszám', aZip: 'Irányítószám', aCity: 'Település', aFoot: 'Erre a címre küldjük vissza a rendezett árut. Az űrlapon még módosíthatja.', aLoading: 'A szállítási cím keresése a számlán…', aMissing: 'Adja meg a telephely utcáját, irányítószámát és települését.', step4: '5. Az Ön nyilvántartásához', custDate: 'A reklamáció bejelentésének dátuma az Ön vásárlójától', typLabel: 'Ki reklamál?', typCust: 'Az Ön vásárlója', typStock: 'Eladás előtt, az Ön raktárában észlelt hiba', kupa: 'A vásárlás dátuma (a bizonylat szerint)', receiptHint: 'Az űrlapon csatolja a vásárló által bemutatott vásárlási bizonylat (nyugta vagy az Ön által kiállított számla) fényképét vagy szkennelt másolatát. Kérjük, készítse elő.', kupaMissing: 'Adja meg a vásárlás dátumát a bizonylat szerint.', kupaAfter: 'A vásárlás dátuma nem lehet későbbi, mint a reklamáció bejelentésének dátuma.', old24: 'A vásárlás óta több mint 24 hónap telt el – ellenőrizze, hogy a termék még jótállás vagy szavatosság alatt áll-e. Elküldheti, de a szerviz elutasíthatja.', stock: 'Raktár – nincs határidő', stockShort: 'Raktáron', bought: 'Vásárolva: {d}', note: 'Megjegyzés (pl. a vásárlói reklamáció száma) – nem kötelező', noteShort: 'Megjegyzés', custHint: 'Ettől a naptól számít a határidő: a javítást vagy cserét lehetőleg 15 napon belül, legfeljebb 30 napon belül kell elvégezni. Elküldés után a reklamáció bekerül a Reklamációim listába.', custFuture: 'A dátum nem lehet jövőbeli.', custMissing: 'Adja meg a reklamáció bejelentésének dátumát.', listTitle: 'Elküldött reklamációim', listNote: 'A lista csak ebben a böngészőben, ezen a számítógépen van tárolva. Más eszközön nem látja – az átvitelhez használja az Exportot és az Importot.', doneHint: 'A Lezárva oszlop az Ön saját nyilvántartása. Miután a rendezett reklamációt átadta a vásárlónak, jelölje be itt, így mindig látja, mi van még nyitva. Az AGS 92 erről nem kap értesítést.', fOpen: 'Nyitott', fDone: 'Lezárt', fAll: 'Összes', cSent: 'Elküldve', cCust: 'Vásárlói bejelentés', cDl: 'Határidő', cLeft: 'Hátralévő idő', cProd: 'Termék', cInv: 'Számla', cDone: 'Vásárlónál lezárva', cDoneShort: 'Lezárva', daysLeft: 'még {n}', overdue: '{k} napja lejárt', today: 'ma jár le', doneOn: 'lezárva: {d}', hu15: 'több mint 15 nap – tájékoztassa a vásárlót', pending: 'Nem ellenőrzött – az űrlapot új ablakban nyitotta meg.', confirmSent: 'Igen, elküldtem', del: 'Törlés', delSure: 'Biztosan törli?', edit: 'Szerkesztés', view: 'Megtekintés', dPicked: 'Kiválasztott dátum: {d}', dEmpty: 'A dátumot a naptárból válassza ki (ikon a mező jobb oldalán). Formátum: éééé. hh. nn.', detTitle: 'Elküldött reklamáció', detSent: 'Elküldve: {d}', detNo: 'Beküldési azonosító', detPrint: 'Nyomtatás / mentés PDF-be', detClose: 'Bezárás', detOwn: 'Adatok az Ön listájából', detForm: 'Az űrlapon megadott válaszok', detNone: 'Ennél a reklamációnál nincsenek elmentve az űrlap válaszai (2026. 09. 30. előtt, másik böngészőben küldték el, vagy kézzel adták hozzá). Az Ön listájában szereplő adatokat mutatjuk.', detFiles: 'A fájlokat az AGS 92 rendszere tárolja. Ha a hivatkozás nem nyílik meg, forduljon hozzánk a beküldési azonosítóval.', detLocal: 'A válaszok másolata csak ebben a böngészőben van tárolva.', detPrinted: 'Nyomtatva az AGS 92 B2B portálról: {d}', add: 'Máshogy elküldött reklamáció hozzáadása', save: 'Mentés', cancel: 'Mégse', sentDate: 'Elküldés dátuma', 'export': 'Export (CSV)', 'import': 'Import (CSV)', importDone: 'Hozzáadott tételek: {n}', importErr: 'A fájlt nem sikerült beolvasni.', empty: 'Még nincs reklamáció a listában. Az űrlap elküldése után automatikusan ide kerül.', emptyFilter: 'Ebben a szűrőben nincs reklamáció.', saved: 'A reklamációt elküldtük, és bekerült a Reklamációim listába.', another: 'Újabb reklamáció bejelentése', showList: 'Reklamációim megtekintése', reqManual: 'Adja meg legalább a termék nevét és a reklamáció bejelentésének dátumát.', mediaQ: 'Hogyan adja hozzá a fényképeket és a videót?', mediaMob: 'Telefonnal fényképezem le a terméket (videót is) – az űrlap elküldése után QR-kód jelenik meg', mediaPc: 'A fényképek és a videó már ezen a számítógépen vannak – az űrlapon töltöm fel', mediaPick: 'Válasszon egy lehetőséget – ennek megfelelően jelenik meg az űrlap.', qrTitle: 'Most fényképezze le a terméket telefonnal', qrHint: 'Olvassa be a QR-kódot a telefon kamerájával. A telefon végigvezeti a lépéseken – nem kell semmit írni:', qrSteps: '1. FOTÓ a teljes termék · 2. FOTÓ a hiba részlete · címke a gyártási számmal · a vásárló bizonylata · videó (nem kötelező)', qrRule: 'Fényképek nélkül a reklamáció nem kerül továbbításra a szerviznek. A link 7 napig érvényes.', qrLink: 'Link a telefonhoz (e-mailben is elküldheti magának):', qrShow: 'QR-kód megjelenítése', qrHide: 'QR-kód elrejtése', textGot: 'Az adatokat megkaptuk. A reklamáció a fotók feltöltése után azonnal a szervizhez kerül.', doneTitle: 'A reklamációt elküldtük a szerviznek', doneGot: 'A telefonról megérkezett:', doneNext: 'A reklamáció számát és állapotát a Reklamációim részben találja. A visszaigazolást a szerviz e-mailben küldi.', f1: '1. FOTÓ – a teljes termék', f2: '2. FOTÓ – a hiba részlete', fsn: 'Címke a gyártási számmal', fdk: 'Vásárlási bizonylat', fv: 'Videó', fnone: 'videó nélkül', pcLink: 'Nincs kéznél a telefon? Töltse fel a fotókat erről a számítógépről', wText: 'Elküldve – feldolgozás alatt', wMedia: 'Fotókra vár a telefonról', wVideo: 'Fotók megérkeztek – küldés a szerviznek', wExpired: 'Befejezetlen – hiányoznak a fotók, a link lejárt. Indítsa újra a reklamációt.', qrSentNow: 'Fotók megérkeztek – a reklamációt elküldtük a szerviznek.', mobBtn: 'Folytatás telefonon', mobTitle: 'Fejezze be a reklamációt a telefonján', mobHint: 'Olvassa be a QR-kódot a telefon kamerájával. Ugyanaz az űrlap nyílik meg a kitöltött adatokkal – a fényképeket és a videót közvetlenül a telefonról töltheti fel. A link 7 napig érvényes.', mobLoading: 'QR-kód előkészítése…', mobErr: 'A QR-kódot nem sikerült előkészíteni. Használja az űrlapot ezen a számítógépen.', mobDirect: 'Link a telefonhoz (e-mailben is elküldheti magának):', mobWait: 'Telefonról történő elküldésre vár', mobSaved: 'A reklamáció telefonról történő elküldésre vár. Elküldés után itt jelenik meg az állapota.', stSent: 'Beérkezett – szervizbe rögzítésre vár', stManual: 'Beérkezett – a szerviz kézzel rögzíti', stNo: 'Reklamáció száma: {n}', stState: 'Állapot a szervizben', stHandling: 'Rendezés módja', stChecked: 'Utolsó állapotellenőrzés', stClosed: 'lezárva', stTitle: 'A reklamáció állapota', stNum: 'A reklamáció száma', stDesc: 'A hiba leírása', stFiles: 'Fényképek és videó', stOffline: 'Az állapotot nem sikerült betölteni. A következő látogatáskor újra megpróbáljuk.', stVideoLink: 'Videó linkje' } }; /* ---------- helpers ---------- */ function market() { var m = location.pathname.match(/^\/(sk|cz|hu)(\/|$)/i); return m ? m[1].toLowerCase() : 'sk'; } function txt(s) { return (s || '').replace(/\s+/g, ' ').trim(); } function esc(s) { return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c]; }); } function norm(s) { return String(s || '').normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase(); } function normCode(s) { return txt(s).toUpperCase().replace(/_VO$/, ''); } function reEsc(s) { return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } function fmt(s, o) { return s.replace(/\{(\w+)\}/g, function (_, k) { return o[k] != null ? o[k] : ''; }); } function lsGet(k) { try { return JSON.parse(localStorage.getItem(k)); } catch (e) { return null; } } function lsSet(k, v) { try { localStorage.setItem(k, JSON.stringify(v)); } catch (e) {} } function lsDel(k) { try { localStorage.removeItem(k); } catch (e) {} } function pageUrl(m, id) { return '/' + m + '/buxus/generate_page.php?page_id=' + id; } function isLoggedIn() { var h = document.querySelector('.header-basic-info h3'); if (h && txt(h.textContent)) { return true; } var links = document.querySelectorAll('a[href]'); for (var i = 0; i < links.length; i++) { if (/logout|odhlas|kijelentkez/i.test(links[i].getAttribute('href') || '')) { return true; } } return false; } function loadScript(src) { return new Promise(function (res, rej) { var s = document.createElement('script'); s.src = src; s.async = true; s.onload = res; s.onerror = function () { rej(new Error('script ' + src)); }; document.head.appendChild(s); }); } /* ---------- 1. presmerovanie po prihlásení ---------- */ var m = market(); /* --- faktúry --- */ var MONTHS = { jan: 0, feb: 1, mar: 2, apr: 3, maj: 4, may: 4, jun: 5, jul: 6, aug: 7, sep: 8, sze: 8, okt: 9, oct: 9, nov: 10, dec: 11 }; function parseDate(s) { var a = s.match(/(\d{4})\s*[.\-\/]\s*(\d{1,2})\s*[.\-\/]\s*(\d{1,2})/); if (a) { return new Date(+a[1], +a[2] - 1, +a[3]); } var b = s.match(/(\d{1,2})\s*[.\-\/]\s*(\d{1,2})\s*[.\-\/]\s*(\d{4})/); if (b) { return new Date(+b[3], +b[2] - 1, +b[1]); } var c = s.match(/(\d{1,2})\s*[.\-\/ ]\s*([A-Za-z\u00C0-\u017F]{3,})\.?\s*[.\-\/ ]?\s*(\d{4})/); /* 25.Sep.2026 (B2B faktúry) */ if (c) { var mo = MONTHS[norm(c[2]).slice(0, 3)]; if (mo != null) { return new Date(+c[3], mo, +c[1]); } } return null; } function fmtDate(d) { if (!d) { return ''; } if (m === 'hu') { return d.getFullYear() + '. ' + ('0' + (d.getMonth() + 1)).slice(-2) + '. ' + ('0' + d.getDate()).slice(-2) + '.'; } return d.getDate() + '. ' + (d.getMonth() + 1) + '. ' + d.getFullYear(); } function loadPdfJs() { if (window.pdfjsLib) { return Promise.resolve(); } var d = window.define; var had = 'define' in window; try { window.define = undefined; } catch (e) {} return loadScript(PDFJS).then(function () { if (had) { window.define = d; } window.pdfjsLib.GlobalWorkerOptions.workerSrc = PDFJS_WORKER; }, function (e) { if (had) { window.define = d; } throw e; }); } /* v k: dodacia adresa z 1. strany faktúry (pravý stĺpec pod „DODACIA ADRESA“, nad „FAKTURAČNÁ ADRESA“) */ var DOD_RE = /DODACIA\s+ADRESA|DODAC[ÍI]\s+ADRESA|SZ[ÁA]LL[ÍI]T[ÁA]SI\s+C[ÍI]M|DELIVERY\s+ADDRESS|ADRES\s+DOSTAWY/i; var DOD_STOP = /FAKTURA[ČC]N[ÁAÍI]\s+ADRESA|SZ[ÁA]ML[ÁA]Z[ÁA]SI\s+C[ÍI]M|BILLING|ODBERATE[ĽL]|ODB[ĚE]RATEL|VEV[ŐO]|IBAN|SWIFT/i; var COUNTRY_RE = /^(slovensko|slovensk[áa] republika|slovakia|česk[áa] republika|ceska republika|česko|czech republic|czechia|magyarorsz[áa]g|hungary|polska|poland|österreich|rak[úu]sko)$/i; function deliveryAddr(raw) { var it = [], h = null, k; for (k = 0; k < raw.length; k++) { var s0 = txt(raw[k].str); if (s0) { it.push({ x: raw[k].transform[4], y: raw[k].transform[5], s: s0 }); } } for (k = 0; k < it.length && !h; k++) { if (DOD_RE.test(it[k].s)) { h = it[k]; } } if (!h) { return null; } var x0 = h.x - 6, rows = []; it.forEach(function (c) { if (c.x < x0 || c.y >= h.y - 1 || c.y < h.y - 120) { return; } var row = null; for (var r = 0; r < rows.length; r++) { if (Math.abs(rows[r].y - c.y) <= 2) { row = rows[r]; break; } } if (!row) { row = { y: c.y, cells: [] }; rows.push(row); } row.cells.push(c); }); rows.sort(function (a, b) { return b.y - a.y; }); var lines = []; for (k = 0; k < rows.length && lines.length < 7; k++) { var line = txt(rows[k].cells.sort(function (a, b) { return a.x - b.x; }).map(function (c) { return c.s; }).join(' ')); if (DOD_STOP.test(line) || DOD_RE.test(line)) { break; } if (line) { lines.push(line); } } if (lines.length < 2) { return null; } var PSC = /^(\d{3}\s?\d{2}|\d{4})(?:\s+(.+))?$/, a = { name: '', street: '', zip: '', city: '', country: '' }, zi = -1; if (COUNTRY_RE.test(lines[lines.length - 1])) { a.country = lines.pop(); } for (k = lines.length - 1; k >= 0 && zi < 0; k--) { var mm = lines[k].match(PSC); if (mm) { zi = k; a.zip = mm[1]; a.city = mm[2] || ''; } } if (zi < 0) { return null; } if (!a.city && lines[zi + 1]) { a.city = lines[zi + 1]; } var before = lines.slice(0, zi); if (before.length >= 2) { a.name = before[0]; a.street = before.slice(1).join(', '); } else if (before.length === 1) { a.street = before[0]; } if (!a.street || !a.city) { return null; } return a; } /* PDF → text + položky (riadok: kód | názov | množstvo | ks/db | ceny) */ var UNIT_RE = /^(ks|db\.?|pcs|szt\.?|kus|bal\.?)$/i; var CODE_RE = /^[A-Z0-9][A-Z0-9\-_.\/]{2,}$/i; function pdfParse(url) { return window.pdfjsLib.getDocument({ url: url, withCredentials: true }).promise.then(function (pdf) { var ps = []; for (var i = 1; i <= pdf.numPages; i++) { ps.push(pdf.getPage(i).then(function (p) { return p.getTextContent().then(function (tc) { tc.__pn = p.pageNumber; return tc; }); }).then(function (tc) { var rows = []; tc.items.forEach(function (it) { if (!txt(it.str)) { return; } var y = it.transform[5], x = it.transform[4], row = null; for (var r = 0; r < rows.length; r++) { if (Math.abs(rows[r].y - y) <= 2) { row = rows[r]; break; } } if (!row) { row = { y: y, cells: [] }; rows.push(row); } row.cells.push({ x: x, s: it.str }); }); rows.sort(function (a, b) { return b.y - a.y; }); var items = [], last = null; rows.forEach(function (row) { var c = row.cells.sort(function (a, b) { return a.x - b.x; }); var ui = -1; for (var k = 1; k < c.length; k++) { if (UNIT_RE.test(txt(c[k].s)) && /^\d+([.,]\d+)?$/.test(txt(c[k - 1].s))) { ui = k; break; } } if (ui >= 2 && c[0].x < 120 && CODE_RE.test(txt(c[0].s))) { last = { code: txt(c[0].s), name: txt(c.slice(1, ui - 1).map(function (q) { return q.s; }).join(' ')), qty: txt(c[ui - 1].s) }; items.push(last); } else if (last && c.length === 1 && c[0].x > 100 && c[0].x < 400 && !/^\d{6,}/.test(txt(c[0].s)) && !/[:]/.test(c[0].s)) { last.name = txt(last.name + ' ' + c[0].s); /* pokračovanie dlhého názvu */ } else { last = null; } }); return { text: tc.items.map(function (it) { return it.str; }).join(' '), items: items, dod: tc.__pn === 1 ? deliveryAddr(tc.items) : null }; })); } return Promise.all(ps).then(function (parts) { var items = []; parts.forEach(function (pt) { items = items.concat(pt.items); }); return { text: parts.map(function (pt) { return pt.text; }).join('\n').toUpperCase(), items: items, dod: (parts[0] && parts[0].dod) || null }; }); }); } /* --- cache položiek faktúr (faktúry sa nemenia → bez expirácie, orezané na 48 mesiacov / 1000 ks) --- */ /* kľúč cache podľa účtu (obchodníci sa prihlasujú za viacerých partnerov v jednom prehliadači) */ function acctKey() { var h = document.querySelector('.header-basic-info h3'), box = document.querySelector('.header-basic-info'); var id = norm((h ? h.textContent : '') + '|' + (((box && box.textContent) || '').match(/[\w.+-]+@[\w-]+(\.[\w-]+)+/) || [''])[0]); var hsh = 5381; for (var i = 0; i < id.length; i++) { hsh = ((hsh << 5) + hsh + id.charCodeAt(i)) >>> 0; } return hsh.toString(36); } var ACCT = acctKey(); var INV_KEY = 'ags_rekl_inv_' + m + '_' + ACCT; lsDel('ags_rekl_inv_' + m); lsDel('ags_rekl_invlist_' + m); /* staré kľúče bez účtu */ function dateKey(d) { return d ? (d.getFullYear() + '-' + ('0' + (d.getMonth() + 1)).slice(-2) + '-' + ('0' + d.getDate()).slice(-2)) : ''; } function invCache() { var c = lsGet(INV_KEY); return (c && c.inv) ? c : { v: 1, inv: {} }; } function invCacheGet(no) { var e = invCache().inv[no]; return e ? { date: e.d, items: e.it.map(function (a) { return { code: a[0], name: a[1], qty: a[2] }; }), hasA: ('a' in e), dod: e.a ? { name: e.a[0], street: e.a[1], zip: e.a[2], city: e.a[3], country: e.a[4] } : null } : null; } function invCachePut(no, date, items, dod) { var c = invCache(); c.inv[no] = { d: dateKey(date), it: items.map(function (it) { return [it.code, it.name, it.qty]; }), t: Date.now(), a: dod ? [dod.name, dod.street, dod.zip, dod.city, dod.country] : 0 }; var cutoff = new Date(); cutoff.setMonth(cutoff.getMonth() - MONTHS_MAX); var ck = dateKey(cutoff); var keys = Object.keys(c.inv).filter(function (k) { if (c.inv[k].d && c.inv[k].d < ck) { delete c.inv[k]; return false; } return true; }); if (keys.length > MAX_INVOICES) { keys.sort(function (a, b) { return (c.inv[a].t || 0) - (c.inv[b].t || 0); }).slice(0, keys.length - MAX_INVOICES).forEach(function (k) { delete c.inv[k]; }); } lsSet(INV_KEY, c); } /* --- zoznam faktúr (24 alebo 48 mesiacov): stránka Faktúry má predvolený filter „od 1.1. aktuálneho roka", preto sa posiela POST s date_from = dnes − N mesiacov; zoznam sa cachuje na 6 h --- */ var INV_LIST_KEY = 'ags_rekl_invlist_' + m + '_' + ACCT, INV_LIST_TTL = 6 * 60 * 60 * 1000, INV_EMPTY_TTL = 2 * 60 * 1000; /* v q */ function ddmmyyyy(d) { return ('0' + d.getDate()).slice(-2) + '.' + ('0' + (d.getMonth() + 1)).slice(-2) + '.' + d.getFullYear(); } function parseInvoiceRows(doc, baseUrl, list, seen) { var links = doc.querySelectorAll('a[href*="invoice_id="]'), added = 0, oldest = null; for (var i = 0; i < links.length; i++) { var tr = links[i].closest('tr'); if (!tr) { continue; } var cells = tr.querySelectorAll('td, th'); var no = cells.length ? txt(cells[0].textContent) : ''; if (!no || seen[no]) { continue; } var d = null; for (var c = 1; c < cells.length && !d; c++) { d = parseDate(txt(cells[c].textContent)); } seen[no] = 1; added++; if (d) { oldest = (!oldest || d < oldest) ? d : oldest; } list.push({ no: no, date: d, pdf: new URL(links[i].getAttribute('href'), baseUrl).toString(), text: null }); } return { added: added, oldest: oldest }; } function loadInvoiceList(force, months) { months = months || MONTHS_BACK; var LK = INV_LIST_KEY + '_' + months; var c = lsGet(LK); if (!force && c && c.ts && (Date.now() - c.ts) < (c.list && c.list.length ? INV_LIST_TTL : INV_EMPTY_TTL) && c.list) { /* v q: prázdny zoznam platí len 2 min */ return Promise.resolve(c.list.map(function (x) { return { no: x[0], date: x[1] ? new Date(x[1] + 'T00:00:00') : null, pdf: x[2], text: null }; })); } var cutoff = new Date(); cutoff.setMonth(cutoff.getMonth() - months); var list = [], seen = {}; return fetch(pageUrl(m, PAGE_ID_FAKTURY), { credentials: 'same-origin' }).then(function (r) { return r.text().then(function (h) { return { url: r.url.split('?')[0], html: h }; }); }).then(function (first) { var doc0 = new DOMParser().parseFromString(first.html, 'text/html'); var inp = doc0.querySelector('input[name="date_from"]'), form = inp ? inp.closest('form') : null; function body() { var fd = new FormData(); if (form) { for (var k = 0; k < form.elements.length; k++) { var e = form.elements[k]; if (!e.name) { continue; } fd.append(e.name, e.name === 'date_from' ? ddmmyyyy(cutoff) : (e.name === 'date_to' ? '' : (e.value || ''))); } } else { fd.append('date_from', ddmmyyyy(cutoff)); } return fd; } function page(n) { var req = form ? fetch(first.url + '?results_per_page=48&page=' + n, { method: 'POST', body: body(), credentials: 'same-origin' }) : fetch(first.url + '?page=' + n, { credentials: 'same-origin' }); return req.then(function (r) { return r.text(); }).then(function (html) { var res = parseInvoiceRows(new DOMParser().parseFromString(html, 'text/html'), first.url, list, seen); var stop = !res.added || list.length >= MAX_INVOICES || (res.oldest && res.oldest < cutoff) || n >= 30; return stop ? list : page(n + 1); }); } return page(1); }).then(function (l) { l = l.filter(function (x) { return !x.date || x.date >= cutoff; }); lsSet(LK, { ts: Date.now(), list: l.map(function (x) { return [x.no, dateKey(x.date), x.pdf]; }) }); return l; }); } /* --- predbežné načítanie položiek do cache na pozadí (PDF generuje server postupne ~3,5 s/ks, paralelizmus nepomáha) --- */ var prefetchRunning = false; function prefetchInvoices(max) { if (prefetchRunning) { return; } prefetchRunning = true; loadInvoiceList().then(function (list) { var queue = list.filter(function (x) { return !invCacheGet(x.no); }).slice(0, max); if (!queue.length) { prefetchRunning = false; return; } return loadPdfJs().then(function () { var idx = 0; function next() { if (idx >= queue.length) { prefetchRunning = false; return; } if (document.visibilityState === 'hidden') { setTimeout(next, 5000); return; } var inv = queue[idx++]; if (invCacheGet(inv.no)) { return next(); } return pdfParse(inv.pdf).then(function (res) { invCachePut(inv.no, inv.date, res.items, res.dod); }, function () {}).then(next); } return next(); }); }).catch(function () { prefetchRunning = false; }); } var qs = new URLSearchParams(location.search); var hs = new URLSearchParams((location.hash || '').replace(/^#/, '')); function qp(k) { return qs.get(k) || hs.get(k) || ''; } /* parametre aj v hashi – prežijú server redirect */ var app = document.getElementById('ags-reklamacia-app'); if (qp('goto') === 'reklamacia') { lsSet(GOTO_KEY, { ts: Date.now(), zdroj: qp('zdroj'), objednavka: qp('objednavka') }); } var pending = lsGet(GOTO_KEY); if (pending && (Date.now() - pending.ts) > GOTO_TTL) { lsDel(GOTO_KEY); pending = null; } if (pending && !app && isLoggedIn()) { var target = pageUrl(m, PAGE_ID_REKLAMACIE) + '&zdroj=' + encodeURIComponent(pending.zdroj) + '&objednavka=' + encodeURIComponent(pending.objednavka); lsSet(GOTO_KEY, { ts: pending.ts, zdroj: pending.zdroj, objednavka: pending.objednavka, redirected: 1 }); if (!pending.redirected) { location.replace(target); return; } } /* ---------- 1a. Faktúry / Objednávky: klzavých 12 mesiacov namiesto „od 1. 1. aktuálneho roka“ + stránkovanie, ktoré nezahodí filter (BUXUS pri ?page=N filter zabúda) ---------- */ var DEFAULT_WINDOW = 12; var autoSubmitting = (function fixListFilter() { var inp = document.querySelector('input[name="date_from"]'); if (!inp || app) { return false; } var form = inp.closest('form'); if (!form || String(form.getAttribute('method') || '').toLowerCase() !== 'post') { return false; } var FLAG = 'ags_filter_' + location.pathname, flag = null; try { flag = sessionStorage.getItem(FLAG); sessionStorage.removeItem(FLAG); } catch (e) {} function send(action, why) { var btn = form.querySelector('[type="submit"][name]'); if (btn && !form.querySelector('input[type="hidden"][name="' + btn.name + '"]')) { var h = document.createElement('input'); h.type = 'hidden'; h.name = btn.name; h.value = btn.value; form.appendChild(h); } try { sessionStorage.setItem(FLAG, why); } catch (e) {} form.setAttribute('action', action); form.submit(); } form.addEventListener('submit', function () { try { sessionStorage.setItem(FLAG, 'user'); } catch (e) {} }); 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 || a.closest('.ags-inv-detail') || e.ctrlKey || e.metaKey) { return; } e.preventDefault(); send(a.href, 'pager'); }); if (!flag && txt(inp.value) === '01.01.' + new Date().getFullYear()) { var d = new Date(); d.setMonth(d.getMonth() - DEFAULT_WINDOW); inp.value = ddmmyyyy(d); send(location.href.split('#')[0], 'auto'); return true; } return false; })(); /* ---------- 1b. stránka Faktúry: rozbalenie položiek + „Reklamovať" + tiché načítanie do cache ---------- */ var invLinks = document.querySelectorAll('a[href*="invoice_id="]'); if (!app && invLinks.length && !autoSubmitting) { enhanceInvoiceList(invLinks); } function enhanceInvoiceList(links) { var L = { sk: { items: 'Položky', hide: 'Skryť', claim: 'Reklamovať', loading: 'Načítavam…', none: 'Položky sa nepodarilo načítať.', qty: 'ks' }, cz: { items: 'Položky', hide: 'Skrýt', claim: 'Reklamovat', loading: 'Načítám…', none: 'Položky se nepodařilo načíst.', qty: 'ks' }, hu: { items: 'Tételek', hide: 'Elrejt', claim: 'Reklamáció', loading: 'Betöltés…', none: 'A tételeket nem sikerült betölteni.', qty: 'db' } }[m]; var st = document.createElement('style'); st.textContent = '.ags-inv-btn{margin-left:8px;font-size:12px;white-space:nowrap}.ags-inv-detail td{background:#f7fbff;padding:6px 10px}' + '.ags-inv-detail table{width:100%;font-size:13px;border-collapse:collapse}.ags-inv-detail th,.ags-inv-detail td{text-align:left;padding:3px 6px;border-bottom:1px solid #e3ecf3;background:none}' + '.ags-inv-detail .ags-q{text-align:right;white-space:nowrap}.ags-inv-detail a.ags-claim{white-space:nowrap}'; document.head.appendChild(st); var rows = []; for (var i = 0; i < links.length; i++) { var tr = links[i].closest('tr'); if (!tr || tr.getAttribute('data-ags')) { continue; } tr.setAttribute('data-ags', '1'); var cells = tr.querySelectorAll('td, th'); var no = cells.length ? txt(cells[0].textContent) : ''; if (!no) { continue; } var d = null; for (var c = 1; c < cells.length && !d; c++) { d = parseDate(txt(cells[c].textContent)); } var pdf = new URL(links[i].getAttribute('href'), location.href).toString(); var btn = document.createElement('a'); btn.href = '#'; btn.className = 'ags-inv-btn'; btn.textContent = L.items; cells[cells.length - 1].appendChild(btn); rows.push({ tr: tr, no: no, date: d, pdf: pdf, btn: btn, detail: null, cols: cells.length }); } function getItems(row) { var cached = invCacheGet(row.no); if (cached) { return Promise.resolve(cached.items); } return loadPdfJs().then(function () { return pdfParse(row.pdf); }).then(function (res) { invCachePut(row.no, row.date, res.items, res.dod); return res.items; }); } function render(row, items) { var h = ''; items.forEach(function (it) { var u = pageUrl(m, PAGE_ID_REKLAMACIE) + '&kod=' + encodeURIComponent(it.code) + '&faktura=' + encodeURIComponent(row.no) + '&zdroj=faktury'; h += ''; }); h += '
' + esc(it.code) + '' + esc(it.name) + '' + esc(it.qty) + ' ' + L.qty + '' + L.claim + '
'; if (!items.length) { h = '' + L.none + ''; } row.detail.firstChild.innerHTML = h; } rows.forEach(function (row) { row.btn.addEventListener('click', function (e) { e.preventDefault(); if (row.detail) { var open = row.detail.style.display !== 'none'; row.detail.style.display = open ? 'none' : ''; row.btn.textContent = open ? L.items : L.hide; return; } row.detail = document.createElement('tr'); row.detail.className = 'ags-inv-detail'; row.detail.innerHTML = '' + L.loading + ''; row.tr.parentNode.insertBefore(row.detail, row.tr.nextSibling); row.btn.textContent = L.hide; getItems(row).then(function (items) { render(row, items); }, function () { row.detail.firstChild.innerHTML = '' + L.none + ''; }); }); }); /* tiché načítanie do cache na pozadí: najprv faktúry viditeľné na stránke, potom celých 24 mesiacov */ setTimeout(function () { var queue = rows.filter(function (r) { return !invCacheGet(r.no); }); var idx = 0; function worker() { if (idx >= queue.length) { prefetchInvoices(MAX_INVOICES); return; } var r = queue[idx++]; return getItems(r).catch(function () {}).then(worker); } loadPdfJs().then(worker).catch(function () {}); }, 1500); } /* Na ostatných stránkach sa zámerne NEprednačítava: server drží PHP session zámok počas generovania PDF (~3,5 s), partnerovi by sa náhodne spomaľovalo prehliadanie B2B. */ /* v k: zoznam prevádzok z Dodacích údajov (krok košíka) – uloží sa pri každej návšteve, použije ho stránka Reklamácie */ var ADR_KEY = 'ags_rekl_adr_' + m + '_' + ACCT; function parseCartAddrs(doc) { var out = [], els = doc.querySelectorAll('input[name="address_selector"]'); for (var i = 0; i < els.length; i++) { var lab = els[i].closest('label') || els[i].parentNode; var s1 = txt(lab ? lab.textContent : ''); if (!s1 || /dropship/i.test(s1)) { continue; } var p = s1.split(',').map(txt); var mm = (p[1] || '').match(/^(\d{3}\s?\d{2}|\d{4})\s+(.+)$/); if (!p[0] || !mm) { continue; } out.push({ name: '', street: p[0], zip: mm[1], city: mm[2], country: p[2] || '' }); } return out; } (function captureCart() { var l = parseCartAddrs(document); if (l.length) { lsSet(ADR_KEY, { ts: Date.now(), list: l }); } })(); if (!app) { return; } /* ---------- 2. widget na stránke Reklamácie ---------- */ var cfg = CFG[m], t = T[m]; var state = { zdroj: qp('zdroj') || (pending && pending.zdroj) || 'menu', objednavka: qp('objednavka') || (pending && pending.objednavka) || '', account: { firma: '', email: '', ico: '', dic: '', ulica: '', psc: '', mesto: '', krajina: cfg.country }, items: [], brands: [], feedError: false, product: null, invoices: null, invoicesError: false, parsed: 0, invoiceChoice: '', invoiceManual: '' }; lsDel(GOTO_KEY); /* --- údaje z účtu --- */ function readHeader() { var box = document.querySelector('.header-basic-info'); if (!box) { return; } var h3 = box.querySelector('h3'); state.account.firma = h3 ? txt(h3.textContent) : ''; var html = box.innerHTML.replace(//gi, '\n').replace(/<\/(p|div|li|h\d|span)>/gi, '\n').replace(/<[^>]+>/g, ''); var em = html.match(/[\w.+-]+@[\w-]+(\.[\w-]+)+/); /* z riadkov, nie z textContent – bez medzery medzi

by sa prilepil ďalší text */ if (em) { state.account.email = em[0]; } var tmp = document.createElement('textarea'); tmp.innerHTML = html; var lines = tmp.value.split('\n').map(txt).filter(Boolean); var addr = []; for (var i = 0; i < lines.length; i++) { var l = lines[i]; if (l === state.account.firma || /@|e-?mail|tel\.?|telef|phone/i.test(l)) { continue; } addr.push(l); } var PSC = m === 'hu' ? '\\d{4}' : '\\d{3}\\s?\\d{2}'; var reLead = new RegExp('^(' + PSC + ')\\s+(.+)$'), reTail = new RegExp('^(.+?),?\\s+(' + PSC + ')$'); var pscLine = -1, j, mm; for (j = 0; j < addr.length && pscLine < 0; j++) { mm = addr[j].match(reLead); if (mm) { state.account.psc = mm[1]; state.account.mesto = mm[2]; pscLine = j; } } for (j = 0; j < addr.length && pscLine < 0; j++) { mm = addr[j].match(reTail); if (mm) { state.account.mesto = mm[1]; state.account.psc = mm[2]; pscLine = j; } } var reOnly = new RegExp('^(' + PSC + ')$'), cityLine = -1; for (j = 0; j < addr.length && pscLine < 0; j++) { mm = addr[j].match(reOnly); if (mm) { state.account.psc = mm[1]; pscLine = j; } } /* PSČ na samostatnom riadku */ if (pscLine >= 0 && !state.account.mesto) { for (j = 0; j < addr.length; j++) { if (j !== pscLine && !/\d/.test(addr[j]) && !/^(slovensko|slovakia|česká republika|ceska republika|czech republic|magyarország|hungary)$/i.test(addr[j])) { state.account.mesto = addr[j]; cityLine = j; break; } } } for (j = 0; j < addr.length; j++) { if (j !== pscLine && j !== cityLine && !state.account.ulica && /\d/.test(addr[j])) { state.account.ulica = addr[j]; } } if (!state.account.ulica && addr.length) { state.account.ulica = addr[0]; } if (/^\d+[a-z]?(\/\d+[a-z]?)?$/i.test(state.account.ulica) && state.account.mesto) { state.account.ulica = state.account.mesto + ' ' + state.account.ulica; } /* obec bez ulíc: „Belá 1003“ */ } /* vlastné identifikátory AGS 92 (pätička stránky) sa nikdy nesmú poslať ako údaje partnera */ var OWN_IDS = null; function ownIds() { if (OWN_IDS) { return OWN_IDS; } OWN_IDS = { '48110591': 1, '53909453': 1, '4820000339': 1 }; /* ags 92, s.r.o. (CZ) + organizačná zložka Senica: IČO, IČ DPH – uvedené na faktúrach */ var els = document.querySelectorAll('.adresa, footer, #footer, .footer'); for (var i = 0; i < els.length; i++) { var mt = (els[i].textContent || '').match(/[A-Z]{0,2}\s?\d[\d\s\-]{5,16}\d/g) || []; mt.forEach(function (x) { var d = x.replace(/[^0-9]/g, ''); if (d.length >= 6) { OWN_IDS[d] = 1; } }); } return OWN_IDS; } function isOwnId(v) { var d = String(v || '').replace(/[^0-9]/g, ''); if (!d) { return true; } var o = ownIds(); if (o[d]) { return true; } for (var k in o) { if (o.hasOwnProperty(k) && k.length >= 8 && (d.indexOf(k) >= 0 || k.indexOf(d) >= 0)) { return true; } } return false; } function firstForeign(re, text) { var mm; re.lastIndex = 0; while ((mm = re.exec(text))) { var v = mm[1].replace(/\s+/g, ''); if (!isOwnId(v)) { return v; } } return ''; } var IDS_KEY = 'ags_rekl_ids_' + m + '_' + ACCT; function grabIds(text) { var ico = firstForeign(/(?:IČO|IČ|Cégjegyzékszám|Reg\. ?č\.)\s*:?\s*([0-9]{6,12})/gi, text); var dic = firstForeign(/(?:DIČ|IČ DPH|Közösségi adószám|Adószám|VAT)\s*:?\s*([A-Z]{0,2}\s?[0-9][0-9\-]{6,14})/gi, text); var changed = false; if (ico && !state.account.ico) { state.account.ico = ico; changed = true; } if (dic && !state.account.dic) { state.account.dic = dic; changed = true; } if (changed) { lsSet(IDS_KEY, { ico: state.account.ico, dic: state.account.dic }); } } /* z textu faktúry iba časť za „Odberateľ / Odběratel / Vevő“ (dodávateľ je AGS 92) */ function grabIdsInvoice(text) { if (!text || (state.account.ico && state.account.dic)) { return; } var i = String(text).search(/ODBERATE[ĽL]|ODBĚRATEL|VEVŐ|VEVO|CUSTOMER|BUYER/i); if (i >= 0) { grabIds(String(text).slice(i)); } } function readIds() { var c = lsGet(IDS_KEY); if (c) { if (c.ico && !isOwnId(c.ico)) { state.account.ico = c.ico; } if (c.dic && !isOwnId(c.dic)) { state.account.dic = c.dic; } } grabIds(document.body.textContent || ''); if (state.account.ico && state.account.dic) { return Promise.resolve(); } return fetch(pageUrl(m, PAGE_ID_UCET), { credentials: 'same-origin' }).then(function (r) { return r.text(); }).then(function (html) { var doc = new DOMParser().parseFromString(html, 'text/html'); grabIds(doc.body ? doc.body.textContent : ''); }).catch(function () {}); } /* --- XML feed --- */ var IMG_BASE = 'https://product-images.ags92.com/'; /* položka = [značka, názov, kód, EAN, hlavný obrázok (bez IMG_BASE), galéria] galéria: "a.jpg|b.jpg" = súbory v priečinku {kód}/ ; "!cesta1;cesta2" = plné cesty bez IMG_BASE */ function packImages(code, image, images) { var main = image.indexOf(IMG_BASE) === 0 ? image.slice(IMG_BASE.length) : image; var list = images.split(';').map(txt).filter(Boolean); var folder = IMG_BASE + code + '/'; var inFolder = list.length && list.every(function (u) { return u.indexOf(folder) === 0 && u.indexOf('/', folder.length) < 0 && u.indexOf('|') < 0; }); var gal = inFolder ? list.map(function (u) { return u.slice(folder.length); }).join('|') : (list.length ? '!' + list.map(function (u) { return u.indexOf(IMG_BASE) === 0 ? u.slice(IMG_BASE.length) : u; }).join(';') : ''); return [main, gal]; } function imagesOf(it) { var main = it[4] ? (/^https?:/.test(it[4]) ? it[4] : IMG_BASE + it[4]) : ''; var gal = it[5] || '', list = []; if (gal.charAt(0) === '!') { list = gal.slice(1).split(';').map(function (p) { return /^https?:/.test(p) ? p : IMG_BASE + p; }); } else if (gal) { list = gal.split('|').map(function (f) { return IMG_BASE + it[2] + '/' + f; }); } return { main: main, list: list }; } function loadFeed() { var key = 'ags_rekl_feed2_' + m; lsDel('ags_rekl_feed_' + m); var c = lsGet(key); if (c && c.ts && (Date.now() - c.ts) < FEED_TTL && c.items && c.items.length) { return Promise.resolve(c.items); } return fetch(cfg.feed).then(function (r) { if (!r.ok) { throw new Error(r.status); } return r.text(); }).then(function (xml) { var doc = new DOMParser().parseFromString(xml, 'text/xml'); var cards = doc.getElementsByTagName('STORECARD'); var items = []; function ch(el, tag) { var n = el.getElementsByTagName(tag)[0]; return n ? txt(n.textContent) : ''; } for (var i = 0; i < cards.length; i++) { var el = cards[i]; var code = ch(el, cfg.codeTag); if (!code) { continue; } var im = packImages(code, ch(el, 'IMAGE'), ch(el, 'IMAGES')); items.push([ch(el, cfg.brandTag) || '–', ch(el, 'NAME'), code, ch(el, 'EAN'), im[0], im[1]]); } lsSet(key, { ts: Date.now(), items: items }); return items; }); } /* --- faktúry --- */ function parseInvoices(list) { /* 1) všetko, čo už je v cache, naraz (okamžite); 2) zvyšok postupne z PDF, od najnovších */ var queue = []; (list || state.invoices).forEach(function (inv) { var cached = invCacheGet(inv.no); if (cached) { inv.text = ''; inv.items = cached.items; inv.hasA = cached.hasA; inv.dod = cached.dod; state.parsed++; } else { queue.push(inv); } }); rebuildBought(); renderBought(); applyPreselect(); renderInvoices(); if (!queue.length) { var lst = list || state.invoices || []; if ((!state.account.ico || !state.account.dic) && lst.length && lst[0].pdf) { /* IČO/DIČ partnera z najnovšej faktúry (1 súbor) */ return loadPdfJs().then(function () { return pdfParse(lst[0].pdf); }).then(function (res) { grabIdsInvoice(res.text); }, function () {}); } return Promise.resolve(); } var idx = 0; function worker() { if (idx >= queue.length) { return Promise.resolve(); } var inv = queue[idx++]; return pdfParse(inv.pdf).then(function (res) { inv.text = res.text; inv.items = res.items; inv.dod = res.dod; inv.hasA = true; invCachePut(inv.no, inv.date, res.items, res.dod); grabIdsInvoice(res.text); }, function () { inv.text = ''; inv.items = []; }).then(function () { state.parsed++; rebuildBought(); renderBought(); applyPreselect(); renderInvoices(); return worker(); }); } return loadPdfJs().then(function () { return Promise.all([worker(), worker()]); }); } /* nakúpené produkty = položky faktúr zlúčené podľa kódu, zoradené od najnovšej faktúry */ function rebuildBought() { var map = {}; (state.invoices || []).forEach(function (inv) { (inv.items || []).forEach(function (it) { var k = normCode(it.code); var b = map[k] || (map[k] = { code: it.code, name: it.name, invoices: [], last: null }); if (it.name.length > b.name.length) { b.name = it.name; } if (!b.invoices.some(function (x) { return x.no === inv.no; })) { b.invoices.push({ no: inv.no, date: inv.date, qty: it.qty }); } if (inv.date && (!b.last || inv.date > b.last)) { b.last = inv.date; } }); }); state.bought = Object.keys(map).map(function (k) { return map[k]; }).sort(function (a, b) { return (b.last ? b.last.getTime() : 0) - (a.last ? a.last.getTime() : 0); }); state.bought.forEach(function (b) { b.invoices.sort(function (x, y) { return ((y.date && y.date.getTime()) || 0) - ((x.date && x.date.getTime()) || 0); }); }); } function invoiceMatches(code, ean) { var out = []; if (!state.invoices) { return out; } var nc = normCode(code); var rc = code ? new RegExp('(^|[^A-Z0-9])' + reEsc(nc) + '(?![A-Z0-9])') : null; var re = ean && /^\d{8,14}$/.test(ean) ? new RegExp('(^|[^0-9])' + ean + '(?![0-9])') : null; for (var i = 0; i < state.invoices.length; i++) { var inv = state.invoices[i]; var byItem = nc && (inv.items || []).some(function (it) { return normCode(it.code) === nc; }); var byText = inv.text && ((rc && rc.test(inv.text)) || (re && re.test(inv.text))); /* faktúry z cache nemajú text, len položky */ if (byItem || byText) { out.push(inv); } } return out; } function feedByCode(code) { var nc = normCode(code); for (var i = 0; i < state.items.length; i++) { if (normCode(state.items[i][2]) === nc) { return state.items[i]; } } return null; } function guessBrand(name) { var n = norm(name).replace(/^\d+x\s+/, ''); var best = ''; state.brands.forEach(function (b) { var nb = norm(b); if (n.indexOf(nb) === 0 && nb.length > best.length) { best = b; } }); if (best) { return best; } var w = name.replace(/^\d+x\s+/, '').split(' ')[0]; return w.replace(/[^A-Za-z0-9&\u00C0-\u017F]/g, ''); } /* --- UI --- */ var css = '#ags-reklamacia-app{max-width:820px;font-size:15px;line-height:1.5}' + '#ags-reklamacia-app .ags-step{border:1px solid #e3e3e3;border-radius:6px;padding:14px 16px;margin:0 0 14px}' + '#ags-reklamacia-app h3{margin:0 0 10px;font-size:17px}' + '#ags-reklamacia-app label{display:block;font-weight:600;margin:8px 0 3px}' + '#ags-reklamacia-app select,#ags-reklamacia-app input[type=text]{width:100%;box-sizing:border-box;padding:7px 9px;border:1px solid #bbb;border-radius:4px;font-size:15px;background:#fff}' + '#ags-reklamacia-app select[size]{height:auto}' + '#ags-reklamacia-app .ags-muted{color:#666;font-size:13px}' + '#ags-reklamacia-app .ags-link{background:none;border:0;padding:0;color:#0070d7;text-decoration:underline;cursor:pointer;font-size:14px}' + '#ags-reklamacia-app .ags-btn{display:inline-block;background:#007aff;color:#fff;border:0;border-radius:4px;padding:10px 18px;font-size:16px;cursor:pointer}' + '#ags-reklamacia-app .ags-btn[disabled]{opacity:.5;cursor:default}' + '#ags-reklamacia-app .ags-err{color:#b00020;margin:8px 0}' + '#ags-reklamacia-app .ags-radio{display:block;font-weight:400;margin:4px 0}' + '#ags-reklamacia-app .ags-radio input{margin-right:6px}' + '#ags-reklamacia-app .ags-tabs{display:flex;gap:6px;flex-wrap:wrap;margin:0 0 10px}' + '#ags-reklamacia-app .ags-tab{border:1px solid #bbb;background:#f7f7f7;border-radius:4px;padding:6px 12px;cursor:pointer;font-size:14px}' + '#ags-reklamacia-app .ags-tab.on{background:#007aff;border-color:#007aff;color:#fff}' + '#ags-reklamacia-app .ags-kv{display:flex;gap:16px;flex-wrap:wrap;margin-top:8px;align-items:flex-end}' + '#ags-reklamacia-app .ags-kv div{flex:1 1 200px}' + '#ags-reklamacia-app .ags-kv input[readonly]{background:#f4f4f4}' + '#ags-reklamacia-app .ags-gallery{display:flex;gap:10px;align-items:flex-start;flex-wrap:wrap;margin-top:12px}' + '#ags-reklamacia-app .ags-gallery a{display:block;border:1px solid #e3e3e3;border-radius:4px;background:#fff;padding:3px;line-height:0}' + '#ags-reklamacia-app .ags-gallery .ags-main img{width:160px;height:160px;object-fit:contain}' + '#ags-reklamacia-app .ags-gallery .ags-thumbs{display:flex;gap:6px;flex-wrap:wrap;max-width:560px}' + '#ags-reklamacia-app .ags-gallery .ags-thumbs img{width:56px;height:56px;object-fit:contain}' + '#ags-reklamacia-form{margin-top:16px}' + '#ags-reklamacia-app .ags-ar{display:flex;gap:8px;align-items:flex-start;font-weight:400;margin:6px 0;padding:8px 10px;border:1px solid #e3e3e3;border-radius:6px;cursor:pointer}' + '#ags-reklamacia-app .ags-ar.on{border-color:#007aff;background:#f2f8ff}#ags-reklamacia-app .ags-ar input{margin-top:4px}#ags-reklamacia-app .ags-ar b{display:block}' + '#ags-reklamacia-app .ags-apill{display:inline-block;font-size:11px;font-weight:700;padding:1px 7px;border-radius:9px;margin-left:6px;vertical-align:1px;background:#e3f4ea;color:#1f7a45}' + '#ags-reklamacia-app .ags-apill.hq{background:#e8edf3;color:#44546a}' + '#ags-reklamacia-app input[type=date]{box-sizing:border-box;padding:6px 9px;border:1px solid #bbb;border-radius:4px;font-size:15px;background:#fff;width:100%}' + '#ags-reklamacia-app .ags-mtabs{display:flex;gap:0;margin:0 0 14px;border-bottom:2px solid #007aff}' + '#ags-reklamacia-app .ags-mtab{border:1px solid #bbb;border-bottom:0;background:#f7f7f7;border-radius:6px 6px 0 0;padding:8px 16px;margin-right:4px;cursor:pointer;font-size:15px;font-weight:600}' + '#ags-reklamacia-app .ags-mtab.on{background:#007aff;border-color:#007aff;color:#fff}' + '#ags-reklamacia-app .ags-badge{display:inline-block;min-width:18px;padding:0 6px;margin-left:6px;border-radius:9px;background:#e3e3e3;color:#333;font-size:12px;line-height:18px;text-align:center}' + '#ags-reklamacia-app .ags-badge.hot{background:#d9534f;color:#fff}' + '#ags-reklamacia-app .ags-badge.none{display:none}' + '#ags-reklamacia-app .ags-note{background:#fff8e1;border:1px solid #f3d27a;border-radius:4px;padding:6px 10px;font-size:13px}' + '#ags-reklamacia-app .ags-tblwrap{overflow-x:auto;margin-top:6px}' + '#ags-reklamacia-app .ags-tbl{border-collapse:collapse;width:100%;font-size:14px}' + '#ags-reklamacia-app .ags-tbl th,#ags-reklamacia-app .ags-tbl td{border-bottom:1px solid #e3e3e3;padding:6px 8px;text-align:left;vertical-align:top}' + '#ags-reklamacia-app .ags-tbl th{background:#f4f6f8;font-size:13px;white-space:nowrap}' + '#ags-reklamacia-app .ags-tbl td:nth-child(-n+2){white-space:nowrap}' + '#ags-reklamacia-app .ags-tbl td.ags-prod{min-width:220px}' + '#ags-reklamacia-app .ags-small{font-size:12px}' + '#ags-reklamacia-app .ags-tbl td:last-child,#ags-reklamacia-app .ags-tbl th:last-child{text-align:center}' + '#ags-reklamacia-app .ags-chk input{width:18px;height:18px}' + '#ags-reklamacia-app .ags-r-done td{color:#888}' + '#ags-reklamacia-app .ags-pill{display:inline-block;padding:2px 8px;border-radius:10px;font-size:13px;white-space:nowrap}' + '#ags-reklamacia-app .ags-p-ok{background:#e3f4ea;color:#1f7a45}' + '#ags-reklamacia-app .ags-p-warn{background:#fff1dc;color:#9a5a00}' + '#ags-reklamacia-app .ags-p-late{background:#fde2e1;color:#b00020;font-weight:600}' + '#ags-reklamacia-app .ags-p-done{background:#eee;color:#666}' + '#ags-reklamacia-app .ags-p-stock{background:#e8edf3;color:#44546a}' + '#ags-reklamacia-app .ags-typ{display:flex;flex-wrap:wrap;gap:6px 18px;margin:0 0 10px}#ags-reklamacia-app .ags-typ-l{font-weight:700;width:100%}#ags-reklamacia-app .ags-typ label{font-weight:400;margin:0}' + '#ags-reklamacia-app .ags-receipt{margin-top:8px;padding:8px 10px;background:#eef5fc;border-left:3px solid #0077c8;font-size:13px}' + '#ags-reklamacia-app .ags-warn24{margin-top:8px;padding:8px 10px;background:#fff1dc;border-left:3px solid #e08a00;font-size:13px}' + '#ags-reklamacia-app .ags-p-warn .ags-muted,#ags-reklamacia-app .ags-p-late .ags-muted{white-space:normal}' + '#ags-reklamacia-app .ags-chk{font-weight:400;margin:0;white-space:nowrap}' + '#ags-reklamacia-app .ags-act{margin-top:4px;white-space:nowrap}' + '#ags-reklamacia-app .ags-red{color:#b00020}' + '#ags-reklamacia-app .ags-pend{margin-top:4px;font-size:13px;color:#9a5a00}' + '#ags-reklamacia-app .ags-srv{margin-top:4px;font-size:13px}#ags-reklamacia-app .ags-srv .ags-pill{white-space:normal}' + '#ags-reklamacia-app .ags-p-srv{background:#e6effa;color:#0a4f96}#ags-reklamacia-app .ags-p-mob{background:#fff1dc;color:#9a5a00}#ags-reklamacia-app .ags-p-exp{background:#fde7e5;color:#9b1c14}' + '#ags-reklamacia-app .ags-media{border:1px solid #cfd8e3;border-radius:6px;padding:10px 14px;margin:0 0 12px;background:#f7fafd}#ags-reklamacia-app .ags-media b{display:block;margin-bottom:6px}#ags-reklamacia-app .ags-media label{display:block;margin:4px 0;cursor:pointer}' + '#ags-reklamacia-app .ags-qr-steps{margin:6px 0;font-weight:600}#ags-reklamacia-app .ags-qr-row{margin:8px 0 0}' + '#ags-reklamacia-app .ags-done{border:2px solid #1f7a45;background:#eef8f1;border-radius:8px;padding:20px 24px;margin:0 0 14px}#ags-reklamacia-app .ags-done h3{margin:0 0 6px;font-size:22px;color:#1f7a45}' + '#ags-reklamacia-app .ags-done .ags-done-p{font-weight:600;margin:0 0 10px}#ags-reklamacia-app .ags-done ul{list-style:none;padding:0;margin:0 0 12px;display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:4px 16px}' + '#ags-reklamacia-app .ags-done li{padding:4px 0}#ags-reklamacia-app .ags-done li b{color:#1f7a45;margin-right:6px}#ags-reklamacia-app .ags-done .ags-btn{margin-right:8px}' + '#ags-reklamacia-app .ags-mob{display:flex;gap:16px;align-items:flex-start;flex-wrap:wrap;border:1px solid #cfd8e3;border-radius:6px;padding:12px 16px;margin:0 0 14px;background:#f7fafd}' + '#ags-reklamacia-app .ags-mob-qr{background:#fff;padding:6px;border:1px solid #e3e8ef;line-height:0}#ags-reklamacia-app .ags-mob-qr svg{width:196px;height:196px}' + '#ags-reklamacia-app .ags-mob-t{flex:1;min-width:220px}#ags-reklamacia-app .ags-mob-t h4{margin:0 0 6px}#ags-reklamacia-app .ags-mob-u{word-break:break-all;font-size:12px}' + '#ags-reklamacia-app .ags-btn-o{background:#fff;color:#0077c8;border:1px solid #0077c8}' + '#ags-reklamacia-app .ags-thumbs{display:flex;flex-wrap:wrap;gap:8px}#ags-reklamacia-app .ags-thumbs a{display:block}#ags-reklamacia-app .ags-thumbs img{width:96px;height:96px;object-fit:cover;border:1px solid #ddd;border-radius:4px}' + '#ags-reklamacia-app .ags-tools{margin:12px 0 0}' + '#ags-reklamacia-app .ags-myform{border:1px dashed #bbb;border-radius:6px;padding:10px 14px;margin-top:12px;background:#fafafa}' + '#ags-reklamacia-app .ags-btn-s{padding:7px 14px;font-size:15px}' + '#ags-reklamacia-app .ags-ok{background:#e3f4ea;border:1px solid #9fd3b2;border-radius:4px;padding:10px 12px;margin:0 0 12px}' + '#ags-reklamacia-app .ags-b{font-weight:600}' + '#ags-reklamacia-app .ags-dread{font-size:13px;color:#777;margin-top:3px;min-height:18px}' + '#ags-reklamacia-app .ags-dread.on{color:#1a6b3a;font-weight:600}' + '#ags-reklamacia-app .ags-det{border:1px solid #cfd8e3;border-radius:6px;padding:12px 16px;margin-top:14px;background:#fff}' + '#ags-reklamacia-app .ags-det-h{display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;align-items:flex-start}' + '#ags-reklamacia-app .ags-det h3{margin:0 0 2px}' + '#ags-reklamacia-app .ags-det h4{margin:14px 0 6px;font-size:15px}' + '#ags-reklamacia-app .ags-dtbl{width:100%;border-collapse:collapse;font-size:14px}' + '#ags-reklamacia-app .ags-dtbl th{width:38%;text-align:left;vertical-align:top;font-weight:600;padding:5px 10px 5px 0;border-bottom:1px solid #eee}' + '#ags-reklamacia-app .ags-dtbl td{vertical-align:top;padding:5px 0;border-bottom:1px solid #eee;word-break:break-word}' + '#ags-reklamacia-app .ags-printonly{display:none}' + '@media print{body.ags-printing *{visibility:hidden!important}body.ags-printing #ags-det-print,body.ags-printing #ags-det-print *{visibility:visible!important}' + 'body.ags-printing #ags-det-print{position:absolute;left:0;top:0;width:100%;border:0;padding:0}body.ags-printing .ags-det-btn,body.ags-printing .ags-noprint{display:none!important}body.ags-printing .ags-printonly{display:block!important}}'; var st = document.createElement('style'); st.textContent = css; document.head.appendChild(st); app.innerHTML = '

' + '
' + '

' + esc(t.step1) + '

' + '
' + '
' + '
' + '' + '
' + '' + '

' + '' + '' + '
' + '

' + esc(t.step3) + '

' + '
' + '

' + esc(t.stepA) + '

' + '' + '' + '
' + esc(t.aFoot) + '
' + '

' + esc(t.step4) + '

' + '
' + esc(t.typLabel) + '
' + '
' + '
' + '
' + esc(t.custHint) + '
' + '
' + esc(t.receiptHint) + '
' + '
' + '' + '

' + '' + '
'; var $ = function (id) { return document.getElementById(id); }; var elBrand = $('ags-brand'), elFilter = $('ags-filter'), elProduct = $('ags-product'), elCount = $('ags-count'); var elBought = $('ags-bought'), elBoughtFilter = $('ags-bought-filter'); state.source = 'bought'; state.bought = []; state.pickedBought = null; state.months = MONTHS_BACK; state.preKod = qp('kod'); state.preFak = qp('faktura'); state.preDone = false; function setSource(src) { state.source = src; state.product = null; state.pickedBought = null; state.invoiceChoice = ''; ['bought', 'catalog', 'manual'].forEach(function (s) { $('ags-src-' + s).style.display = s === src ? '' : 'none'; }); var tabs = app.querySelectorAll('#ags-s1 .ags-tab'); for (var i = 0; i < tabs.length; i++) { tabs[i].className = 'ags-tab' + (tabs[i].getAttribute('data-src') === src ? ' on' : ''); } showPicked(null); renderInvoices(); } function showPicked(p, it) { var box = $('ags-picked'); if (!p) { box.style.display = 'none'; renderGallery(null, null); return; } box.style.display = ''; $('ags-brand-ro').value = p.brand; $('ags-code-ro').value = p.code; $('ags-ean-ro').value = p.ean; renderGallery(it, p.code); } function currentProduct() { if (state.source === 'manual') { return { brand: txt($('ags-m-brand').value), name: txt($('ags-m-name').value), code: normCode($('ags-m-code').value), ean: txt($('ags-m-ean').value) }; } return state.product; } function countText(n) { if (m === 'hu') { return n + ' termék'; } var w = m === 'cz' ? ['produkt', 'produkty', 'produktů'] : ['produkt', 'produkty', 'produktov']; return n + ' ' + (n === 1 ? w[0] : (n >= 2 && n <= 4 ? w[1] : w[2])); } function renderGallery(it, code) { var g = $('ags-gallery'); var im = it ? imagesOf(it) : { main: code ? IMG_BASE + 'images/' + code + '.jpg' : '', list: [] }; /* aj ukončený produkt máva hlavnú fotku */ var all = im.list.filter(function (u) { return u !== im.main; }); var thumbs = all.slice(0, 12); var h = ''; if (im.main) { h += ''; } if (thumbs.length) { h += '
' + thumbs.map(function (u) { return ''; }).join('') + (all.length > 12 ? '+' + (all.length - 12) + '' : '') + '
'; } g.innerHTML = h; } /* --- tolerantné vyhľadávanie: poradie slov, diakritika, veľkosť písmen, spojené/rozdelené slová a preklepy nevadia --- */ function toks(str) { return norm(str).replace(/[^a-z0-9]+/g, ' ').trim().split(' ').filter(Boolean); } function wordsOf(str) { /* slová + spojené susedné dvojice (PETITE&MARS → petite, mars, petitemars) */ var w = toks(str), out = w.slice(); for (var i = 0; i + 1 < w.length; i++) { out.push(w[i] + w[i + 1]); } return out; } function lev(a, b, max) { /* Damerau-Levenshtein (prehodené písmená = 1 chyba), s predčasným ukončením */ if (Math.abs(a.length - b.length) > max) { return max + 1; } var pp = null, prev = [], cur, i, j; for (j = 0; j <= b.length; j++) { prev[j] = j; } for (i = 1; i <= a.length; i++) { cur = [i]; var rowMin = i; for (j = 1; j <= b.length; j++) { var cost = a.charCodeAt(i - 1) === b.charCodeAt(j - 1) ? 0 : 1; cur[j] = Math.min(prev[j] + 1, cur[j - 1] + 1, prev[j - 1] + cost); if (pp && i > 1 && j > 1 && a.charCodeAt(i - 1) === b.charCodeAt(j - 2) && a.charCodeAt(i - 2) === b.charCodeAt(j - 1)) { cur[j] = Math.min(cur[j], pp[j - 2] + 1); } if (cur[j] < rowMin) { rowMin = cur[j]; } } if (rowMin > max) { return max + 1; } pp = prev; prev = cur; } return prev[b.length]; } function tokScore(q, words) { var best = 0, tol = q.length >= 8 ? 2 : (q.length >= 4 ? 1 : 0); for (var i = 0; i < words.length; i++) { var w = words[i]; if (w === q) { return 4; } if (w.indexOf(q) === 0) { best = Math.max(best, 3); continue; } if (q.length >= 3 && w.indexOf(q) > 0) { best = Math.max(best, 2); continue; } if (tol && best < 1.5 && (w.charCodeAt(0) === q.charCodeAt(0) || w.charCodeAt(1) === q.charCodeAt(1))) { /* preklep býva zriedka v prvých 2 písmenách */ if (lev(q, w, tol) <= tol || (w.length > q.length && lev(q, w.slice(0, q.length), tol) <= tol)) { best = 1.5; } } } return best; } function fuzzyScore(qt, words) { /* 0 = nevyhovuje; každé slovo dopytu musí niekde sedieť */ var sum = 0; for (var i = 0; i < qt.length; i++) { var sc = tokScore(qt[i], words); if (!sc) { return 0; } sum += sc; } return sum; } function searchList(list, query, wordsFn, keep) { var qt = toks(query), res = []; for (var i = 0; i < list.length; i++) { if (keep && !keep(list[i])) { continue; } if (!qt.length) { res.push({ i: i, s: 0 }); continue; } var sc = fuzzyScore(qt, wordsFn(list[i], i)); if (sc) { res.push({ i: i, s: sc }); } } if (qt.length) { res.sort(function (a, b) { return (b.s - a.s) || (a.i - b.i); }); } return res; } /* --- zdroj A: nakúpené produkty z faktúr --- */ function renderBought() { var stEl = $('ags-bought-status'); var total = state.invoices ? state.invoices.length : 0; if (state.invoicesError) { stEl.textContent = t.invoicesError; } else if (!state.invoices) { stEl.textContent = t.boughtLoading; } else if (!total) { stEl.textContent = t.boughtEmpty; } else if (state.parsed < total) { var left = total - state.parsed; stEl.textContent = fmt(t.boughtParsing, { n: state.parsed, m: total, eta: Math.max(1, Math.ceil(left * 3.5 / 60)) }); } else { stEl.textContent = ''; } $('ags-more').style.display = (state.invoices && !state.invoicesError && state.months < MONTHS_MAX) ? '' : 'none'; var sel = state.pickedBought ? normCode(state.pickedBought.code) : ''; var hits = searchList(state.bought, elBoughtFilter.value, function (b) { return b.w || (b.w = wordsOf(b.name + ' ' + b.code)); }); var opts = [], n = hits.length; for (var h = 0; h < hits.length && h < 400; h++) { var i = hits[h].i, b = state.bought[i], inv = b.invoices[0]; opts.push(''); } elBought.innerHTML = opts.join(''); $('ags-bought-count').textContent = state.bought.length ? countText(n) + (n > 400 ? ' (' + t.first400 + ')' : '') : ''; } function onBoughtPick() { var b = state.bought[+elBought.value]; if (!b) { return; } state.pickedBought = b; var it = feedByCode(b.code); state.product = { brand: it ? it[0] : guessBrand(b.name), name: it ? it[1] : b.name, code: b.code, ean: it ? it[3] : '' }; if (it && it[1].length < b.name.length) { state.product.name = b.name; } elBoughtFilter.value = b.name; state.invoiceChoice = b.invoices[0] ? b.invoices[0].no : ''; showPicked(state.product, it); renderInvoices(); } /* --- zdroj B: katalóg --- */ function renderProducts() { var brand = elBrand.value; state.itemWords = state.itemWords || []; var hits = searchList(state.items, elFilter.value, function (it, i) { return state.itemWords[i] || (state.itemWords[i] = wordsOf(it[0] + ' ' + it[1] + ' ' + it[2] + ' ' + it[3])); }, brand ? function (it) { return it[0] === brand; } : null); var opts = [], n = hits.length; for (var h = 0; h < hits.length && h < 400; h++) { var it = state.items[hits[h].i]; opts.push(''); } elProduct.innerHTML = opts.join(''); elCount.textContent = countText(n) + (n > 400 ? ' (' + t.first400 + ')' : ''); elProduct.disabled = !opts.length; state.product = null; state.invoiceChoice = ''; showPicked(null); renderInvoices(); } function onProductPick() { var it = state.items[+elProduct.value]; if (!it) { state.product = null; showPicked(null); return; } state.product = { brand: it[0], name: it[1], code: it[2], ean: it[3] }; elFilter.value = it[1]; /* celý názov do poľa (bez spustenia filtra) */ state.invoiceChoice = ''; showPicked(state.product, it); renderInvoices(); } /* predvýber z odkazu „Reklamovať" pri položke faktúry (?kod=…&faktura=…) */ function applyPreselect() { if (!state.preKod || state.preDone) { return; } for (var i = 0; i < state.bought.length; i++) { if (normCode(state.bought[i].code) === normCode(state.preKod)) { state.preDone = true; renderBought(); elBought.value = String(i); onBoughtPick(); if (state.preFak) { state.invoiceChoice = state.preFak; renderInvoices(); } return; } } } /* --- faktúry k vybranému produktu --- */ function renderInvoices() { var box = $('ags-inv'); var p = currentProduct(); if (!p || (!p.code && !p.ean)) { box.innerHTML = '
' + esc(t.pickProductFirst) + '
'; return; } if (state.invoicesError) { box.innerHTML = '
' + esc(t.invoicesError) + '
'; return; } var total = state.invoices ? state.invoices.length : 0; var done = state.invoices && state.parsed >= total; var hits = invoiceMatches(p.code, p.ean); var h = ''; if (!done) { h += '
' + esc(fmt(t.searching, { n: state.parsed, m: total, mo: state.months })) + '
'; } if (hits.length) { h += '
' + esc(t.found) + '
'; for (var i = 0; i < hits.length; i++) { var chk = state.invoiceChoice === hits[i].no ? ' checked' : ''; h += ''; } } else if (state.moreLoading) { h += '
' + esc(t.moreLoading) + '
'; } else if (done) { h += '
' + esc(fmt(t.none, { mo: state.months })) + '
'; if (state.months < MONTHS_MAX) { h += '

'; } } box.innerHTML = h; var mb = $('ags-more2'); if (mb) { mb.addEventListener('click', loadMore); } var rs = box.querySelectorAll('input[name=ags-inv-r]'); for (var r = 0; r < rs.length; r++) { rs[r].addEventListener('change', function (e) { state.invoiceChoice = e.target.value; renderAddr(); }); } if (hits.length && !state.invoiceChoice) { state.invoiceChoice = hits[0].no; rs[0].checked = true; } renderAddr(); } /* ---------- v k: adresa prevádzky ---------- */ state.addr = { sel: '', forInv: null, manual: false, all: false, cart: null, cartTried: false }; var CART_PATHS = { sk: '/sk/dodacie-udaje', cz: '/cz/dodacie-udaje' }; /* HU: cesta neznáma – zoznam sa uloží pri návšteve Dodacích údajov (captureCart) */ function aKey(a) { return norm(a.street).replace(/[^a-z0-9]/g, '') + '|' + String(a.zip || '').replace(/\D/g, ''); } function aText(a) { return a.street + ', ' + a.zip + ' ' + a.city; } function loadCartAddrs() { if (state.addr.cartTried) { return; } state.addr.cartTried = true; var c = lsGet(ADR_KEY); if (c && c.list) { state.addr.cart = c.list; } if ((c && c.ts && (Date.now() - c.ts) < 24 * 3600 * 1000) || !CART_PATHS[m]) { return; } fetch(CART_PATHS[m], { credentials: 'same-origin' }).then(function (r) { return r.ok ? r.text() : ''; }).then(function (h) { if (!h) { return; } var l = parseCartAddrs(new DOMParser().parseFromString(h, 'text/html')); if (l.length) { lsSet(ADR_KEY, { ts: Date.now(), list: l }); state.addr.cart = l; renderAddr(); } }).catch(function () {}); } function currentInvoice() { var no = txt($('ags-inv-manual').value) || state.invoiceChoice || ''; if (!no || !state.invoices) { return null; } for (var i = 0; i < state.invoices.length; i++) { if (state.invoices[i].no === no) { return state.invoices[i]; } } return null; } function collectAddrs(inv) { var map = {}, order = []; function add(a, src, cnt) { if (!a || !a.street) { return null; } var k = aKey(a), e = map[k]; if (!e) { e = map[k] = { key: k, name: a.name || '', street: a.street, zip: a.zip, city: a.city, country: a.country || '', n: 0, hq: false, cart: false }; order.push(e); } if (!e.name && a.name) { e.name = a.name; } if (src === 'hq') { e.hq = true; } if (src === 'cart') { e.cart = true; } e.n += cnt || 0; return e; } var ac = state.account; add({ name: ac.firma, street: ac.ulica, zip: ac.psc, city: ac.mesto, country: ac.krajina }, 'hq', 0); (state.invoices || []).forEach(function (x) { if (x.dod) { add(x.dod, 'inv', 1); } }); (state.addr.cart || []).forEach(function (a) { add(a, 'cart', 0); }); var invE = inv && inv.dod ? map[aKey(inv.dod)] : null; var list = order.filter(function (e) { return e.hq || e.cart || e.n >= 2 || e === invE; }); list.sort(function (a, b) { return (a === invE ? -1 : b === invE ? 1 : 0) || (b.n - a.n) || (a.hq ? -1 : b.hq ? 1 : 0); }); return { list: list, invE: invE }; } function renderAddr() { var box = $('ags-a-list'); if (!box) { return; } loadCartAddrs(); var inv = currentInvoice(); if (inv && !inv.hasA && inv.pdf && !inv.aLoading && !window.pdfjsLib && !state.addr.pdfReq) { state.addr.pdfReq = true; loadPdfJs().then(renderAddr, function () {}); } if (inv && !inv.hasA && inv.pdf && !inv.aLoading && window.pdfjsLib) { inv.aLoading = true; pdfParse(inv.pdf).then(function (res) { inv.dod = res.dod; inv.hasA = true; inv.items = inv.items || res.items; invCachePut(inv.no, inv.date, res.items, res.dod); }, function () { inv.hasA = true; }).then(function () { inv.aLoading = false; renderAddr(); }); } var c = collectAddrs(inv), invE = c.invE, list = c.list, hint = $('ags-a-hint'); var invNo = inv ? inv.no : ''; var pending = !!(inv && !inv.hasA && inv.pdf); if (state.addr.forInv !== invNo && !state.addr.manual) { if (!pending) { state.addr.forInv = invNo; } var known = invE && (invE.hq || invE.cart || invE.n >= 2 || !(state.addr.cart && state.addr.cart.length)); state.addr.sel = known ? invE.key : (list[0] ? (list.filter(function (e) { return e.hq; })[0] || list[0]).key : 'other'); } if (inv && inv.aLoading) { hint.textContent = t.aLoading; } else if (invE && state.addr.sel === invE.key) { hint.innerHTML = fmt(esc(t.aHint), { inv: '' + esc(inv.no) + '', a: '' + esc(aText(invE)) + '' }); } else { hint.textContent = t.aHint0; } var vis = state.addr.all ? list : list.slice(0, 3); if (!state.addr.all && state.addr.sel !== 'other' && !vis.some(function (e) { return e.key === state.addr.sel; })) { vis = vis.concat(list.filter(function (e) { return e.key === state.addr.sel; })); } var h = ''; vis.forEach(function (e) { var on = state.addr.sel === e.key; h += ''; }); var so = state.addr.sel === 'other'; h += ''; box.innerHTML = h; $('ags-a-other').style.display = so ? '' : 'none'; var all = $('ags-a-all'); all.style.display = list.length > 3 ? '' : 'none'; all.textContent = state.addr.all ? t.aLess : fmt(t.aAll, { n: list.length }); state.addr.list = list; var rr = box.querySelectorAll('input[name=ags-a-r]'); for (var i = 0; i < rr.length; i++) { rr[i].addEventListener('change', function (e) { state.addr.sel = e.target.value; state.addr.manual = true; renderAddr(); }); } } /* dodacie adresy aj z faktúr, ktoré boli v cache ešte bez adresy (pred verziou k) – na pozadí, najnovšie najprv */ var fillRunning = false; function fillAddrs() { if (fillRunning || !state.invoices) { return; } var q = state.invoices.filter(function (x) { return !x.hasA && x.pdf; }).slice(0, 80); if (!q.length) { return; } fillRunning = true; loadPdfJs().then(function () { var i = 0; function next() { if (i >= q.length) { fillRunning = false; renderAddr(); return; } if (document.visibilityState === 'hidden') { setTimeout(next, 5000); return; } var inv = q[i++]; if (inv.hasA) { return next(); } return pdfParse(inv.pdf).then(function (res) { inv.dod = res.dod; inv.hasA = true; invCachePut(inv.no, inv.date, inv.items && inv.items.length ? inv.items : res.items, res.dod); }, function () { inv.hasA = true; }) .then(function () { if (i % 5 === 0) { renderAddr(); } return next(); }); } return next(); }).catch(function () { fillRunning = false; }); } function chosenAddr() { var a = state.account; if (state.addr.sel === 'other') { return { name: txt($('ags-a-name').value), street: txt($('ags-a-street').value), zip: txt($('ags-a-zip').value), city: txt($('ags-a-city').value), country: a.krajina, other: true }; } var e = (state.addr.list || []).filter(function (x) { return x.key === state.addr.sel; })[0]; if (!e) { return { name: a.firma, street: a.ulica, zip: a.psc, city: a.mesto, country: a.krajina }; } var same = !e.country || ({ sk: /slovak|slovensk|szlov/, cz: /czech|cesk|cesko|cseh/, hu: /hungar|magyar|madar/ }[m] || /^$/).test(norm(e.country)); return { name: (e.hq || !e.name || norm(e.name) === norm(a.firma)) ? a.firma : a.firma + ' – ' + e.name, street: e.street, zip: e.zip, city: e.city, country: same ? a.krajina : e.country }; } function buildUrl() { var p = currentProduct(); var a = state.account; var ad = chosenAddr(); var inv = txt($('ags-inv-manual').value) || state.invoiceChoice || ''; var params = { alignLeft: 1, hideTitle: 1, transparentBackground: 1, dynamicHeight: 1, firma: a.firma, email: a.email, ico: a.ico, dic: a.dic, trh: cfg.trh, zdroj: state.zdroj, objednavka: state.objednavka, ulica: ad.street, psc: ad.zip, mesto: ad.city, krajina: ad.country || a.krajina, prevadzka: ad.name || a.firma, znacka: p.brand, produkt: p.name, kod: p.code, ean: p.ean, faktura: inv, prijate: typVal() === 'sklad' ? '' : txt($('ags-cust').value), kupa: typVal() === 'sklad' ? '' : txt($('ags-kupa').value), typ: typVal() }; if (state.draft && state.draft.rid) { params.rid = state.draft.rid; } params.media = (MOST && state.draft && state.draft.rid && state.media === 'mobil') ? 'mobil' : ''; /* v o: fotky z telefónu → Tally skryje sekciu 5 */ var mob = Object.keys(params).filter(function (k) { return !/^(alignLeft|hideTitle|transparentBackground|dynamicHeight)$/.test(k); }) .map(function (k) { return k + '=' + encodeURIComponent(params[k] == null ? '' : params[k]); }).join('&'); var q = Object.keys(params).map(function (k) { return k + '=' + encodeURIComponent(params[k] == null ? '' : params[k]); }).join('&'); return { embed: 'https://tally.so/embed/' + cfg.formId + '?' + q, full: 'https://tally.so/r/' + cfg.formId + '?' + q, mobile: 'https://tally.so/r/' + cfg.formId + '?' + mob }; } function go() { var p = currentProduct(); var err = $('ags-err'); if (!p || !p.brand || !p.name || !p.code) { err.textContent = t.validation; err.style.display = ''; return; } var cust = txt($('ags-cust').value), kupa = txt($('ags-kupa').value); if (typVal() !== 'sklad') { if (!cust) { err.textContent = t.custMissing; err.style.display = ''; return; } if (cust > todayKey()) { err.textContent = t.custFuture; err.style.display = ''; return; } if (!kupa) { err.textContent = t.kupaMissing; err.style.display = ''; return; } if (kupa > cust) { err.textContent = t.kupaAfter; err.style.display = ''; return; } } var adc = chosenAddr(); if (adc.other && (!adc.street || !adc.zip || !adc.city)) { err.textContent = t.aMissing; err.style.display = ''; return; } err.style.display = 'none'; if (!state.media) { state.media = MOST ? MEDIA_DEFAULT : 'pc'; } /* '' = najprv otázka, formulár až po voľbe */ state.draft = makeDraft(); renderForm(); $('ags-go').style.display = 'none'; $('ags-reklamacia-form').scrollIntoView({ behavior: 'smooth', block: 'start' }); } /* v o: voľba „telefón / počítač“ + vložený formulár (pri zmene voľby sa formulár načíta znova s iným skrytým poľom media) */ function renderForm() { var u = buildUrl(); var host = $('ags-reklamacia-form'); var ask = MOST && state.draft.rid, chosen = !ask || !!state.media; host.innerHTML = (ask ? '
' + esc(t.mediaQ) + '' + '' + '' + (chosen ? '' : '
' + esc(t.mediaPick) + '
') + '
' : '') + (chosen ? '' + '

' + esc(t.openNew) + '

' : ''); var ol = host.querySelector('a[target=_blank]'); if (ol) { ol.addEventListener('click', onOpenNew); } var rs = host.querySelectorAll('input[name=ags-media]'); for (var ri = 0; ri < rs.length; ri++) { rs[ri].addEventListener('change', function (e) { state.media = e.target.value; state.draft.media = state.media; renderForm(); }); } if (!chosen) { return; } if (window.Tally && window.Tally.loadEmbeds) { window.Tally.loadEmbeds(); } else { loadScript('https://tally.so/widgets/embed.js').then(function () { if (window.Tally && window.Tally.loadEmbeds) { window.Tally.loadEmbeds(); } }, function () { host.querySelector('iframe').src = u.embed; }); } } /* ---------- 3. Moje reklamácie – prehľad pre partnera (uložené len v tomto prehliadači) ---------- */ var MY_KEY = 'ags_rekl_moje_' + m + '_' + ACCT; var LIMIT_DAYS = 30; function myLoad() { var d = lsGet(MY_KEY); return (d && d.list) ? d.list : []; } function mySave(l) { lsSet(MY_KEY, { v: 1, list: l }); } function todayKey() { return dateKey(new Date()); } function keyToDate(k) { return k ? new Date(k + 'T00:00:00') : null; } function fD(k) { var d = keyToDate(k); if (!d || isNaN(d)) { return ''; } if (m === 'hu') { return d.getFullYear() + '. ' + ('0' + (d.getMonth() + 1)).slice(-2) + '. ' + ('0' + d.getDate()).slice(-2) + '.'; } return d.getDate() + '. ' + (d.getMonth() + 1) + '. ' + d.getFullYear(); } function daysWord(n) { if (m === 'hu') { return n + ' nap'; } var w = m === 'cz' ? ['den', 'dny', 'dní'] : ['deň', 'dni', 'dní']; return n + ' ' + (n === 1 ? w[0] : (n >= 2 && n <= 4 ? w[1] : w[2])); } function deadlineOf(r) { var d = keyToDate(r.cust || r.sent); d.setDate(d.getDate() + LIMIT_DAYS); if (m === 'cz') { while (d.getDay() === 0 || d.getDay() === 6) { d.setDate(d.getDate() + 1); } } /* ČOI: koniec lehoty v sobotu/nedeľu → pondelok */ return d; } function info(r) { var t0 = keyToDate(todayKey()), dl = deadlineOf(r); var left = Math.round((dl - t0) / 86400000), age = Math.round((t0 - keyToDate(r.cust || r.sent)) / 86400000); var cls = r.done ? 'done' : (r.typ === 'sklad' ? 'stock' : (left < 0 ? 'late' : ((left <= 7 || (m === 'hu' && age >= 15)) ? 'warn' : 'ok'))); return { dl: dl, left: left, age: age, cls: cls }; } function newId() { return 'r' + Date.now().toString(36) + Math.random().toString(36).slice(2, 6); } function newRid() { /* kód reklamácie pre Most: 128 bitov, base64url (len tento partner ho pozná) */ var b = new Uint8Array(16), s = '', i; try { (window.crypto || window.msCrypto).getRandomValues(b); } catch (e) { for (i = 0; i < 16; i++) { b[i] = Math.floor(Math.random() * 256); } } for (i = 0; i < 16; i++) { s += String.fromCharCode(b[i]); } return btoa(s).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); } function upsert(rec) { var l = myLoad(), i; for (i = 0; i < l.length; i++) { if (l[i].id === rec.id) { l[i] = rec; mySave(l); return; } } l.push(rec); mySave(l); } function removeRec(id) { mySave(myLoad().filter(function (r) { return r.id !== id; })); } var ui = { view: qp('zoznam') ? 'list' : 'new', filter: 'open', editing: null, sureDel: null, viewing: null }; function setView(v) { ui.view = v; $('ags-view-new').style.display = v === 'new' ? '' : 'none'; $('ags-view-list').style.display = v === 'list' ? '' : 'none'; var b = app.querySelectorAll('.ags-mtab'); for (var i = 0; i < b.length; i++) { b[i].className = 'ags-mtab' + (b[i].getAttribute('data-v') === v ? ' on' : ''); } if (v === 'list') { renderList(); syncStatus(false); } } function renderBadge() { var open = myLoad().filter(function (r) { return !r.done; }); var hot = open.filter(function (r) { var c = info(r).cls; return c === 'late' || c === 'warn'; }).length; var el = $('ags-list-badge'); el.textContent = open.length ? String(open.length) : ''; el.className = 'ags-badge' + (hot ? ' hot' : '') + (open.length ? '' : ' none'); } function sortList(l) { return l.slice().sort(function (a, b) { if (!!a.done !== !!b.done) { return a.done ? 1 : -1; } if (a.done) { return a.done < b.done ? 1 : -1; } return deadlineOf(a) - deadlineOf(b); }); } function renderList() { var box = $('ags-view-list'); var all = myLoad(); var l = sortList(all.filter(function (r) { return ui.filter === 'all' ? true : (ui.filter === 'done' ? !!r.done : !r.done); })); var h = '

' + esc(t.listTitle) + '

' + '
' + esc(t.listNote) + '
' + '
' + esc(t.doneHint) + '
' + '
' + ['open', 'done', 'all'].map(function (f) { var n = f === 'all' ? all.length : all.filter(function (r) { return f === 'done' ? !!r.done : !r.done; }).length; return ''; }).join('') + '
'; if (!all.length) { h += '

' + esc(t.empty) + '

'; } else if (!l.length) { h += '

' + esc(t.emptyFilter) + '

'; } else { h += '
'; l.forEach(function (r) { var x = info(r), left, extra = ''; if (r.done) { left = fmt(t.doneOn, { d: fD(r.done) }); } else if (r.typ === 'sklad') { left = t.stock; } else if (x.left < 0) { left = fmt(t.overdue, { n: daysWord(-x.left), k: -x.left }); } else if (x.left === 0) { left = t.today; } else { left = fmt(t.daysLeft, { n: daysWord(x.left) }); } if (!r.done && r.typ !== 'sklad' && m === 'hu' && x.age >= 15 && x.left >= 0) { extra = '
' + esc(t.hu15) + '
'; } h += '' + '' + '' + '' + '' + ''; }); h += '
' + esc(t.cCust) + '' + esc(t.cDl) + '' + esc(t.cProd) + '' + esc(t.cInv) + '' + esc(t.cDoneShort) + '
' + (r.typ === 'sklad' ? esc(t.stockShort) : esc(fD(r.cust))) + (r.kupa ? '
' + esc(fmt(t.bought, { d: fD(r.kupa) })) + '
' : '') + '
' + esc(t.cSent) + ' ' + esc(fD(r.sent)) + '
' + (r.typ === 'sklad' ? '' : '' + esc(fD(dateKey(x.dl))) + '
') + '' + esc(left) + '' + extra + '
' + esc(r.name) + '
' + esc([r.brand, r.code].filter(Boolean).join(' · ')) + '
' + (r.note ? '
' + esc(r.note) + '
' : '') + srvLine(r) + (r.src === 'pending' ? '
' + esc(t.pending) + '
' : '') + '
· · ' + (ui.sureDel === r.id ? '' : '') + '
' + esc(r.inv || '') + '
'; } h += '
' + '

' + ' · ' + ' · ' + '

'; box.innerHTML = h; if (ui.editing) { renderMyForm(ui.editing); } if (ui.viewing) { var vr = myLoad().filter(function (r) { return r.id === ui.viewing; })[0]; if (vr) { renderDetail(vr); } else { ui.viewing = null; } } if (ui.qr) { var qr = all.filter(function (r) { return r.id === ui.qr; })[0]; if (qr) { renderQr($('ags-qr-' + qr.id), qr); } } renderBadge(); if (all.some(function (r) { return r.src === 'mobil' && r.w !== 'expired'; })) { watchMobile(); } } function renderMyForm(rec) { var f = $('ags-my-form'); if (!f) { return; } var r = rec === 'new' ? { sent: todayKey(), cust: todayKey() } : rec; f.innerHTML = '
' + '
' + '
' + '
' + '
' + '
' + '
' + '' + '' + '' + '

'; } function saveMyForm() { var rec = ui.editing === 'new' ? { id: newId(), src: 'manual', done: '' } : ui.editing; var v = function (id) { return txt($(id).value); }; var cust = v('ags-f-cust'), sent = v('ags-f-sent') || todayKey(), err = $('ags-f-err'); if (!v('ags-f-name') || !cust) { err.textContent = t.reqManual; err.style.display = ''; return; } if (cust > todayKey() || sent > todayKey()) { err.textContent = t.custFuture; err.style.display = ''; return; } rec.sent = sent; rec.cust = cust; rec.brand = v('ags-f-brand'); rec.code = v('ags-f-code'); rec.inv = v('ags-f-inv'); rec.name = v('ags-f-name'); rec.note = v('ags-f-note'); rec.kupa = v('ags-f-kupa'); upsert(rec); ui.editing = null; renderList(); } /* CSV: bodkočiarka + BOM (Excel v SK/CZ/HU), dátumy RRRR-MM-DD */ var CSV_COLS = ['sent', 'cust', 'deadline', 'brand', 'name', 'code', 'inv', 'note', 'done']; function csvCell(s) { s = String(s == null ? '' : s); return /[;"\n\r]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s; } function exportCsv() { var head = [t.cSent, t.cCust, t.cDl, t.brand, t.cProd, t.code, t.cInv, t.noteShort, t.cDone, t.kupa, t.typLabel]; var rows = [head.map(csvCell).join(';')].concat(sortList(myLoad()).map(function (r) { return [r.sent, r.cust, r.typ === 'sklad' ? '' : dateKey(deadlineOf(r)), r.brand, r.name, r.code, r.inv, r.note, r.done, r.kupa || '', r.typ === 'sklad' ? t.stockShort : t.typCust].map(csvCell).join(';'); })); var blob = new Blob(['' + rows.join('\r\n')], { type: 'text/csv;charset=utf-8' }); var a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'reklamacie-' + m + '-' + todayKey() + '.csv'; document.body.appendChild(a); a.click(); setTimeout(function () { URL.revokeObjectURL(a.href); a.parentNode.removeChild(a); }, 1000); } function parseCsv(text) { var rows = [], row = [], cell = '', q = false, i, c; text = text.replace(/^/, ''); for (i = 0; i < text.length; i++) { c = text.charAt(i); if (q) { if (c === '"') { if (text.charAt(i + 1) === '"') { cell += '"'; i++; } else { q = false; } } else { cell += c; } } else if (c === '"') { q = true; } else if (c === ';' || c === ',') { row.push(cell); cell = ''; } else if (c === '\n') { row.push(cell); rows.push(row); row = []; cell = ''; } else if (c !== '\r') { cell += c; } } if (cell || row.length) { row.push(cell); rows.push(row); } return rows; } function normDateCell(s) { s = txt(s); var mm; if ((mm = s.match(/^(\d{4})[-.\/ ]+(\d{1,2})[-.\/ ]+(\d{1,2})\.?$/))) { return mm[1] + '-' + ('0' + mm[2]).slice(-2) + '-' + ('0' + mm[3]).slice(-2); } if ((mm = s.match(/^(\d{1,2})[.\/ ]+(\d{1,2})[.\/ ]+(\d{4})$/))) { return mm[3] + '-' + ('0' + mm[2]).slice(-2) + '-' + ('0' + mm[1]).slice(-2); } return ''; } function importCsv(file) { var msg = $('ags-my-msg'); var rd = new FileReader(); rd.onload = function () { try { var rows = parseCsv(String(rd.result)), l = myLoad(), added = 0; var sig = function (r) { return [r.sent, r.cust, norm(r.name), norm(r.code), norm(r.inv)].join('|'); }; var have = {}; l.forEach(function (r) { have[sig(r)] = 1; }); rows.forEach(function (c) { var sent = normDateCell(c[0] || ''), cust = normDateCell(c[1] || ''); if (!sent || !txt(c[4] || '')) { return; } /* hlavička alebo prázdny riadok */ var r = { id: newId(), src: 'import', sent: sent, cust: cust || sent, brand: txt(c[3] || ''), name: txt(c[4] || ''), code: txt(c[5] || ''), inv: txt(c[6] || ''), note: txt(c[7] || ''), done: normDateCell(c[8] || ''), kupa: normDateCell(c[9] || ''), typ: (txt(c[10] || '') && txt(c[10] || '') !== t.typCust) ? 'sklad' : '' }; if (have[sig(r)]) { return; } have[sig(r)] = 1; l.push(r); added++; }); mySave(l); renderList(); $('ags-my-msg').textContent = fmt(t.importDone, { n: added }); } catch (e) { msg.textContent = t.importErr; } }; rd.onerror = function () { msg.textContent = t.importErr; }; rd.readAsText(file, 'utf-8'); } function onListClick(e) { var el = e.target.closest ? e.target.closest('[data-a],[data-f]') : null; if (!el) { return; } var f = el.getAttribute('data-f'); if (f) { ui.filter = f; ui.sureDel = null; renderList(); return; } var a = el.getAttribute('data-a'), id = el.getAttribute('data-id'); var rec = id ? myLoad().filter(function (r) { return r.id === id; })[0] : null; if (a === 'done' || a === 'file') { return; } if (a === 'qr' && rec) { ui.qr = ui.qr === rec.id ? null : rec.id; renderList(); } else if (a === 'confirm' && rec) { rec.src = 'tally-okno'; upsert(rec); renderList(); } else if (a === 'del') { ui.sureDel = id; renderList(); } else if (a === 'del2') { removeRec(id); detDel(id); if (ui.viewing === id) { ui.viewing = null; } ui.sureDel = null; renderList(); } else if (a === 'view' && rec) { ui.viewing = rec.id; ui.editing = null; renderList(); $('ags-my-detail').scrollIntoView({ behavior: 'smooth', block: 'start' }); } else if (a === 'close') { ui.viewing = null; renderList(); } else if (a === 'print') { document.body.classList.add('ags-printing'); setTimeout(function () { window.print(); }, 50); } else if (a === 'edit' && rec) { ui.editing = rec; ui.viewing = null; renderList(); $('ags-my-form').scrollIntoView({ behavior: 'smooth', block: 'center' }); } else if (a === 'add') { ui.editing = 'new'; renderList(); $('ags-my-form').scrollIntoView({ behavior: 'smooth', block: 'center' }); } else if (a === 'save') { saveMyForm(); } else if (a === 'cancel') { ui.editing = null; renderList(); } else if (a === 'export') { exportCsv(); } else if (a === 'import') { $('ags-my-file').click(); } } function onListChange(e) { var el = e.target; if (el.id === 'ags-my-file' && el.files && el.files[0]) { importCsv(el.files[0]); el.value = ''; return; } if (el.getAttribute('data-a') === 'done') { var rec = myLoad().filter(function (r) { return r.id === el.getAttribute('data-id'); })[0]; if (rec) { rec.done = el.checked ? todayKey() : ''; upsert(rec); renderList(); } } } /* záznam po odoslaní formulára */ function typVal() { var r = app.querySelector('input[name=ags-typ]:checked'); return r ? r.value : 'zakaznik'; } function over24(k, c) { var d = keyToDate(k); d.setMonth(d.getMonth() + 24); return d < keyToDate(c); } function checkKupa() { var k = txt($('ags-kupa').value), c = txt($('ags-cust').value) || todayKey(), w = $('ags-warn24'); if (k && over24(k, c)) { w.textContent = t.old24; w.style.display = ''; } else { w.style.display = 'none'; } } function makeDraft() { var p = currentProduct(); return { id: newId(), src: 'draft', sent: todayKey(), typ: typVal(), kupa: typVal() === 'sklad' ? '' : txt($('ags-kupa').value), cust: (typVal() === 'sklad' ? '' : txt($('ags-cust').value)) || todayKey(), brand: p.brand, name: p.name, code: p.code, inv: txt($('ags-inv-manual').value) || state.invoiceChoice || '', note: txt($('ags-note').value), done: '', rid: MOST ? newRid() : '', media: MOST ? state.media : 'pc' }; } /* ---------- detail odoslanej reklamácie (kópia odpovedí z Tally, iba v tomto prehliadači) ---------- */ var DET_KEY = 'ags_rekl_det_' + m + '_' + ACCT, DET_MAX = 150; function detAll() { var d = lsGet(DET_KEY); return (d && d.v === 1 && d.map) ? d : { v: 1, map: {} }; } function detGet(id) { return detAll().map[id] || null; } function detPut(id, snap) { var d = detAll(); d.map[id] = snap; var ids = Object.keys(d.map); if (ids.length > DET_MAX) { ids.sort(function (a, b) { return (d.map[a].at || 0) - (d.map[b].at || 0); }).slice(0, ids.length - DET_MAX).forEach(function (k) { delete d.map[k]; }); } lsSet(DET_KEY, d); } function detDel(id) { var d = detAll(); if (d.map[id]) { delete d.map[id]; lsSet(DET_KEY, d); } } var SKIP_TITLE = /intern|belső/i; function snapshot(p, sid) { var fields = p.fields || (p.data && p.data.fields) || [], out = [], size = 0; fields.forEach(function (f) { if (!f || size > 12000) { return; } var title = txt(f.title || f.label || f.name || ''), type = String(f.type || ''); if (!title || type === 'HIDDEN_FIELDS' || type === 'CALCULATED_FIELDS' || SKIP_TITLE.test(title)) { return; } var a = f.answer, v = (a && typeof a === 'object' && !Array.isArray(a) && ('value' in a || 'raw' in a)) ? (a.value != null ? a.value : a.raw) : (a != null ? a : f.value); var row = null; if (Array.isArray(v) && v.length && typeof v[0] === 'object' && v[0] && (v[0].url || v[0].name)) { row = [title, v.map(function (x) { return { n: String(x.name || 'súbor').slice(0, 120), u: /^https:\/\//.test(x.url || '') ? String(x.url) : '' }; }), 'f']; } else if (Array.isArray(v)) { var s0 = v.filter(function (x) { return x != null && x !== ''; }).map(function (x) { return typeof x === 'object' ? (x.text || x.label || x.value || '') : String(x); }).join(', '); if (s0) { row = [title, s0.length > 240 ? s0.slice(0, 237) + '…' : s0, 't']; } } else if (v === true || v === false) { row = [title, v ? '✓' : '–', 't']; } else if (v != null && typeof v !== 'object' && String(v) !== '') { var sv = String(v); if (/^\d{4}-\d{2}-\d{2}$/.test(sv)) { sv = fD(sv); } row = [title, sv.length > 2000 ? sv.slice(0, 1997) + '…' : sv, 't']; } if (row) { out.push(row); size += JSON.stringify(row).length; } }); return { at: Date.now(), sid: sid || '', form: p.formId || cfg.formId, k: Object.keys(p).slice(0, 12).join(','), f: out }; } function renderDetail(rec) { var box = $('ags-my-detail'); if (!box) { return; } if (!rec) { box.innerHTML = ''; document.body.classList.remove('ags-printing'); return; } var sn = detGet(rec.id), x = info(rec); var kv = function (k, v) { return v ? '' + esc(k) + '' + esc(v) + '' : ''; }; var h = '

' + esc(t.detTitle) + '

' + esc(fmt(t.detSent, { d: fD(rec.sent) })) + (rec.srv && rec.srv.n ? ' · ' + esc(fmt(t.stNo, { n: rec.srv.n })) : ((sn && sn.sid) || rec.sid ? ' · ' + esc(t.detNo) + ': ' + esc((sn && sn.sid) || rec.sid) + '' : '')) + '
' + '
' + srvDetail(rec) + '

' + esc(t.detOwn) + '

' + kv(t.cProd, rec.name) + kv(t.brand, rec.brand) + kv(t.code, rec.code) + kv(t.cInv, rec.inv) + kv(t.typLabel, rec.typ === 'sklad' ? t.stockShort : t.typCust) + (rec.typ === 'sklad' ? '' : kv(t.custDate, fD(rec.cust)) + kv(t.kupa, fD(rec.kupa)) + kv(t.cDl, fD(dateKey(x.dl)))) + kv(t.noteShort, rec.note) + kv(t.cDone, rec.done ? fD(rec.done) : '') + '
'; if (sn && sn.f && sn.f.length) { var files = false; h += '

' + esc(t.detForm) + '

' + sn.f.map(function (r) { var val; if (r[2] === 'f') { files = true; val = r[1].map(function (fl) { return fl.u ? '' + esc(fl.n) + '' : esc(fl.n); }).join('
'); } else { val = esc(r[1]).replace(/\n/g, '
'); } return ''; }).join('') + '
' + esc(r[0]) + '' + val + '
' + (files ? '

' + esc(t.detFiles) + '

' : '') + '

' + esc(t.detLocal) + '

'; } else { h += '

' + esc(t.detNone) + '

'; } h += '

' + esc(fmt(t.detPrinted, { d: fD(todayKey()) })) + '

'; box.innerHTML = h; if (rec.src === 'mobil' && rec.w !== 'expired') { renderQr($('ags-qr-det-' + rec.id), rec); } try { if (window.dataLayer && window.dataLayer.push) { window.dataLayer.push({ event: 'ags_reklamacia_detail', trh: cfg.trh }); } } catch (e2) {} } function onTallyMessage(e) { if (e.origin !== 'https://tally.so' || !state.draft) { return; } var d = e.data; if (typeof d === 'string') { if (d.indexOf('Tally.FormSubmitted') < 0) { return; } try { d = JSON.parse(d); } catch (x) { return; } } if (!d || d.event !== 'Tally.FormSubmitted') { return; } var p = d.payload || {}; if (p.formId && p.formId !== cfg.formId) { return; } var rec = state.draft; state.draft = null; var viaPhone = !!(MOST && rec.rid && rec.media === 'mobil'); rec.src = viaPhone ? 'mobil' : 'tally'; rec.sid = p.id || p.submissionId || p.respondentId || ''; if (viaPhone) { rec.w = 'text'; } upsert(rec); renderBadge(); try { detPut(rec.id, snapshot(p, rec.sid)); } catch (x) {} try { if (window.dataLayer && window.dataLayer.push) { window.dataLayer.push({ event: 'ags_reklamacia_odoslana', trh: cfg.trh }); } } catch (x) {} var ok = $('ags-saved'); ok.innerHTML = (viaPhone ? '
' : '') + '
' + esc(viaPhone ? t.textGot : t.saved) + ' ·
'; ok.style.display = ''; if (viaPhone) { try { $('ags-reklamacia-form').innerHTML = ''; } catch (x4) {} foldSteps(); renderQr($('ags-qr-main'), rec); watchMobile(); } $('ags-show-list').addEventListener('click', function () { setView('list'); window.scrollTo({ top: app.getBoundingClientRect().top + window.pageYOffset - 20, behavior: 'smooth' }); }); $('ags-another').addEventListener('click', function () { location.href = location.pathname; }); ok.scrollIntoView({ behavior: 'smooth', block: 'center' }); } window.addEventListener('message', onTallyMessage); window.addEventListener('afterprint', function () { document.body.classList.remove('ags-printing'); }); /* formulár otvorený v novom okne – odoslanie nevieme overiť → záznam „neoverené“ */ function onOpenNew() { if (!state.draft) { return; } var rec = JSON.parse(JSON.stringify(state.draft)); rec.src = 'pending'; upsert(rec); renderBadge(); /* ak partner odošle aj vo vloženom formulári, ten istý záznam sa potvrdí */ } /* ---------- v o: QR kód pre telefón (po odoslaní textu) + sledovanie stavu ---------- */ function qrSvg(text) { var q = window.qrcode(0, 'M'); q.addData(text); q.make(); return q.createSvgTag({ cellSize: 4, margin: 2, scalable: true }); } function mobLink(rid) { return MOST + '?a=m&r=' + rid; } function renderQr(box, rec) { if (!box || !rec || !rec.rid || !MOST) { return; } var link = mobLink(rec.rid); var body = function (svg) { return '
' + svg + '

' + esc(t.qrTitle) + '

' + esc(t.qrHint) + '

' + esc(t.qrSteps) + '

' + '

' + esc(t.qrRule) + '

' + esc(t.qrLink) + '
' + esc(link) + '

' + '

' + esc(t.pcLink) + '

'; }; box.innerHTML = body('…'); (window.qrcode ? Promise.resolve() : loadScript(QRJS)).then(function () { box.innerHTML = body(qrSvg(link)); }, function () {}); try { if (window.dataLayer && window.dataLayer.push) { window.dataLayer.push({ event: 'ags_reklamacia_qr', trh: cfg.trh }); } } catch (e) {} } var watchT = null, watchFrom = 0; function watchMobile() { if (!MOST || watchT) { return; } watchFrom = Date.now(); watchT = setInterval(function () { var open = myLoad().some(function (r) { return r.src === 'mobil' && r.rid && r.w !== 'expired'; }); if (!open || Date.now() - watchFrom > WATCH_MAX || document.hidden) { if (!open || Date.now() - watchFrom > WATCH_MAX) { clearInterval(watchT); watchT = null; } return; } syncStatus(true); }, WATCH_EVERY); } function gotList(rec) { /* čo prišlo z telefónu (počty z Mosta) */ var m = rec.mf || {}, li = function (lab, n, ok) { return '
  • ' + (ok ? '\u2713' : '\u2013') + '' + esc(lab) + (n > 1 ? ' (' + n + '\u00d7)' : '') + '
  • '; }; return ''; } /* v r: názov produktu z feedu už značku obsahuje („KINDERKRAFT Kočík…“) – značku nepridávať dvakrát */ function prodTitle(brand, name) { var z = txt(brand || ''), p = txt(name || ''); if (z && p.toLowerCase().indexOf(z.toLowerCase()) === 0) { return p; } return [z, p].filter(Boolean).join(' '); } function donePanel(rec, withButtons) { return '

    ' + esc(t.doneTitle) + '

    ' + (rec.srv && rec.srv.n ? '

    ' + esc(fmt(t.stNo, { n: rec.srv.n })) + '

    ' : '') + '

    ' + esc(prodTitle(rec.brand, rec.name)) + (rec.code ? ' ' + esc(rec.code) + '' : '') + '

    ' + /* v r */ (rec.mf ? '

    ' + esc(t.doneGot) + '

    ' + gotList(rec) : '') + '

    ' + esc(t.doneNext) + '

    ' + (withButtons ? '

    ' : '') + '
    '; } function foldSteps() { /* v p: po odoslaní textu skryť vyplnené kroky – partner vidí len QR / výsledok */ var st = app.querySelectorAll('#ags-view-new .ags-step'); for (var i = 0; i < st.length; i++) { st[i].style.display = 'none'; } var g = $('ags-go'); if (g) { g.style.display = 'none'; } try { app.scrollIntoView({ behavior: 'smooth', block: 'start' }); } catch (e) {} } function onSentFromPhone(rec) { /* fotky prišli a Most odoslal do servisu – na stránke, kde partner čaká, jeden veľký panel namiesto QR a pásikov */ var ok = $('ags-saved'); if (!ok || !$('ags-qr-main')) { return; } ok.innerHTML = donePanel(rec, true); foldSteps(); $('ags-show-list').addEventListener('click', function () { setView('list'); window.scrollTo({ top: app.getBoundingClientRect().top + window.pageYOffset - 20, behavior: 'smooth' }); }); $('ags-another').addEventListener('click', function () { location.href = location.pathname; }); ok.scrollIntoView({ behavior: 'smooth', block: 'center' }); } /* ---------- v n: stav z Mosta (odoslané, číslo a stav v servise, súbory) ---------- */ var ST_KEY = 'ags_rekl_st_' + m + '_' + ACCT; function syncStatus(force) { if (!MOST) { return; } var last = +(lsGet(ST_KEY) || 0); if (!force && Date.now() - last < ST_EVERY) { return; } var l = myLoad().filter(function (r) { return r.rid && !(r.srv && r.srv.fin && r.srv.t && Date.now() - r.srv.t < 86400000 * 3); }); l.sort(function (a, b) { return (b.sent || '') < (a.sent || '') ? -1 : 1; }); var ids = l.slice(0, 40).map(function (r) { return r.rid; }); if (!ids.length) { return; } lsSet(ST_KEY, Date.now()); fetch(MOST + '?a=st&r=' + ids.join(','), { credentials: 'omit', redirect: 'follow' }).then(function (r) { return r.json(); }).then(function (res) { if (!res || !res.ok || !res.items) { return; } var all = myLoad(), ch = false; all.forEach(function (r) { var it = r.rid ? res.items[r.rid] : null; if (!it) { return; } if (it.s === 1) { var wasPhone = r.src === 'mobil'; if (r.src === 'mobil' || r.src === 'pending' || r.src === 'draft') { r.src = 'tally'; if (it.at) { r.sent = it.at.slice(0, 10); } ch = true; } if (it.m) { r.mf = it.m; r.mv = it.v ? 1 : 0; } /* v p: čo prišlo z telefónu */ if (wasPhone) { r.w = ''; setTimeout(function () { onSentFromPhone(r); }, 0); } var srv = { n: it.n || '', st: it.st || '', vy: it.vy || '', fin: it.fin ? 1 : 0, ch: it.ch || '', t: Date.now() }; if (JSON.stringify([srv.n, srv.st, srv.vy, srv.fin]) !== JSON.stringify(r.srv ? [r.srv.n, r.srv.st, r.srv.vy, r.srv.fin] : [])) { ch = true; } r.srv = srv; if (it.d) { try { detMost(r.id, it.d); } catch (e) {} } } else if (r.src === 'mobil') { if (it.w && it.w !== r.w) { r.w = it.w; ch = true; } /* v o: text / media / video / expired */ if (it.op && !r.mobOpen) { r.mobOpen = it.op; ch = true; } } }); if (ch) { mySave(all); if (ui.view === 'list') { renderList(); } else { renderBadge(); } } }).catch(function () {}); } /* súbory a odpovede z Mosta (aj keď partner odoslal z mobilu) – doplní kópiu detailu, ak v tomto prehliadači chýba */ function detMost(id, d) { var cur = detGet(id); if (cur && cur.most) { return; } var F = d.files || [], rows = []; var add = function (k, v) { if (v) { rows.push([k, v, 't']); } }; if (!cur || !cur.f || !cur.f.length) { add(t.cProd, d.p); add(t.brand, d.z); add(t.code, d.k); add(t.cInv, d.f); add(t.stDesc, d.po); } var snap = cur || { at: Date.now(), sid: '', form: cfg.formId, f: [] }; snap.f = (snap.f || []).concat(rows); snap.most = { files: F.slice(0, 40), vl: d.vl || '' }; detPut(id, snap); } function srvLine(r) { if (r.src === 'mobil') { var w = r.w || 'media', lab = w === 'expired' ? t.wExpired : (w === 'video' ? t.wVideo : (w === 'text' ? t.wText : t.wMedia)); return '
    ' + esc(lab) + '' + (w === 'expired' || !r.rid ? '' : ' ') + '
    ' + (ui.qr === r.id && w !== 'expired' ? '
    ' : ''); } if (!r.srv) { return ''; } var s = r.srv, label; if (s.st === '#rucne') { label = t.stManual; } else if (!s.n) { label = t.stSent; } else { label = fmt(t.stNo, { n: s.n }) + (s.st ? ' · ' + s.st : '') + (s.fin && !/vyrie|vyřízen|vybaven/i.test(s.st) ? ' · ' + t.stClosed : ''); } return '
    ' + esc(label) + '
    '; } function srvDetail(rec) { var s = rec.srv, sn = detGet(rec.id), h = ''; if (rec.src === 'mobil') { var w = rec.w || 'media'; return '

    ' + esc(w === 'expired' ? t.wExpired : (w === 'video' ? t.wVideo : (w === 'text' ? t.wText : t.wMedia))) + '

    ' + (w === 'expired' ? '' : '
    '); } if (rec.mf) { h += '

    ' + esc(t.doneGot) + '

    ' + gotList(rec) + '
    '; } /* v p */ if (s) { var kv = function (k, v) { return v ? '' + esc(k) + '' + esc(v) + '' : ''; }; var st = s.st === '#rucne' ? t.stManual : (s.st || (s.n ? '' : t.stSent)); h += '

    ' + esc(t.stTitle) + '

    ' + kv(t.stNum, s.n) + kv(t.stState, st + (s.fin && st && !/vyrie|vyřízen|vybaven/i.test(st) ? ' (' + t.stClosed + ')' : '')) + kv(t.stHandling, s.vy) + kv(t.stChecked, s.ch ? new Date(s.ch).toLocaleString({ sk: 'sk-SK', cz: 'cs-CZ', hu: 'hu-HU' }[m] || 'sk-SK') : '') + '
    '; } var F = sn && sn.most ? sn.most.files : []; if (F.length || (sn && sn.most && sn.most.vl)) { var img = F.filter(function (f) { return /^image\//.test(f.m || '') || /\.(jpe?g|png|webp|heic)$/i.test(f.n || ''); }); var oth = F.filter(function (f) { return img.indexOf(f) < 0; }); h += '

    ' + esc(t.stFiles) + '

    ' + (img.length ? '
    ' + img.map(function (f) { return '' + esc(f.n) + ''; }).join('') + '
    ' : '') + (oth.length ? '

    ' + oth.map(function (f) { return '' + esc(f.n) + '' + (f.s ? ' (' + (Math.round(f.s / 104857.6) / 10) + ' MB)' : ''); }).join('
    ') + '

    ' : '') + (sn.most.vl && /^https?:\/\//.test(sn.most.vl) ? '

    ' + esc(t.stVideoLink) + ': ' + esc(sn.most.vl) + '

    ' : ''); } return h; } var mt = app.querySelectorAll('.ags-mtab'); for (var mi = 0; mi < mt.length; mi++) { mt[mi].addEventListener('click', function (e) { var b = e.target.closest ? e.target.closest('.ags-mtab') : e.target; setView(b.getAttribute('data-v')); }); } $('ags-view-list').addEventListener('click', onListClick); $('ags-view-list').addEventListener('change', onListChange); $('ags-cust').value = todayKey(); $('ags-cust').max = todayKey(); $('ags-kupa').max = todayKey(); dateRead('ags-cust'); dateRead('ags-kupa'); function onTyp() { $('ags-cust-box').style.display = typVal() === 'sklad' ? 'none' : ''; $('ags-err').style.display = 'none'; } var typR = app.querySelectorAll('input[name=ags-typ]'); for (var tyi = 0; tyi < typR.length; tyi++) { typR[tyi].addEventListener('change', onTyp); } /* dátum slovom pod poľom – jednoznačné bez ohľadu na jazyk prehliadača (4. 3. vs 3. 4.) */ function longDate(k) { var d = keyToDate(k); if (!d || isNaN(d)) { return ''; } try { return new Intl.DateTimeFormat({ sk: 'sk-SK', cz: 'cs-CZ', hu: 'hu-HU' }[m] || 'sk-SK', { year: 'numeric', month: 'long', day: 'numeric' }).format(d); } catch (e) { return fD(k); } } function dateRead(id) { var inp = $(id), out = $(id + '-r'); if (!inp || !out) { return; } var v = txt(inp.value); out.textContent = v ? fmt(t.dPicked, { d: longDate(v) }) : t.dEmpty; out.className = 'ags-dread' + (v ? ' on' : ''); } ['ags-cust', 'ags-kupa'].forEach(function (id) { ['input', 'change'].forEach(function (ev) { $(id).addEventListener(ev, function () { dateRead(id); }); }); }); $('ags-kupa').addEventListener('change', checkKupa); $('ags-cust').addEventListener('change', checkKupa); renderBadge(); if (ui.view === 'list') { setView('list'); } else { setTimeout(function () { syncStatus(false); }, 4000); } var tabs = app.querySelectorAll('#ags-view-new .ags-tab'); for (var ti = 0; ti < tabs.length; ti++) { tabs[ti].addEventListener('click', function (e) { setSource(e.target.getAttribute('data-src')); }); } var debB; elBoughtFilter.addEventListener('input', function () { state.pickedBought = null; state.product = null; state.invoiceChoice = ''; showPicked(null); clearTimeout(debB); debB = setTimeout(function () { renderBought(); renderInvoices(); }, 120); }); elBoughtFilter.addEventListener('focus', function () { if (state.pickedBought) { this.select(); } }); elBought.addEventListener('change', onBoughtPick); elBrand.addEventListener('change', function () { elFilter.value = ''; renderProducts(); }); var debP; elFilter.addEventListener('input', function () { clearTimeout(debP); debP = setTimeout(renderProducts, 150); }); elFilter.addEventListener('focus', function () { if (state.product) { this.select(); } }); /* po výbere produktu: písanie nahradí názov */ elProduct.addEventListener('change', onProductPick); var deb; ['ags-m-code', 'ags-m-ean'].forEach(function (id) { $(id).addEventListener('input', function () { clearTimeout(deb); deb = setTimeout(renderInvoices, 400); }); }); $('ags-go').addEventListener('click', go); $('ags-a-all').addEventListener('click', function () { state.addr.all = !state.addr.all; renderAddr(); }); var debA; $('ags-inv-manual').addEventListener('input', function () { clearTimeout(debA); debA = setTimeout(function () { state.addr.manual = false; renderAddr(); }, 400); }); /* --- štart --- */ readHeader(); readIds(); renderBought(); loadFeed().then(function (items) { state.items = items; var bs = {}; items.forEach(function (it) { bs[it[0]] = 1; }); state.brands = Object.keys(bs).sort(function (a, b) { return a.localeCompare(b); }); elBrand.innerHTML = '' + state.brands.map(function (b) { return ''; }).join(''); elBrand.disabled = false; elFilter.disabled = false; $('ags-feed-status').textContent = ''; renderProducts(); }).catch(function () { state.feedError = true; $('ags-feed-status').textContent = t.feedError; }); renderInvoices(); loadInvoiceList().then(function (list) { state.invoices = list; renderBought(); renderInvoices(); if (list.length) { return parseInvoices().then(fillAddrs); } }).catch(function () { state.invoicesError = true; renderBought(); renderInvoices(); }); /* staršie faktúry (25 – 48 mesiacov) len na vyžiadanie – z kroku 1 aj z kroku 3 */ function loadMore() { if (state.months >= MONTHS_MAX || !state.invoices || state.moreLoading) { return; } state.months = MONTHS_MAX; state.moreLoading = true; $('ags-more').style.display = 'none'; $('ags-more-status').textContent = t.moreLoading; renderInvoices(); loadInvoiceList(false, MONTHS_MAX).then(function (list) { var have = {}; state.invoices.forEach(function (x) { have[x.no] = 1; }); var add = list.filter(function (x) { return !have[x.no]; }); state.invoices = state.invoices.concat(add); state.moreLoading = false; $('ags-more-status').textContent = ''; renderBought(); renderInvoices(); return parseInvoices(add); }).then(function () { $('ags-more-status').textContent = t.moreDone; }, function () { state.moreLoading = false; $('ags-more-status').textContent = t.invoicesError; renderInvoices(); }); } $('ags-more').addEventListener('click', loadMore); })();