Actualizar contabilidad.html

This commit is contained in:
2026-08-02 13:40:09 +00:00
parent d87c83cea5
commit 086928ed88

View File

@@ -848,6 +848,72 @@
const name = document.getElementById('bName').value; const name = document.getElementById('bName').value;
if(!name) return showToast("El nombre es obligatorio"); if(!name) return showToast("El nombre es obligatorio");
const items = [];
document.querySelectorAll('#budgetLines > div').forEach(line => {
const idEl = line.querySelector('.b-item-id'); // Por si lograste poner el input oculto
const conceptEl = line.querySelector('.b-concept');
const qtyEl = line.querySelector('.b-qty');
const priceEl = line.querySelector('.b-price');
if (conceptEl && qtyEl && priceEl) {
const c = conceptEl.value;
// Forzamos que si escribes comas, se pasen a puntos para que JS no falle
const qStr = qtyEl.value.toString().replace(',', '.');
const pStr = priceEl.value.toString().replace(',', '.');
const q = parseFloat(qStr) || 0;
const p = parseFloat(pStr) || 0;
if(c && q > 0) {
const itemObj = { concept: c, qty: q, price: p };
if (idEl && idEl.value) itemObj.id = parseInt(idEl.value);
items.push(itemObj);
}
}
});
if(items.length === 0) return showToast("Añade al menos un concepto");
// Aseguramos que limpiamos el símbolo de euro y cambiamos comas por puntos en los totales
const sub = parseFloat(document.getElementById('bSubtotal').innerText.replace('€', '').replace(',', '.')) || 0;
const tax = parseFloat(document.getElementById('bTax').innerText.replace('€', '').replace(',', '.')) || 0;
const tot = parseFloat(document.getElementById('bTotal').innerText.replace('€', '').replace(',', '.')) || 0;
const payload = { client_phone: phone, client_name: name, client_address: document.getElementById('bAddress').value, items, subtotal: sub, tax, total: tot };
const editId = document.getElementById('editBudgetId').value;
try {
let res;
if (editId) {
res = await fetch(`${API_URL}/budgets/${editId}`, { method: 'PUT', headers: { "Content-Type": "application/json", "Authorization": `Bearer ${localStorage.getItem("token")}` }, body: JSON.stringify(payload) });
} else {
res = await fetch(`${API_URL}/budgets`, { method: 'POST', headers: { "Content-Type": "application/json", "Authorization": `Bearer ${localStorage.getItem("token")}` }, body: JSON.stringify(payload) });
}
// Leemos como texto por si el servidor devuelve un string vacío o error HTML
const textResponse = await res.text();
let data = {};
if (textResponse) {
try { data = JSON.parse(textResponse); } catch(e) { console.warn("El servidor no devolvió JSON puro:", textResponse); }
}
if (res.ok && data.ok !== false) {
document.getElementById('budgetModal').classList.add('hidden');
showToast(editId ? "✅ Presupuesto actualizado" : "✅ Presupuesto guardado");
loadBudgets();
} else {
showToast("❌ Error: " + (data.error || "Fallo en el servidor"));
console.error("Respuesta del servidor:", data, textResponse);
}
} catch (error) {
showToast("❌ Error de conexión al guardar.");
console.error("Error en fetch:", error);
}
}
const name = document.getElementById('bName').value;
if(!name) return showToast("El nombre es obligatorio");
const items = []; const items = [];
document.querySelectorAll('#budgetLines > div').forEach(line => { document.querySelectorAll('#budgetLines > div').forEach(line => {
const c = line.querySelector('.b-concept').value; const c = line.querySelector('.b-concept').value;