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::now().date_naive().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.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 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.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
}
}