use std::sync::Arc; use axum::{ Extension, Json, extract::{Path, State}, http::StatusCode, response::IntoResponse, }; use serde_json::json; use sqlx::{Row, query}; use crate::{ AppState, models::{FilteredUser, TicketCreateScheme, TicketResponse, TicketUpdateScheme}, }; pub async fn create_ticket( Extension(user): Extension, State(data): State>, Json(body): Json, ) -> Result)> { let query = query( r#"INSERT INTO tickets (category, description, betreff, room, user_id) VALUES ($1, $2, $3, $4, $5)"#, ) .bind(body.category.to_string()) .bind(body.description.to_string()) .bind(body.betreff.to_string()) .bind(body.room) .bind(user.id) .execute(&data.db) .await; if let Err(err) = query { return Err(( StatusCode::INTERNAL_SERVER_ERROR, Json(json!({"status": "error", "message": format!("{:?}", err),})), )); } let response_status = serde_json::json!({"status": "success"}); Ok(Json(response_status)) } pub async fn delete_ticket( Path(id): Path, State(data): State>, ) -> Result)> { let query = sqlx::query(r#"DELETE FROM tickets WHERE id = $1"#) .bind(id) .execute(&data.db) .await .map_err(|e| { ( StatusCode::INTERNAL_SERVER_ERROR, Json(json!({"status": "error", "message": format!("{:?}", e)})), ) })?; if query.rows_affected() == 0 { let error_response = serde_json::json!({ "status": "error", "message": format!("Ticket with ID {} not found", id) }); return Err((StatusCode::NOT_FOUND, Json(error_response))); } Ok(StatusCode::NO_CONTENT) } pub async fn get_tickets( State(data): State>, ) -> Result)> { println!("get_tickets called"); let tickets = sqlx::query( r#"SELECT t.id, t.category, t.betreff, t.description, t.room, t.status, t.date, t.user_id, u.first_name, u.last_name FROM tickets t LEFT JOIN users u ON t.user_id = u.id WHERE t.status <> 'Archived' ORDER BY t.date DESC"#, ) .fetch_all(&data.db) .await .map_err(|e| { let error_response = serde_json::json!({ "status": "error", "message": format!("Database error: {}", e), }); (StatusCode::INTERNAL_SERVER_ERROR, Json(error_response)) })?; println!("Tickets fetched"); let ticket_response: Vec = tickets .iter() .map(|row| TicketResponse { id: row.get("id"), category: row.get("category"), betreff: row.get("betreff"), description: row.get("description"), room: row.get("room"), status: row.get("status"), date: row.get("date"), user_id: row.get("user_id"), user_first_name: row.get("first_name"), user_last_name: row.get("last_name"), }) .collect(); let json_response = serde_json::json!(ticket_response); println!("Json contructed"); Ok(Json(json_response)) } pub async fn get_ticket_by_id( Path(id): Path, State(data): State>, ) -> Result)> { let query = sqlx::query( r#"SELECT t.id, t.category, t.betreff, t.description, t.room, t.status, t.date, t.user_id, u.first_name, u.last_name FROM tickets t LEFT JOIN users u ON t.user_id = u.id WHERE t.id = $1"#, ) .bind(id) .fetch_one(&data.db) .await; match query { Ok(row) => { let ticket_response = TicketResponse { id: row.get("id"), category: row.get("category"), betreff: row.get("betreff"), description: row.get("description"), room: row.get("room"), status: row.get("status"), date: row.get("date"), user_id: row.get("user_id"), user_first_name: row.get("first_name"), user_last_name: row.get("last_name"), }; let response = serde_json::json!(ticket_response); return Ok(Json(response)); } Err(sqlx::Error::RowNotFound) => { let error_response = serde_json::json!({ "status": "fail", "message": format!("Ticket with ID {} not found", id) }); return Err((StatusCode::NOT_FOUND, Json(error_response))); } Err(e) => { return Err(( StatusCode::INTERNAL_SERVER_ERROR, Json(json!({"status": "error", "message": format!("{:?}", e)})), )); } }; } pub async fn edit_ticket( Path(id): Path, State(data): State>, Json(body): Json, ) -> Result)> { let update_result = sqlx::query(r#"UPDATE tickets SET status = $1 WHERE id = $2"#) .bind(body.status.to_owned()) .bind(id) .execute(&data.db) .await .map_err(|e| { ( StatusCode::INTERNAL_SERVER_ERROR, Json(json!({"status": "error", "message": format!("{:?}", e)})), ) })?; if update_result.rows_affected() == 0 { let error_response = serde_json::json!({ "status": "error", "message": format!("Ticket with ID {} not found", id) }); return Err((StatusCode::INTERNAL_SERVER_ERROR, Json(error_response))); } let updated_ticket = sqlx::query( r#"SELECT t.id, t.category, t.betreff, t.description, t.room, t.status, t.date, t.user_id, u.first_name, u.last_name FROM tickets t LEFT JOIN users u ON t.user_id = u.id WHERE t.id = $1"#, ) .bind(id) .fetch_one(&data.db) .await .map_err(|e| { ( StatusCode::INTERNAL_SERVER_ERROR, Json(json!({"status": "error", "message": format!("{:?}", e)})), ) })?; let ticket_response = TicketResponse { id: updated_ticket.get("id"), category: updated_ticket.get("category"), betreff: updated_ticket.get("betreff"), description: updated_ticket.get("description"), room: updated_ticket.get("room"), status: updated_ticket.get("status"), date: updated_ticket.get("date"), user_id: updated_ticket.get("user_id"), user_first_name: updated_ticket.get("first_name"), user_last_name: updated_ticket.get("last_name"), }; let response = serde_json::json!({ "ticket": ticket_response, "status": "success" }); Ok(Json(response)) }