diff --git a/pos/blueprints/customers_bp.py b/pos/blueprints/customers_bp.py index c571f03..7fe7ad5 100644 --- a/pos/blueprints/customers_bp.py +++ b/pos/blueprints/customers_bp.py @@ -321,7 +321,12 @@ def update_customer(customer_id): @customers_bp.route('/', methods=['DELETE']) @require_auth('customers.delete') def delete_customer(customer_id): - """Soft-delete (deactivate) a customer.""" + """Hard-delete a customer. + + Related records (sales, service orders, vehicles, etc.) keep their data but + lose the customer reference. Layaways for this customer are removed because + they require a customer_id. + """ conn = get_tenant_conn(g.tenant_id) cur = conn.cursor() @@ -330,8 +335,29 @@ def delete_customer(customer_id): cur.close(); conn.close() return jsonify({'error': 'Customer not found'}), 404 - cur.execute("UPDATE customers SET is_active = false WHERE id = %s", (customer_id,)) - log_action(conn, 'CUSTOMER_DEACTIVATE', 'customer', customer_id) + # Remove layaway dependencies first, then the layaways themselves + cur.execute("DELETE FROM layaway_items WHERE layaway_id IN (SELECT id FROM layaways WHERE customer_id = %s)", (customer_id,)) + cur.execute("DELETE FROM layaway_payments WHERE layaway_id IN (SELECT id FROM layaways WHERE customer_id = %s)", (customer_id,)) + cur.execute("DELETE FROM layaways WHERE customer_id = %s", (customer_id,)) + + # Nullify every other FK reference back to customers. + cur.execute(""" + SELECT c.relname::text AS tbl, a.attname::text AS col + FROM pg_constraint con + JOIN pg_class c ON c.oid = con.conrelid + JOIN pg_attribute a ON a.attrelid = con.conrelid AND a.attnum = ANY(con.conkey) + WHERE con.confrelid = 'public.customers'::regclass + AND con.contype = 'f' + """) + refs = cur.fetchall() + for tbl, col in refs: + # Cascade-delete tables and already-handled layaways are skipped. + if tbl in ('customer_activities', 'customer_tag_assignments', 'loyalty_points', 'loyalty_redemptions', 'layaways'): + continue + cur.execute(f'UPDATE "{tbl}" SET "{col}" = NULL WHERE "{col}" = %s', (customer_id,)) + + cur.execute("DELETE FROM customers WHERE id = %s", (customer_id,)) + log_action(conn, 'CUSTOMER_DELETE', 'customer', customer_id) conn.commit() cur.close() conn.close() diff --git a/pos/static/js/customers.js b/pos/static/js/customers.js index e2c17d0..279fc59 100644 --- a/pos/static/js/customers.js +++ b/pos/static/js/customers.js @@ -442,7 +442,7 @@ const Customers = (() => { alert('No tienes permiso para eliminar clientes'); return; } - if (!confirm(`¿Eliminar al cliente "${currentCustomer.name}"? Se marcará como inactivo.`)) return; + if (!confirm(`¿Eliminar al cliente "${currentCustomer.name}"? Se borrará completamente. Las ventas, órdenes y vehículos conservarán sus datos pero quedarán sin cliente asignado.`)) return; try { await api(`/pos/api/customers/${currentCustomer.id}`, { method: 'DELETE' }); alert('Cliente eliminado');