use hyper::header::CONTENT_TYPE; use hyper::{Body, Response}; use std::collections::HashMap; use tera::Context; use crate::controller::utils; use crate::controller::wallet::Wallet; use crate::db; use crate::model::frequency::Frequency; use crate::queries; use crate::templates; use crate::validation; static PER_PAGE: i64 = 10; pub async fn table( wallet: &Wallet, query: queries::Payments, ) -> Response { let page = query.page.unwrap_or(1); let count = db::payments::count(&wallet.pool, &query).await; let payments = db::payments::list_for_table(&wallet.pool, &query, PER_PAGE).await; let max_page = (count.count as f32 / PER_PAGE as f32).ceil() as i64; let users = db::users::list(&wallet.pool).await; let categories = db::categories::list(&wallet.pool).await; let mut context = Context::new(); context.insert("header", &templates::Header::Payments); context.insert("connected_user", &wallet.user); context.insert("payments", &payments); context.insert("page", &page); context.insert("max_page", &max_page); context.insert("query", &query); context.insert("count", &count.count); context.insert("total_cost", &count.total_cost); context.insert("users", &users); context.insert("categories", &categories); utils::template( &wallet.assets, &wallet.templates, "payment/table.html", context, ) } pub async fn create_form( wallet: &Wallet, query: queries::Payments, ) -> Response { create_form_feedback(wallet, query, HashMap::new(), None).await } async fn create_form_feedback( wallet: &Wallet, query: queries::Payments, form: HashMap, error: Option, ) -> Response { let users = db::users::list(&wallet.pool).await; let categories = db::categories::list(&wallet.pool).await; let mut context = Context::new(); context.insert("header", &templates::Header::Payments); context.insert("connected_user", &wallet.user); context.insert("users", &users); context.insert("categories", &categories); context.insert("query", &query); context.insert("form", &form); context.insert("error", &error); utils::template( &wallet.assets, &wallet.templates, "payment/create.html", context, ) } pub async fn create( wallet: &Wallet, query: queries::Payments, form: HashMap, ) -> Response { let error = |e: &str| { create_form_feedback(wallet, query, form.clone(), Some(e.to_string())) }; match validation::payment::create(&form) { Some(create_payment) => { match db::payments::create(&wallet.pool, &create_payment).await { Some(id) => { let row = db::payments::get_row( &wallet.pool, id, create_payment.frequency, ) .await; let page = (row - 1) / PER_PAGE + 1; let query = queries::Payments { page: Some(page), name: None, cost: None, frequency: Some(create_payment.frequency), highlight: Some(id), user: None, category: None, start_date: None, end_date: None, }; utils::redirect(&format!( "/{}", queries::payments_url(query) )) } None => error("Erreur serveur.").await, } } None => error("Erreur lors de la validation du formulaire.").await, } } pub async fn update_form( id: i64, wallet: &Wallet, query: queries::Payments, ) -> Response { update_form_feedback(id, wallet, query, HashMap::new(), None).await } async fn update_form_feedback( id: i64, wallet: &Wallet, query: queries::Payments, form: HashMap, error: Option, ) -> Response { let payment = db::payments::get_for_form(&wallet.pool, id).await; let users = db::users::list(&wallet.pool).await; let categories = db::categories::list(&wallet.pool).await; let mut context = Context::new(); context.insert("header", &templates::Header::Payments); context.insert("connected_user", &wallet.user); context.insert("id", &id); context.insert("payment", &payment); context.insert("users", &users); context.insert("categories", &categories); context.insert("query", &query); context.insert("form", &form); context.insert("error", &error); utils::template( &wallet.assets, &wallet.templates, "payment/update.html", context, ) } pub async fn update( id: i64, wallet: &Wallet, query: queries::Payments, form: HashMap, ) -> Response { let error = |e: &str| { update_form_feedback( id, wallet, query.clone(), form.clone(), Some(e.to_string()), ) }; match validation::payment::update(&form) { Some(update_payment) => { if db::payments::update(&wallet.pool, id, &update_payment).await { let frequency = query.frequency.unwrap_or(Frequency::Punctual); let row = db::payments::get_row(&wallet.pool, id, frequency).await; let page = (row - 1) / PER_PAGE + 1; // TODO: keep name, cost, user and category when updating a line let query = queries::Payments { page: Some(page), name: None, cost: None, frequency: Some(frequency), highlight: Some(id), user: None, category: None, start_date: None, end_date: None, }; utils::redirect(&format!("/{}", queries::payments_url(query))) } else { error("Erreur serveur").await } } None => error("Erreur lors de la validation du formulaire.").await, } } pub async fn delete( id: i64, wallet: &Wallet, query: queries::Payments, ) -> Response { if db::payments::delete(&wallet.pool, id).await { let query = queries::Payments { highlight: None, ..query }; utils::redirect(&format!("/{}", queries::payments_url(query))) } else { update_form_feedback( id, wallet, query, HashMap::new(), Some("Erreur serveur".to_string()), ) .await } } pub async fn search_category( wallet: &Wallet, query: queries::PaymentCategory, ) -> Response { match db::payments::search_category(&wallet.pool, query.payment_name).await { Some(category_id) => utils::with_headers( Response::new(format!("{}", category_id).into()), vec![(CONTENT_TYPE, "application/json")], ), None => utils::not_found(), } }