Can export data to FinancesManager
This commit is contained in:
		@@ -1,15 +1,18 @@
 | 
			
		||||
use crate::controllers::HttpResult;
 | 
			
		||||
use crate::converters::finances_manager_converter::FinancesManagerFile;
 | 
			
		||||
use crate::converters::finances_manager_converter::{
 | 
			
		||||
    FinancesManagerAccount, FinancesManagerFile, FinancesManagerMovement,
 | 
			
		||||
};
 | 
			
		||||
use crate::extractors::auth_extractor::AuthExtractor;
 | 
			
		||||
use crate::extractors::file_extractor::FileExtractor;
 | 
			
		||||
use crate::models::accounts::AccountType;
 | 
			
		||||
use crate::services::accounts_service::UpdateAccountQuery;
 | 
			
		||||
use crate::services::movements_service::UpdateMovementQuery;
 | 
			
		||||
use crate::services::{accounts_service, movements_service};
 | 
			
		||||
use crate::utils::time_utils::{format_date, time};
 | 
			
		||||
use actix_web::HttpResponse;
 | 
			
		||||
 | 
			
		||||
/// Import data from a [FinancesManager](https://gitlab.com/pierre42100/cpp-financesmanager) file
 | 
			
		||||
pub async fn import_financesmanager(auth: AuthExtractor, file: FileExtractor) -> HttpResult {
 | 
			
		||||
pub async fn finances_manager_import(auth: AuthExtractor, file: FileExtractor) -> HttpResult {
 | 
			
		||||
    let file = FinancesManagerFile::parse(&String::from_utf8_lossy(&file.buff))?;
 | 
			
		||||
 | 
			
		||||
    // Create each account & push the movements independently
 | 
			
		||||
@@ -38,3 +41,38 @@ pub async fn import_financesmanager(auth: AuthExtractor, file: FileExtractor) ->
 | 
			
		||||
 | 
			
		||||
    Ok(HttpResponse::Accepted().finish())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Export data to a [FinancesManager](https://gitlab.com/pierre42100/cpp-financesmanager) file
 | 
			
		||||
pub async fn finances_manager_export(auth: AuthExtractor) -> HttpResult {
 | 
			
		||||
    let accounts = accounts_service::get_list_user(auth.user_id()).await?;
 | 
			
		||||
 | 
			
		||||
    let mut out = FinancesManagerFile { accounts: vec![] };
 | 
			
		||||
 | 
			
		||||
    for account in accounts {
 | 
			
		||||
        let movements = movements_service::get_list_account(account.id()).await?;
 | 
			
		||||
        let mut file_account = FinancesManagerAccount {
 | 
			
		||||
            name: account.name,
 | 
			
		||||
            movements: Vec::with_capacity(movements.len()),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        for movement in movements {
 | 
			
		||||
            file_account.movements.push(FinancesManagerMovement {
 | 
			
		||||
                label: movement.label,
 | 
			
		||||
                time: movement.time as u64,
 | 
			
		||||
                amount: movement.amount,
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        out.accounts.push(file_account);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(HttpResponse::Ok()
 | 
			
		||||
        .insert_header((
 | 
			
		||||
            "Content-Disposition",
 | 
			
		||||
            format!(
 | 
			
		||||
                "attachment; filename=export_{}.finance",
 | 
			
		||||
                format_date(time() as i64)?.replace('/', "-")
 | 
			
		||||
            ),
 | 
			
		||||
        ))
 | 
			
		||||
        .body(out.encode()))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -163,8 +163,12 @@ async fn main() -> std::io::Result<()> {
 | 
			
		||||
            )
 | 
			
		||||
            // Backup controller
 | 
			
		||||
            .route(
 | 
			
		||||
                "/api/backup/financesmanager/import",
 | 
			
		||||
                web::post().to(backup_controller::import_financesmanager),
 | 
			
		||||
                "/api/backup/finances_manager/import",
 | 
			
		||||
                web::post().to(backup_controller::finances_manager_import),
 | 
			
		||||
            )
 | 
			
		||||
            .route(
 | 
			
		||||
                "/api/backup/finances_manager/export",
 | 
			
		||||
                web::get().to(backup_controller::finances_manager_export),
 | 
			
		||||
            )
 | 
			
		||||
            // Static assets
 | 
			
		||||
            .route("/", web::get().to(static_controller::root_index))
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
//! # Time utilities
 | 
			
		||||
 | 
			
		||||
use chrono::Datelike;
 | 
			
		||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
 | 
			
		||||
 | 
			
		||||
/// Get the current time since epoch
 | 
			
		||||
@@ -19,3 +20,15 @@ pub fn unix_to_system_time(time: u64) -> SystemTime {
 | 
			
		||||
pub fn unix_to_http_date(time: u64) -> String {
 | 
			
		||||
    httpdate::fmt_http_date(unix_to_system_time(time))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Format given UNIX time in a simple format
 | 
			
		||||
pub fn format_date(time: i64) -> anyhow::Result<String> {
 | 
			
		||||
    let date = chrono::DateTime::from_timestamp(time, 0).ok_or(anyhow::anyhow!("invalid date"))?;
 | 
			
		||||
 | 
			
		||||
    Ok(format!(
 | 
			
		||||
        "{:0>2}/{:0>2}/{}",
 | 
			
		||||
        date.day(),
 | 
			
		||||
        date.month(),
 | 
			
		||||
        date.year()
 | 
			
		||||
    ))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user