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_header(
Response::new(format!("{}", category_id).into()),
CONTENT_TYPE,
"application/json",
),
None => utils::not_found(),
}
}