use std::sync::Arc; use axum::{ Json, extract::{Path, State}, http::StatusCode, response::IntoResponse, }; use serde_json::json; use sqlx::query; use crate::{ AppState, models::{Ticket, TicketCreateScheme, TicketResponse, TicketUpdateScheme}, }; pub async fn create_ticket( State(data): State>, Json(body): Json, ) -> Result)> { let query = query( r#"INSERT INTO tickets (category, description, betreff, room) VALUES ($1, $2, $3, $4)"#, ) .bind(body.category.to_string()) .bind(body.description.to_string()) .bind(body.betreff.to_string()) .bind(body.room) .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_as::<_, Ticket>( r#"SELECT * FROM tickets WHERE status <> 'Archived' ORDER BY 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 = tickets .iter() .map(|ticket| filter_record(&ticket)) .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_as::<_, Ticket>(r#"SELECT * FROM tickets WHERE id = $1"#) .bind(id) .fetch_one(&data.db) .await; match query { Ok(ticket) => { let ticket_response = serde_json::json!(filter_record(&ticket)); return Ok(Json(ticket_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_as::<_, Ticket>(r#"SELECT * FROM tickets WHERE 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 = serde_json::json!({ "ticket": filter_record(&updated_ticket), "status": "success" }); Ok(Json(ticket_response)) } fn filter_record(ticket: &Ticket) -> TicketResponse { TicketResponse { id: ticket.id.to_owned(), category: ticket.category.to_owned(), betreff: ticket.betreff.to_owned(), description: ticket.description.to_owned(), room: ticket.room.to_owned(), status: ticket.status.to_owned(), date: ticket.date.to_owned(), user_id: ticket.user_id.to_owned(), } }