Get accounts and balances
This commit is contained in:
		@@ -1,8 +1,9 @@
 | 
			
		||||
use crate::controllers::HttpResult;
 | 
			
		||||
use crate::extractors::account_extractor::AccountInPath;
 | 
			
		||||
use crate::extractors::auth_extractor::AuthExtractor;
 | 
			
		||||
use crate::services::accounts_service;
 | 
			
		||||
use crate::models::accounts::Account;
 | 
			
		||||
use crate::services::accounts_service::UpdateAccountQuery;
 | 
			
		||||
use crate::services::{accounts_service, movements_service};
 | 
			
		||||
use actix_web::{HttpResponse, web};
 | 
			
		||||
 | 
			
		||||
/// Create a new account
 | 
			
		||||
@@ -16,9 +17,38 @@ pub async fn create(auth: AuthExtractor, req: web::Json<UpdateAccountQuery>) ->
 | 
			
		||||
    Ok(HttpResponse::Created().finish())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Deserialize)]
 | 
			
		||||
pub struct GetListQuery {
 | 
			
		||||
    #[serde(default)]
 | 
			
		||||
    include_balances: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Serialize)]
 | 
			
		||||
struct AccountAndBalance {
 | 
			
		||||
    #[serde(flatten)]
 | 
			
		||||
    account: Account,
 | 
			
		||||
    balance: f32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get the list of accounts of the user
 | 
			
		||||
pub async fn get_list(auth: AuthExtractor) -> HttpResult {
 | 
			
		||||
    Ok(HttpResponse::Ok().json(accounts_service::get_list_user(auth.user_id()).await?))
 | 
			
		||||
pub async fn get_list(auth: AuthExtractor, query: web::Query<GetListQuery>) -> HttpResult {
 | 
			
		||||
    let accounts = accounts_service::get_list_user(auth.user_id()).await?;
 | 
			
		||||
 | 
			
		||||
    Ok(match query.include_balances {
 | 
			
		||||
        false => HttpResponse::Ok().json(accounts),
 | 
			
		||||
        true => {
 | 
			
		||||
            let balances = movements_service::get_balances(auth.user_id()).await?;
 | 
			
		||||
            let accounts = accounts
 | 
			
		||||
                .into_iter()
 | 
			
		||||
                .map(|account| AccountAndBalance {
 | 
			
		||||
                    balance: *balances.get(&account.id()).unwrap_or(&0.0),
 | 
			
		||||
                    account,
 | 
			
		||||
                })
 | 
			
		||||
                .collect::<Vec<_>>();
 | 
			
		||||
 | 
			
		||||
            HttpResponse::Ok().json(accounts)
 | 
			
		||||
        }
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get a single account
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,11 @@ pub async fn create(auth: AuthExtractor, req: web::Json<UpdateMovementQuery>) ->
 | 
			
		||||
    Ok(HttpResponse::Created().finish())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get the balances of all the accounts of the user
 | 
			
		||||
pub async fn get_accounts_balances(auth: AuthExtractor) -> HttpResult {
 | 
			
		||||
    Ok(HttpResponse::Ok().json(movements_service::get_balances(auth.user_id()).await?))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get the list of movements of an account
 | 
			
		||||
pub async fn get_list_of_account(account_id: AccountInPath) -> HttpResult {
 | 
			
		||||
    Ok(HttpResponse::Ok()
 | 
			
		||||
 
 | 
			
		||||
@@ -131,6 +131,10 @@ async fn main() -> std::io::Result<()> {
 | 
			
		||||
            )
 | 
			
		||||
            // Movement controller
 | 
			
		||||
            .route("/api/movement", web::post().to(movement_controller::create))
 | 
			
		||||
            .route(
 | 
			
		||||
                "/api/accounts/balances",
 | 
			
		||||
                web::get().to(movement_controller::get_accounts_balances),
 | 
			
		||||
            )
 | 
			
		||||
            .route(
 | 
			
		||||
                "/api/account/{account_id}/movements",
 | 
			
		||||
                web::get().to(movement_controller::get_list_of_account),
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,9 @@ use crate::schema::*;
 | 
			
		||||
use diesel::prelude::*;
 | 
			
		||||
use std::fmt::{Display, Formatter};
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
 | 
			
		||||
#[derive(
 | 
			
		||||
    Debug, Clone, Copy, serde::Serialize, serde::Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord,
 | 
			
		||||
)]
 | 
			
		||||
pub struct AccountID(pub i32);
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
 | 
			
		||||
 
 | 
			
		||||
@@ -7,8 +7,9 @@ use crate::models::users::UserID;
 | 
			
		||||
use crate::schema::movements;
 | 
			
		||||
use crate::services::{accounts_service, files_service};
 | 
			
		||||
use crate::utils::time_utils::time;
 | 
			
		||||
use diesel::RunQueryDsl;
 | 
			
		||||
use diesel::prelude::*;
 | 
			
		||||
use diesel::{RunQueryDsl, sql_query};
 | 
			
		||||
use std::collections::HashMap;
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Deserialize)]
 | 
			
		||||
pub struct UpdateMovementQuery {
 | 
			
		||||
@@ -136,6 +137,31 @@ pub async fn get_list_account(account_id: AccountID) -> anyhow::Result<Vec<Movem
 | 
			
		||||
        .get_results(&mut db()?)?)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
table! {
 | 
			
		||||
    accounts_balances (account_id) {
 | 
			
		||||
        account_id -> Int4,
 | 
			
		||||
        balance -> Float4,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(QueryableByName)]
 | 
			
		||||
#[diesel(table_name = accounts_balances)]
 | 
			
		||||
struct AccountBalance {
 | 
			
		||||
    account_id: i32,
 | 
			
		||||
    balance: f32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get the balances of all the accounts of the user
 | 
			
		||||
pub async fn get_balances(user_id: UserID) -> anyhow::Result<HashMap<AccountID, f32>> {
 | 
			
		||||
    let result = sql_query(format!("select a.id as account_id, sum(m.amount) as balance from accounts a right join movements m on a.id = m.account_id where a.user_id = {} group by a.id", user_id.0))
 | 
			
		||||
        .get_results::<AccountBalance>(&mut db()?)?;
 | 
			
		||||
 | 
			
		||||
    Ok(result
 | 
			
		||||
        .into_iter()
 | 
			
		||||
        .map(|r| (AccountID(r.account_id), r.balance))
 | 
			
		||||
        .collect())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Delete a movement
 | 
			
		||||
pub async fn delete(id: MovementID) -> anyhow::Result<()> {
 | 
			
		||||
    diesel::delete(movements::dsl::movements.filter(movements::dsl::id.eq(id.0)))
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user