let settAcTimeout = null; document.addEventListener('DOMContentLoaded', async () => { await loadDropdowns(); await loadSettings(); wireAutocomplete('settTransportCodmat', 'settTransportAc'); wireAutocomplete('settDiscountCodmat', 'settDiscountAc'); wireAutocomplete('settKitDiscountCodmat', 'settKitDiscountAc'); // Kit pricing mode radio toggle document.querySelectorAll('input[name="kitPricingMode"]').forEach(r => { r.addEventListener('change', () => { document.getElementById('kitModeBFields').style.display = document.getElementById('kitModeSeparate').checked ? '' : 'none'; }); }); // Catalog sync toggle const catChk = document.getElementById('settCatalogSyncEnabled'); if (catChk) catChk.addEventListener('change', () => { document.getElementById('catalogSyncOptions').style.display = catChk.checked ? '' : 'none'; }); }); async function loadDropdowns() { try { const [sectiiRes, politiciRes, gestiuniRes] = await Promise.all([ fetch('/api/settings/sectii'), fetch('/api/settings/politici'), fetch('/api/settings/gestiuni') ]); const sectii = await sectiiRes.json(); const politici = await politiciRes.json(); const gestiuni = await gestiuniRes.json(); const gestContainer = document.getElementById('settGestiuniContainer'); if (gestContainer) { gestContainer.innerHTML = ''; gestiuni.forEach(g => { gestContainer.innerHTML += `
`; }); if (gestiuni.length === 0) gestContainer.innerHTML = 'Nicio gestiune disponibilă'; } const sectieEl = document.getElementById('settIdSectie'); if (sectieEl) { sectieEl.innerHTML = ''; sectii.forEach(s => { sectieEl.innerHTML += ``; }); } const polEl = document.getElementById('settIdPol'); if (polEl) { polEl.innerHTML = ''; politici.forEach(p => { polEl.innerHTML += ``; }); } const tPolEl = document.getElementById('settTransportIdPol'); if (tPolEl) { tPolEl.innerHTML = ''; politici.forEach(p => { tPolEl.innerHTML += ``; }); } const dPolEl = document.getElementById('settDiscountIdPol'); if (dPolEl) { dPolEl.innerHTML = ''; politici.forEach(p => { dPolEl.innerHTML += ``; }); } const pPolEl = document.getElementById('settIdPolProductie'); if (pPolEl) { pPolEl.innerHTML = ''; politici.forEach(p => { pPolEl.innerHTML += ``; }); } const kdPolEl = document.getElementById('settKitDiscountIdPol'); if (kdPolEl) { kdPolEl.innerHTML = ''; politici.forEach(p => { kdPolEl.innerHTML += ``; }); } } catch (err) { console.error('loadDropdowns error:', err); } } async function loadSettings() { try { const res = await fetch('/api/settings'); const data = await res.json(); const el = (id) => document.getElementById(id); if (el('settTransportCodmat')) el('settTransportCodmat').value = data.transport_codmat || ''; if (el('settTransportVat')) el('settTransportVat').value = data.transport_vat || '21'; if (el('settTransportIdPol')) el('settTransportIdPol').value = data.transport_id_pol || ''; if (el('settDiscountCodmat')) el('settDiscountCodmat').value = data.discount_codmat || ''; if (el('settDiscountVat')) el('settDiscountVat').value = data.discount_vat || '21'; if (el('settDiscountIdPol')) el('settDiscountIdPol').value = data.discount_id_pol || ''; if (el('settSplitDiscountVat')) el('settSplitDiscountVat').checked = data.split_discount_vat === "1"; if (el('settIdPol')) el('settIdPol').value = data.id_pol || ''; if (el('settIdPolProductie')) el('settIdPolProductie').value = data.id_pol_productie || ''; if (el('settIdSectie')) el('settIdSectie').value = data.id_sectie || ''; // Multi-gestiune checkboxes const gestVal = data.id_gestiune || ''; if (gestVal) { const selectedIds = gestVal.split(',').map(s => s.trim()); selectedIds.forEach(id => { const chk = document.getElementById('gestChk_' + id); if (chk) chk.checked = true; }); } if (el('settGomagApiKey')) el('settGomagApiKey').value = data.gomag_api_key || ''; if (el('settGomagApiShop')) el('settGomagApiShop').value = data.gomag_api_shop || ''; if (el('settGomagDaysBack')) el('settGomagDaysBack').value = data.gomag_order_days_back || '7'; if (el('settGomagLimit')) el('settGomagLimit').value = data.gomag_limit || '100'; if (el('settDashPollSeconds')) el('settDashPollSeconds').value = data.dashboard_poll_seconds || '5'; // Kit pricing const kitMode = data.kit_pricing_mode || ''; document.querySelectorAll('input[name="kitPricingMode"]').forEach(r => { r.checked = r.value === kitMode; }); document.getElementById('kitModeBFields').style.display = kitMode === 'separate_line' ? '' : 'none'; if (el('settKitDiscountCodmat')) el('settKitDiscountCodmat').value = data.kit_discount_codmat || ''; if (el('settKitDiscountIdPol')) el('settKitDiscountIdPol').value = data.kit_discount_id_pol || ''; // Price sync if (el('settPriceSyncEnabled')) el('settPriceSyncEnabled').checked = data.price_sync_enabled !== "0"; if (el('settCatalogSyncEnabled')) { el('settCatalogSyncEnabled').checked = data.catalog_sync_enabled === "1"; document.getElementById('catalogSyncOptions').style.display = data.catalog_sync_enabled === "1" ? '' : 'none'; } if (el('settPriceSyncSchedule')) el('settPriceSyncSchedule').value = data.price_sync_schedule || ''; // Load price sync status try { const psRes = await fetch('/api/price-sync/status'); const psData = await psRes.json(); const psEl = document.getElementById('settPriceSyncStatus'); if (psEl && psData.last_run) { psEl.textContent = `Ultima: ${psData.last_run.finished_at || ''} — ${psData.last_run.updated || 0} actualizate din ${psData.last_run.matched || 0}`; } } catch {} } catch (err) { console.error('loadSettings error:', err); } } async function saveSettings() { const el = (id) => document.getElementById(id); const payload = { transport_codmat: el('settTransportCodmat')?.value?.trim() || '', transport_vat: el('settTransportVat')?.value || '21', transport_id_pol: el('settTransportIdPol')?.value?.trim() || '', discount_codmat: el('settDiscountCodmat')?.value?.trim() || '', discount_vat: el('settDiscountVat')?.value || '21', discount_id_pol: el('settDiscountIdPol')?.value?.trim() || '', split_discount_vat: el('settSplitDiscountVat')?.checked ? "1" : "", id_pol: el('settIdPol')?.value?.trim() || '', id_pol_productie: el('settIdPolProductie')?.value?.trim() || '', id_sectie: el('settIdSectie')?.value?.trim() || '', id_gestiune: Array.from(document.querySelectorAll('#settGestiuniContainer input:checked')).map(c => c.value).join(','), gomag_api_key: el('settGomagApiKey')?.value?.trim() || '', gomag_api_shop: el('settGomagApiShop')?.value?.trim() || '', gomag_order_days_back: el('settGomagDaysBack')?.value?.trim() || '7', gomag_limit: el('settGomagLimit')?.value?.trim() || '100', dashboard_poll_seconds: el('settDashPollSeconds')?.value?.trim() || '5', kit_pricing_mode: document.querySelector('input[name="kitPricingMode"]:checked')?.value || '', kit_discount_codmat: el('settKitDiscountCodmat')?.value?.trim() || '', kit_discount_id_pol: el('settKitDiscountIdPol')?.value?.trim() || '', price_sync_enabled: el('settPriceSyncEnabled')?.checked ? "1" : "0", catalog_sync_enabled: el('settCatalogSyncEnabled')?.checked ? "1" : "0", price_sync_schedule: el('settPriceSyncSchedule')?.value || '', gomag_products_url: '', }; try { const res = await fetch('/api/settings', { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); const data = await res.json(); const resultEl = document.getElementById('settSaveResult'); if (data.success) { if (resultEl) { resultEl.textContent = 'Salvat!'; resultEl.style.color = '#16a34a'; } setTimeout(() => { if (resultEl) resultEl.textContent = ''; }, 3000); } else { if (resultEl) { resultEl.textContent = 'Eroare: ' + JSON.stringify(data); resultEl.style.color = '#dc2626'; } } } catch (err) { const resultEl = document.getElementById('settSaveResult'); if (resultEl) { resultEl.textContent = 'Eroare: ' + err.message; resultEl.style.color = '#dc2626'; } } } async function startCatalogSync() { const btn = document.getElementById('btnCatalogSync'); const status = document.getElementById('settPriceSyncStatus'); btn.disabled = true; btn.innerHTML = ' Sincronizare...'; try { const res = await fetch('/api/price-sync/start', { method: 'POST' }); const data = await res.json(); if (data.error) { status.innerHTML = `${escHtml(data.error)}`; btn.disabled = false; btn.textContent = 'Sincronizează acum'; return; } // Poll status const pollInterval = setInterval(async () => { const sr = await fetch('/api/price-sync/status'); const sd = await sr.json(); if (sd.status === 'running') { status.textContent = sd.phase_text || 'Sincronizare în curs...'; } else { clearInterval(pollInterval); btn.disabled = false; btn.textContent = 'Sincronizează acum'; if (sd.last_run) status.textContent = `Ultima: ${sd.last_run.finished_at || ''} — ${sd.last_run.updated || 0} actualizate din ${sd.last_run.matched || 0}`; } }, 2000); } catch (err) { status.innerHTML = `${escHtml(err.message)}`; btn.disabled = false; btn.textContent = 'Sincronizează acum'; } } function wireAutocomplete(inputId, dropdownId) { const input = document.getElementById(inputId); const dropdown = document.getElementById(dropdownId); if (!input || !dropdown) return; input.addEventListener('input', () => { clearTimeout(settAcTimeout); settAcTimeout = setTimeout(async () => { const q = input.value.trim(); if (q.length < 2) { dropdown.classList.add('d-none'); return; } try { const res = await fetch(`/api/articles/search?q=${encodeURIComponent(q)}`); const data = await res.json(); if (!data.results || data.results.length === 0) { dropdown.classList.add('d-none'); return; } dropdown.innerHTML = data.results.map(r => `