aboutsummaryrefslogtreecommitdiff
path: root/src/controller/incomes.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/controller/incomes.rs')
-rw-r--r--src/controller/incomes.rs221
1 files changed, 221 insertions, 0 deletions
diff --git a/src/controller/incomes.rs b/src/controller/incomes.rs
new file mode 100644
index 0000000..ea7f1cf
--- /dev/null
+++ b/src/controller/incomes.rs
@@ -0,0 +1,221 @@
+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<Body> {
+ 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<Body> {
+ create_form_feedback(wallet, query, HashMap::new(), None).await
+}
+
+async fn create_form_feedback(
+ wallet: &Wallet,
+ query: queries::Incomes,
+ form: HashMap<String, String>,
+ error: Option<String>,
+) -> Response<Body> {
+ 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<String, String>,
+) -> Response<Body> {
+ 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<Body> {
+ update_form_feedback(id, wallet, query, HashMap::new(), None).await
+}
+
+async fn update_form_feedback(
+ id: i64,
+ wallet: &Wallet,
+ query: queries::Incomes,
+ form: HashMap<String, String>,
+ error: Option<String>,
+) -> Response<Body> {
+ 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<String, String>,
+) -> Response<Body> {
+ 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<Body> {
+ 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
+ }
+}