diff --git a/presupuestos.html b/presupuestos.html index 247c0c6..348fb6e 100644 --- a/presupuestos.html +++ b/presupuestos.html @@ -7,92 +7,103 @@ - + -
-
+
+ +
+
-

Presupuestos

+

Mis Presupuestos

-
-
-

Historial

-
- Cargando... + Cargando...
-
+
-

Nuevo Presupuesto

- +

Generar Nuevo

+
-
-

Datos del Cliente

+
+

Cliente

- - - + + +
-
-

Conceptos

+
+

Conceptos

-
+
- +
- +
- +
- +
-
-
+
+
+
Subtotal: 0.00 €
-
+
IVA (21%): 0.00 €
-
- TOTAL: 0.00 € +
+ TOTAL: 0.00 €
- @@ -109,22 +120,41 @@ let catalog = []; let currentItems = []; + let allBudgets = []; + + // ------------------ INICIALIZACIÓN Y TEMA CORPORATIVO ------------------ + async function applyTheme() { + try { + let theme = JSON.parse(localStorage.getItem('app_theme')); + const res = await fetch(`${API_URL}/config/company`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } }); + const data = await res.json(); + if(data.ok && data.config && data.config.portal_settings && data.config.portal_settings.app_settings) { + theme = data.config.portal_settings.app_settings; + localStorage.setItem('app_theme', JSON.stringify(theme)); + } + if(theme) { + document.documentElement.style.setProperty('--primary', theme.primary); + document.documentElement.style.setProperty('--secondary', theme.secondary); + document.documentElement.style.setProperty('--app-bg', theme.bg); + } + } catch (e) { console.warn("Usando tema por defecto"); } + } document.addEventListener("DOMContentLoaded", async () => { if (!localStorage.getItem("token")) { window.location.href = "index.html"; return; } + await applyTheme(); lucide.createIcons(); await fetchArticles(); await fetchBudgets(); - // Llenar precio auto al seleccionar artículo del catálogo document.getElementById('item_concept').addEventListener('change', (e) => { const art = catalog.find(a => a.name === e.target.value); if(art) document.getElementById('item_price').value = art.price; }); }); - // ------------------ NAVEGACIÓN ------------------ + // ------------------ NAVEGACIÓN Y TOASTS ------------------ function showCreateView() { document.getElementById('viewList').classList.add('hidden'); document.getElementById('viewCreate').classList.remove('hidden'); @@ -167,12 +197,125 @@ try { const res = await fetch(`${API_URL}/budgets`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } }); const data = await res.json(); - if(data.ok) renderBudgetsList(data.budgets); + if(data.ok) { + allBudgets = data.budgets; + renderBudgetsList(allBudgets); + } } catch(e) { document.getElementById('budgetsList').innerHTML = `
Error de conexión
`; } } + // ------------------ ACCIONES DE LOS PRESUPUESTOS ------------------ + async function updateStatus(id, newStatus) { + try { + const res = await fetch(`${API_URL}/budgets/${id}/status`, { + method: 'PATCH', + headers: { 'Content-Type': 'application/json', "Authorization": `Bearer ${localStorage.getItem("token")}` }, + body: JSON.stringify({ status: newStatus }) + }); + const data = await res.json(); + if (data.ok) { + showToast(newStatus === 'accepted' ? "¡Presupuesto Aceptado!" : "Presupuesto Rechazado"); + fetchBudgets(); + } else { showToast("Error al actualizar"); } + } catch (e) { showToast("Error de conexión"); } + } + + async function deleteBudget(id) { + if (!confirm("¿Seguro que quieres borrar este presupuesto?")) return; + try { + const res = await fetch(`${API_URL}/budgets/${id}`, { + method: 'DELETE', + headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } + }); + const data = await res.json(); + if (data.ok) { + showToast("Presupuesto borrado correctamente"); + fetchBudgets(); + } else { + showToast(data.error || "No se puede borrar este presupuesto"); + } + } catch (e) { showToast("Error de conexión"); } + } + + // FUNCIÓN PARA GENERAR Y DESCARGAR PDF BÁSICO + function downloadPDF(id) { + const b = allBudgets.find(x => x.id === id); + if(!b) return; + + // Creamos un HTML limpio imprimible + let itemsHtml = (b.items || []).map(i => ` + + ${i.concept} + ${i.qty} + ${parseFloat(i.price).toFixed(2)}€ + ${parseFloat(i.total).toFixed(2)}€ + + `).join(''); + + const companyName = localStorage.getItem('userName') || 'Empresa Instaladora'; + const dateStr = new Date(b.created_at).toLocaleDateString('es-ES'); + + const printContent = ` + + + Presupuesto PRE-${b.id} + + + +
+
+

PRESUPUESTO PRE-${b.id}

+

Fecha: ${dateStr}

+

Emitido por: ${companyName}

+
+
+

Datos del Cliente

+

${b.client_name}

+

Tel: ${b.client_phone}

+

${b.client_address || ''}

+
+
+ + + + + + + + + + ${itemsHtml} +
ConceptoCant.Precio/UTotal
+
+
Subtotal: ${parseFloat(b.subtotal).toFixed(2)}€
+
IVA (21%): ${parseFloat(b.tax).toFixed(2)}€
+
TOTAL: ${parseFloat(b.total).toFixed(2)}€
+
+