use chrono::Datelike; use chrono::Utc; 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::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 mut context = Context::new(); context.insert("header", &templates::Header::Incomes); context.insert("connected_user", &wallet.user); context.insert("incomes", &incomes); context.insert("page", &page); context.insert("max_page", &max_page); context.insert("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 mut context = Context::new(); context.insert("header", &templates::Header::Incomes); context.insert("connected_user", &wallet.user); context.insert("users", &users); context.insert("query", &query); context.insert("current_month", &Utc::today().naive_utc().month()); context.insert("months", &MONTHS); context.insert("form", &form); context.insert("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.month, income.year, ) .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 mut context = Context::new(); context.insert("header", &templates::Header::Incomes); context.insert("connected_user", &wallet.user); context.insert("users", &users); context.insert("id", &id); context.insert("income", &income); context.insert("query", &query); context.insert("months", &MONTHS); context.insert("form", &form); context.insert("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.month, income.year, ) .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 } }