feat(customers): show vehicles and delete customer
- get_customer now returns fleet_vehicles assigned to the customer. - Added DELETE /pos/api/customers/<id> soft-delete (is_active=false) with customers.delete permission. - Added Vehicles section in customer detail panel. - Added Eliminar button in quick actions (owner/admin/customers.delete).
This commit is contained in:
@@ -11,6 +11,11 @@ const Customers = (() => {
|
||||
let currentCustomer = null;
|
||||
let searchTimeout = null;
|
||||
|
||||
const user = window.POS_USER || {};
|
||||
const userRole = (user.role || '').toLowerCase();
|
||||
const userPerms = user.permissions || [];
|
||||
const canDeleteCustomer = userRole === 'owner' || userRole === 'admin' || userPerms.includes('customers.delete');
|
||||
|
||||
const fmt = (n) => '$' + parseFloat(n || 0).toLocaleString('es-MX', {
|
||||
minimumFractionDigits: 2, maximumFractionDigits: 2
|
||||
});
|
||||
@@ -295,6 +300,28 @@ const Customers = (() => {
|
||||
const discountEl = document.getElementById('detailMaxDiscount');
|
||||
if (discountEl) discountEl.textContent = (c.max_discount_pct || 0) + '%';
|
||||
|
||||
// Vehicles
|
||||
const vehiclesEl = document.getElementById('detailVehicles');
|
||||
if (vehiclesEl) {
|
||||
const vehicles = c.fleet_vehicles || [];
|
||||
if (vehicles.length === 0) {
|
||||
vehiclesEl.innerHTML = '<span style="color:var(--color-text-muted);">Sin vehículos registrados</span>';
|
||||
} else {
|
||||
vehiclesEl.innerHTML = vehicles.map(v => {
|
||||
const title = [v.year, v.make, v.model].filter(Boolean).join(' ');
|
||||
const subtitle = [v.plate, v.vin, v.color].filter(Boolean).join(' · ');
|
||||
return `<div class="vehicle-row" style="padding:var(--space-2);border:1px solid var(--color-border);border-radius:var(--radius-md);">
|
||||
<div style="font-weight:600;">${title || 'Vehículo'}</div>
|
||||
<div style="font-size:var(--text-caption);color:var(--color-text-muted);">${subtitle}</div>
|
||||
</div>`;
|
||||
}).join('');
|
||||
}
|
||||
}
|
||||
|
||||
// Delete button visibility
|
||||
const btnDelete = document.getElementById('btnDeleteCustomer');
|
||||
if (btnDelete) btnDelete.style.display = canDeleteCustomer ? 'inline-flex' : 'none';
|
||||
|
||||
// Re-wire action buttons after detail panel is visible
|
||||
wireActionButtons();
|
||||
|
||||
@@ -396,7 +423,7 @@ const Customers = (() => {
|
||||
// Wire action buttons in detail panel
|
||||
function wireActionButtons() {
|
||||
const btns = document.querySelectorAll('.quick-actions .action-btn');
|
||||
// Order: Nueva Venta, Editar, Estado de Cuenta, Historial
|
||||
// Order: Nueva Venta, Editar, Estado de Cuenta, Historial, Eliminar
|
||||
if (btns.length >= 1) btns[0].onclick = () => {
|
||||
if (currentCustomer) window.location.href = '/pos/sale?customer=' + currentCustomer.id;
|
||||
};
|
||||
@@ -405,8 +432,29 @@ const Customers = (() => {
|
||||
if (btns.length >= 4) btns[3].onclick = () => {
|
||||
if (currentCustomer) showCustomerHistory(currentCustomer.id);
|
||||
};
|
||||
const btnDelete = document.getElementById('btnDeleteCustomer');
|
||||
if (btnDelete) btnDelete.onclick = () => deleteCustomer();
|
||||
}
|
||||
|
||||
async function deleteCustomer() {
|
||||
if (!currentCustomer) return;
|
||||
if (!canDeleteCustomer) {
|
||||
alert('No tienes permiso para eliminar clientes');
|
||||
return;
|
||||
}
|
||||
if (!confirm(`¿Eliminar al cliente "${currentCustomer.name}"? Se marcará como inactivo.`)) return;
|
||||
try {
|
||||
await api(`/pos/api/customers/${currentCustomer.id}`, { method: 'DELETE' });
|
||||
alert('Cliente eliminado');
|
||||
currentCustomer = null;
|
||||
closeDetail();
|
||||
loadCustomers(currentPage);
|
||||
} catch (e) {
|
||||
alert('Error: ' + e.message);
|
||||
}
|
||||
}
|
||||
window.deleteCustomer = deleteCustomer;
|
||||
|
||||
async function showCustomerHistory(customerId) {
|
||||
try {
|
||||
const res = await api(`/pos/api/customers/${customerId}/purchases`);
|
||||
@@ -906,6 +954,7 @@ const Customers = (() => {
|
||||
showStatement, closeStatement,
|
||||
showPaymentModal, closePayment, recordPayment,
|
||||
showCustomerHistory, closeCustomerHistoryModal,
|
||||
deleteCustomer,
|
||||
};
|
||||
|
||||
// Register Cmd+K items
|
||||
|
||||
Reference in New Issue
Block a user