feat(workshop): allow admin/owner to delete service orders
- Soft-delete service orders via is_deleted flag. - Added DELETE /pos/api/service-orders/<id> restricted to owner/admin. - Updated list, detail, summary, status and assignment queries to exclude deleted orders. - Added 'Eliminar orden' button in the detail modal for administrators.
This commit is contained in:
@@ -115,7 +115,7 @@ def get_service_order(conn, so_id):
|
||||
LEFT JOIN employees creator ON so.created_by = creator.id
|
||||
LEFT JOIN branches b ON so.branch_id = b.id
|
||||
LEFT JOIN couriers co ON so.courier_id = co.id
|
||||
WHERE so.id = %s
|
||||
WHERE so.id = %s AND so.is_deleted = false
|
||||
""", (so_id,))
|
||||
row = cur.fetchone()
|
||||
if not row:
|
||||
@@ -242,7 +242,8 @@ def list_service_orders(conn, status=None, branch_id=None, customer_id=None,
|
||||
where_clauses.append("(so.order_number ILIKE %s OR c.name ILIKE %s OR fv.plate ILIKE %s)")
|
||||
params.extend([f'%{q}%', f'%{q}%', f'%{q}%'])
|
||||
|
||||
where = " AND ".join(where_clauses) if where_clauses else "true"
|
||||
where_clauses.append("so.is_deleted = false")
|
||||
where = " AND ".join(where_clauses)
|
||||
|
||||
cur.execute(f"""
|
||||
SELECT count(*) FROM service_orders so
|
||||
@@ -309,7 +310,7 @@ def list_service_orders(conn, status=None, branch_id=None, customer_id=None,
|
||||
def update_status(conn, so_id, new_status, changed_by=None, notes=None):
|
||||
"""Update service order status with validation."""
|
||||
cur = conn.cursor()
|
||||
cur.execute("SELECT status FROM service_orders WHERE id = %s", (so_id,))
|
||||
cur.execute("SELECT status FROM service_orders WHERE id = %s AND is_deleted = false", (so_id,))
|
||||
row = cur.fetchone()
|
||||
if not row:
|
||||
cur.close()
|
||||
@@ -486,7 +487,7 @@ def get_kanban_summary(conn, branch_id=None):
|
||||
cur.execute(f"""
|
||||
SELECT status, COUNT(*) as cnt
|
||||
FROM service_orders
|
||||
WHERE status != 'cancelled' {branch_filter}
|
||||
WHERE status != 'cancelled' AND is_deleted = false {branch_filter}
|
||||
GROUP BY status
|
||||
""", params)
|
||||
|
||||
@@ -499,6 +500,7 @@ def get_kanban_summary(conn, branch_id=None):
|
||||
SELECT count(*) FROM service_orders
|
||||
WHERE estimated_completion < NOW()
|
||||
AND status NOT IN ('ready', 'delivered', 'cancelled')
|
||||
AND is_deleted = false
|
||||
{branch_filter}
|
||||
""", params)
|
||||
overdue = cur.fetchone()[0]
|
||||
@@ -813,7 +815,7 @@ def convert_to_sale(conn, so_id, sale_data, employee_id=None):
|
||||
def assign_mechanic(conn, so_id, employee_id):
|
||||
"""Assign a mechanic/technician to a service order."""
|
||||
cur = conn.cursor()
|
||||
cur.execute("SELECT id FROM service_orders WHERE id = %s", (so_id,))
|
||||
cur.execute("SELECT id FROM service_orders WHERE id = %s AND is_deleted = false", (so_id,))
|
||||
if not cur.fetchone():
|
||||
cur.close()
|
||||
raise ValueError("Service order not found")
|
||||
@@ -827,6 +829,21 @@ def assign_mechanic(conn, so_id, employee_id):
|
||||
return {"employee_id": employee_id}
|
||||
|
||||
|
||||
def delete_service_order(conn, so_id):
|
||||
"""Soft-delete a service order."""
|
||||
cur = conn.cursor()
|
||||
cur.execute(
|
||||
"UPDATE service_orders SET is_deleted = true WHERE id = %s AND is_deleted = false",
|
||||
(so_id,),
|
||||
)
|
||||
deleted = cur.rowcount
|
||||
conn.commit()
|
||||
cur.close()
|
||||
if deleted == 0:
|
||||
raise ValueError("Service order not found")
|
||||
return {"deleted": True}
|
||||
|
||||
|
||||
# ─── Service catalog (reusable labor concepts) ───────────────────────────────
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user