Actualizar contabilidad.html
This commit is contained in:
@@ -545,59 +545,85 @@
|
||||
function renderBudgets() {
|
||||
const list = document.getElementById('budgetsList');
|
||||
list.innerHTML = "";
|
||||
if(myBudgets.length === 0) { list.innerHTML = `<div class="p-6 text-center text-slate-400">Sin presupuestos</div>`; return; }
|
||||
if(myBudgets.length === 0) {
|
||||
list.innerHTML = `<div class="p-16 text-center text-slate-400">Sin presupuestos generados aún.</div>`;
|
||||
return;
|
||||
}
|
||||
|
||||
myBudgets.forEach(b => {
|
||||
const date = new Date(b.created_at).toLocaleDateString('es-ES');
|
||||
const bDate = new Date(b.created_at);
|
||||
const dateDisplay = bDate.toLocaleDateString('es-ES');
|
||||
|
||||
// 🔴 LÓGICA DE CADUCIDAD (30 DÍAS)
|
||||
const diffDays = Math.ceil(Math.abs(new Date() - bDate) / (1000 * 60 * 60 * 24));
|
||||
const isExpired = diffDays > 30;
|
||||
|
||||
let bStatus = '';
|
||||
let isAnulado = false;
|
||||
if (b.linked_service_status_name && b.linked_service_status_name.toLowerCase().includes('anulado')) {
|
||||
isAnulado = true;
|
||||
}
|
||||
|
||||
if(b.status === 'pending') {
|
||||
bStatus = `<span class="bg-amber-100 text-amber-700 px-2 py-1 rounded text-[10px] font-black uppercase"><i data-lucide="clock" class="w-3 h-3 inline"></i> Pte. Resolver</span>`;
|
||||
} else if(b.status === 'rejected') {
|
||||
bStatus = `<span class="bg-red-100 text-red-700 px-2 py-1 rounded text-[10px] font-black uppercase"><i data-lucide="x" class="w-3 h-3 inline"></i> Rechazado</span>`;
|
||||
} else if(b.status === 'accepted') {
|
||||
bStatus = `<span class="bg-blue-100 text-blue-700 px-2 py-1 rounded text-[10px] font-black uppercase"><i data-lucide="check" class="w-3 h-3 inline"></i> Aceptado</span>`;
|
||||
} else if(b.status === 'converted') {
|
||||
// 🎨 DEFINICIÓN DE ETIQUETAS UNIFICADAS
|
||||
if (b.status === 'paid') {
|
||||
bStatus = `<span class="bg-emerald-100 text-emerald-700 px-3 py-1 rounded-lg text-[10px] font-black uppercase border border-emerald-200 shadow-sm"><i data-lucide="badge-check" class="w-3 h-3 inline mr-1"></i> Pagado Online</span>`;
|
||||
} else if (isExpired && b.status !== 'rejected' && b.status !== 'converted') {
|
||||
bStatus = `<span class="bg-slate-100 text-slate-500 px-3 py-1 rounded-lg text-[10px] font-black uppercase border border-slate-200"><i data-lucide="clock-alert" class="w-3 h-3 inline mr-1"></i> Caducado</span>`;
|
||||
} else if (b.status === 'pending') {
|
||||
bStatus = `<span class="bg-amber-100 text-amber-700 px-3 py-1 rounded-lg text-[10px] font-black uppercase border border-amber-200"><i data-lucide="clock" class="w-3 h-3 inline mr-1"></i> Pte. Resolver</span>`;
|
||||
} else if (b.status === 'rejected') {
|
||||
bStatus = `<span class="bg-red-100 text-red-700 px-3 py-1 rounded-lg text-[10px] font-black uppercase"><i data-lucide="x" class="w-3 h-3 inline mr-1"></i> Rechazado</span>`;
|
||||
} else if (b.status === 'accepted') {
|
||||
bStatus = `<span class="bg-blue-100 text-blue-700 px-3 py-1 rounded-lg text-[10px] font-black uppercase border border-blue-200"><i data-lucide="check" class="w-3 h-3 inline mr-1"></i> Aceptado</span>`;
|
||||
} else if (b.status === 'converted') {
|
||||
if (isAnulado) {
|
||||
bStatus = `<span class="bg-red-100 text-red-700 px-2 py-1 rounded text-[10px] font-black uppercase shadow-sm border border-red-200"><i data-lucide="x-circle" class="w-3 h-3 inline"></i> Servicio Anulado</span>`;
|
||||
bStatus = `<span class="bg-red-50 text-red-600 px-3 py-1 rounded-lg text-[10px] font-black uppercase border border-red-100"><i data-lucide="x-circle" class="w-3 h-3 inline mr-1"></i> Servicio Anulado</span>`;
|
||||
} else {
|
||||
const sName = b.linked_service_status_name || 'En gestión';
|
||||
bStatus = `<span class="bg-emerald-100 text-emerald-700 px-2 py-1 rounded text-[10px] font-black uppercase shadow-sm border border-emerald-200" title="Estado en Operativa"><i data-lucide="briefcase" class="w-3 h-3 inline"></i> ${sName}</span>`;
|
||||
bStatus = `<span class="bg-emerald-50 text-emerald-700 px-3 py-1 rounded-lg text-[10px] font-black uppercase border border-emerald-100" title="Estado en Operativa"><i data-lucide="briefcase" class="w-3 h-3 inline mr-1"></i> ${sName}</span>`;
|
||||
}
|
||||
}
|
||||
|
||||
// 🛠️ LÓGICA DE ACCIONES (Botón de "Crear Servicio")
|
||||
let actions = '';
|
||||
if(b.status === 'pending') {
|
||||
if(b.status === 'pending' && !isExpired) {
|
||||
actions = `
|
||||
<button onclick="updateBudgetStatus(${b.id}, 'accepted')" class="bg-blue-50 text-blue-600 hover:bg-blue-500 hover:text-white p-2 rounded shadow-sm transition-colors" title="Aceptar Presupuesto"><i data-lucide="thumbs-up" class="w-4 h-4"></i></button>
|
||||
<button onclick="updateBudgetStatus(${b.id}, 'rejected')" class="bg-red-50 text-red-600 hover:bg-red-500 hover:text-white p-2 rounded shadow-sm transition-colors" title="Rechazar"><i data-lucide="thumbs-down" class="w-4 h-4"></i></button>
|
||||
<button onclick="updateBudgetStatus(${b.id}, 'accepted')" class="bg-blue-50 text-blue-600 hover:bg-blue-500 hover:text-white p-2 rounded-xl shadow-sm transition-all" title="Aceptar"><i data-lucide="thumbs-up" class="w-4 h-4"></i></button>
|
||||
<button onclick="updateBudgetStatus(${b.id}, 'rejected')" class="bg-rose-50 text-rose-600 hover:bg-rose-500 hover:text-white p-2 rounded-xl shadow-sm transition-all" title="Rechazar"><i data-lucide="thumbs-down" class="w-4 h-4"></i></button>
|
||||
`;
|
||||
} else if(b.status === 'accepted') {
|
||||
actions = `<button onclick="openConvertModal(${b.id})" class="bg-emerald-500 text-white px-3 py-1.5 rounded font-black text-[10px] uppercase tracking-widest shadow-md hover:bg-emerald-600">Crear Servicio</button>`;
|
||||
} else if((b.status === 'accepted' || b.status === 'paid') && !isExpired) {
|
||||
// El botón de crear servicio aparece tanto si está aceptado por firma como si ya está PAGADO
|
||||
actions = `<button onclick="openConvertModal(${b.id})" class="bg-emerald-500 text-white px-4 py-2 rounded-xl font-black text-[10px] uppercase tracking-widest shadow-md hover:bg-emerald-600 transition-all active:scale-95">Crear Servicio</button>`;
|
||||
}
|
||||
|
||||
// Botón de PDF
|
||||
actions += `<button onclick="generatePDF(${b.id})" class="text-slate-400 hover:text-blue-600 p-2 ml-2 transition-colors" title="Descargar PDF"><i data-lucide="file-text" class="w-4 h-4"></i></button>`;
|
||||
|
||||
// Botón de Borrar
|
||||
actions += `<button onclick="deleteBudget(${b.id}, '${b.status}', ${isAnulado})" class="text-slate-300 hover:text-red-500 p-2 ml-2 transition-colors" title="Borrar Presupuesto"><i data-lucide="trash-2" class="w-4 h-4"></i></button>`;
|
||||
// Botones fijos (PDF y Borrar)
|
||||
let utilityButtons = `
|
||||
<button onclick="generatePDF(${b.id})" class="text-slate-400 hover:text-blue-600 p-2 transition-colors" title="Descargar PDF"><i data-lucide="file-text" class="w-5 h-5"></i></button>
|
||||
<button onclick="deleteBudget(${b.id}, '${b.status}', ${isAnulado})" class="text-slate-300 hover:text-red-500 p-2 transition-colors" title="Borrar"><i data-lucide="trash-2" class="w-5 h-5"></i></button>
|
||||
`;
|
||||
|
||||
list.innerHTML += `
|
||||
<div class="grid grid-cols-12 gap-4 p-4 items-center hover:bg-slate-50 transition-colors">
|
||||
<div class="grid grid-cols-12 gap-4 p-5 items-center hover:bg-slate-50/50 transition-colors border-b border-slate-100">
|
||||
<div class="col-span-4 pl-2 min-w-0">
|
||||
<p class="text-xs font-black text-slate-800 uppercase truncate">
|
||||
<span class="text-blue-500 mr-1 tracking-widest">#PRE-${b.id}</span> ${b.client_name}
|
||||
<p class="text-sm font-black text-slate-800 uppercase truncate">
|
||||
<span class="text-blue-500 mr-1 tracking-tighter">#PRE-${b.id}</span> ${b.client_name}
|
||||
</p>
|
||||
<p class="text-[10px] font-bold text-slate-400 mt-1 flex items-center gap-2">
|
||||
<span><i data-lucide="calendar" class="w-3 h-3 inline"></i> ${dateDisplay}</span>
|
||||
<span>•</span>
|
||||
<span><i data-lucide="phone" class="w-3 h-3 inline"></i> ${b.client_phone}</span>
|
||||
</p>
|
||||
<p class="text-[10px] font-bold text-slate-400 mt-0.5"><i data-lucide="calendar" class="w-3 h-3 inline"></i> ${date} - 📞 ${b.client_phone}</p>
|
||||
</div>
|
||||
<div class="col-span-3 min-w-0"><p class="text-[10px] text-slate-500 truncate">${b.client_address}</p></div>
|
||||
<div class="col-span-2 text-center"><p class="text-sm font-black text-slate-800">${b.total}€</p></div>
|
||||
<div class="col-span-3 flex justify-center items-center gap-2">${bStatus} ${actions}</div>
|
||||
<div class="col-span-3 min-w-0">
|
||||
<p class="text-[11px] text-slate-500 font-medium truncate italic">${b.client_address || 'Sin dirección'}</p>
|
||||
</div>
|
||||
<div class="col-span-2 text-center">
|
||||
<p class="text-base font-black text-slate-700">${parseFloat(b.total).toFixed(2)}€</p>
|
||||
</div>
|
||||
<div class="col-span-3 flex justify-end items-center gap-3 pr-4">
|
||||
<div class="shrink-0">${bStatus}</div>
|
||||
<div class="flex items-center gap-1">${actions} ${utilityButtons}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user