feat: client cascade delete with dependency counts
This commit is contained in:
@@ -110,11 +110,66 @@ pub fn update_client(state: State<AppState>, client: Client) -> Result<(), Strin
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn get_client_dependents(state: State<AppState>, client_id: i64) -> Result<serde_json::Value, String> {
|
||||||
|
let conn = state.db.lock().map_err(|e| e.to_string())?;
|
||||||
|
let project_count: i64 = conn.query_row(
|
||||||
|
"SELECT COUNT(*) FROM projects WHERE client_id = ?1", params![client_id], |row| row.get(0)
|
||||||
|
).map_err(|e| e.to_string())?;
|
||||||
|
let invoice_count: i64 = conn.query_row(
|
||||||
|
"SELECT COUNT(*) FROM invoices WHERE client_id = ?1", params![client_id], |row| row.get(0)
|
||||||
|
).map_err(|e| e.to_string())?;
|
||||||
|
let expense_count: i64 = conn.query_row(
|
||||||
|
"SELECT COUNT(*) FROM expenses WHERE client_id = ?1", params![client_id], |row| row.get(0)
|
||||||
|
).map_err(|e| e.to_string())?;
|
||||||
|
Ok(serde_json::json!({
|
||||||
|
"projects": project_count,
|
||||||
|
"invoices": invoice_count,
|
||||||
|
"expenses": expense_count
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn delete_client(state: State<AppState>, id: i64) -> Result<(), String> {
|
pub fn delete_client(state: State<AppState>, id: i64) -> Result<(), String> {
|
||||||
let conn = state.db.lock().map_err(|e| e.to_string())?;
|
let conn = state.db.lock().map_err(|e| e.to_string())?;
|
||||||
conn.execute("DELETE FROM clients WHERE id = ?1", params![id]).map_err(|e| e.to_string())?;
|
|
||||||
Ok(())
|
conn.execute_batch("BEGIN TRANSACTION").map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
|
let result = (|| -> Result<(), rusqlite::Error> {
|
||||||
|
let project_ids: Vec<i64> = {
|
||||||
|
let mut stmt = conn.prepare("SELECT id FROM projects WHERE client_id = ?1")?;
|
||||||
|
let rows = stmt.query_map(params![id], |row| row.get(0))?;
|
||||||
|
rows.filter_map(|r| r.ok()).collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
for pid in &project_ids {
|
||||||
|
conn.execute("DELETE FROM entry_tags WHERE entry_id IN (SELECT id FROM time_entries WHERE project_id = ?1)", params![pid])?;
|
||||||
|
conn.execute("DELETE FROM time_entries WHERE project_id = ?1", params![pid])?;
|
||||||
|
conn.execute("DELETE FROM tasks WHERE project_id = ?1", params![pid])?;
|
||||||
|
conn.execute("DELETE FROM tracked_apps WHERE project_id = ?1", params![pid])?;
|
||||||
|
conn.execute("DELETE FROM favorites WHERE project_id = ?1", params![pid])?;
|
||||||
|
conn.execute("DELETE FROM recurring_entries WHERE project_id = ?1", params![pid])?;
|
||||||
|
conn.execute("DELETE FROM timeline_events WHERE project_id = ?1", params![pid])?;
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.execute("DELETE FROM expenses WHERE client_id = ?1", params![id])?;
|
||||||
|
conn.execute("DELETE FROM invoice_items WHERE invoice_id IN (SELECT id FROM invoices WHERE client_id = ?1)", params![id])?;
|
||||||
|
conn.execute("DELETE FROM invoices WHERE client_id = ?1", params![id])?;
|
||||||
|
conn.execute("DELETE FROM projects WHERE client_id = ?1", params![id])?;
|
||||||
|
conn.execute("DELETE FROM clients WHERE id = ?1", params![id])?;
|
||||||
|
Ok(())
|
||||||
|
})();
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(()) => {
|
||||||
|
conn.execute_batch("COMMIT").map_err(|e| e.to_string())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
conn.execute_batch("ROLLBACK").ok();
|
||||||
|
Err(e.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Project commands
|
// Project commands
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ pub fn run() {
|
|||||||
commands::create_client,
|
commands::create_client,
|
||||||
commands::update_client,
|
commands::update_client,
|
||||||
commands::delete_client,
|
commands::delete_client,
|
||||||
|
commands::get_client_dependents,
|
||||||
commands::get_projects,
|
commands::get_projects,
|
||||||
commands::create_project,
|
commands::create_project,
|
||||||
commands::update_project,
|
commands::update_project,
|
||||||
|
|||||||
Reference in New Issue
Block a user