use chrono::Datelike; use chrono::Utc; use http_body_util::Full; use hyper::body::Bytes; use hyper::Response; use std::collections::HashMap; use crate::controller::utils; use crate::controller::wallet::Wallet; use crate::db; use crate::queries; use crate::templates; use crate::validation; static PER_PAGE: i64 = 10; pub async fn table( wallet: &Wallet, query: queries::Incomes, ) -> Response> { let page = query.page.unwrap_or(1); let count = db::incomes::count(&wallet.pool).await; let incomes = db::incomes::list(&wallet.pool, page, PER_PAGE).await; let max_page = (count as f32 / PER_PAGE as f32).ceil() as i64; let context = minijinja::context!( header => templates::Header::Incomes, connected_user => wallet.user, incomes => incomes, page => page, max_page => max_page, highlight => query.highlight ); utils::template( &wallet.assets, &wallet.templates, "income/table.html", context, ) } static MONTHS: [&str; 12] = [ "Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre", ]; pub async fn create_form( wallet: &Wallet, query: queries::Incomes, ) -> Response> { create_form_feedback(wallet, query, HashMap::new(), None).await } async fn create_form_feedback( wallet: &Wallet, query: queries::Incomes, form: HashMap, error: Option, ) -> Response> { let users = db::users::list(&wallet.pool).await; let context = minijinja::context!( header => templates::Header::Incomes, connected_user => wallet.user, users => users, query => query, current_month => Utc::now().date_naive().month(), months => MONTHS, form => form, error => error, ); utils::template( &wallet.assets, &wallet.templates, "income/create.html", context, ) } pub async fn create( wallet: &Wallet, query: queries::Incomes, form: HashMap, ) -> Response> { let error = |e: &str| { create_form_feedback(wallet, query, form.clone(), Some(e.to_string())) }; match validation::income::create(&form) { Some(income) => { if !db::incomes::defined_at( &wallet.pool, income.user_id, income.date, ) .await .is_empty() { error("Un revenu est déjà défini à cette date.").await } else { match db::incomes::create(&wallet.pool, &income).await { Some(id) => { let row = db::incomes::get_row(&wallet.pool, id).await; let page = (row - 1) / PER_PAGE + 1; utils::redirect(&format!( "/incomes?page={}&highlight={}", page, id )) } 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::Incomes, ) -> Response> { update_form_feedback(id, wallet, query, HashMap::new(), None).await } async fn update_form_feedback( id: i64, wallet: &Wallet, query: queries::Incomes, form: HashMap, error: Option, ) -> Response> { let users = db::users::list(&wallet.pool).await; let income = db::incomes::get(&wallet.pool, id).await; let context = minijinja::context!( header => &templates::Header::Incomes, connected_user => &wallet.user, users => &users, id => &id, income => &income, query => &query, months => &MONTHS, form => &form, error => &error ); utils::template( &wallet.assets, &wallet.templates, "income/update.html", context, ) } pub async fn update( id: i64, wallet: &Wallet, query: queries::Incomes, form: HashMap, ) -> Response> { let error = |e: &str| { update_form_feedback( id, wallet, query, form.clone(), Some(e.to_string()), ) }; match validation::income::update(&form) { Some(income) => { let existing_incomes = db::incomes::defined_at( &wallet.pool, income.user_id, income.date, ) .await; if existing_incomes.into_iter().any(|eid| eid != id) { error("Un revenu est déjà défini à cette date.").await } else if db::incomes::update(&wallet.pool, id, &income).await { let row = db::incomes::get_row(&wallet.pool, id).await; let page = (row - 1) / PER_PAGE + 1; utils::redirect(&format!( "/incomes?page={}&highlight={}", page, id )) } 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::Incomes, ) -> Response> { if db::incomes::delete(&wallet.pool, id).await { utils::redirect(&format!("/incomes?page={}", query.page.unwrap_or(1))) } else { update_form_feedback( id, wallet, query, HashMap::new(), Some("Erreur serveur".to_string()), ) .await } }