fix: update DTOs for account and account category with validation and timestamp adjustments

This commit is contained in:
GW_MC
2026-05-27 11:19:27 +00:00
parent 517fb37818
commit 1d5e24bdfb
2 changed files with 35 additions and 9 deletions

View File

@@ -1,13 +1,16 @@
// TODO: validation for all dto
use crate::db::{
Db,
entities::account_category::{
ActiveModel as AccountCategoryActiveModel, Entity as AccountCategoryEntity,
},
Db,
};
use migration::OnConflict;
use sea_orm::{
ActiveModelTrait, ActiveValue::Set, ColumnTrait, ConnectionTrait, DatabaseConnection,
DatabaseTransaction, EntityTrait, IntoActiveModel, ModelTrait, PaginatorTrait, QueryFilter,
ActiveModelTrait, ActiveValue::Set, ColumnTrait, DatabaseConnection, EntityTrait,
IntoActiveModel, ModelTrait, PaginatorTrait, QueryFilter,
};
use serde::{Deserialize, Serialize};
pub struct AccountCategory {
pub id: i64,
@@ -18,17 +21,23 @@ pub struct AccountCategory {
pub updated_at: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AccountType {
Asset, // Positive balance, e.g. Checking, Savings
#[serde(rename = "Asset")]
Asset, // Positive balance, e.g. Checking, Savings
#[serde(rename = "Liability")]
Liability, // Negative balance, e.g. Credit Card
Unknown, // Fallback for unknown types
#[serde(other, rename = "Unknown")]
Unknown, // Fallback for unknown types
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateAccountCategoryRequest {
pub name: String,
pub account_type: AccountType,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UpdateAccountCategoryRequest {
pub name: Option<String>,
pub account_type: Option<AccountType>,
@@ -129,9 +138,20 @@ impl AccountCategoryService for AccountCategoryServiceImpl {
let new_category = AccountCategoryActiveModel {
name: Set(create_request.name),
account_type: Set(create_request.account_type.to_string()),
created_at: Set(chrono::Utc::now().to_rfc3339()),
updated_at: Set(chrono::Utc::now().to_rfc3339()),
..Default::default()
};
let res = new_category.insert(tx).await.map_err(|e| e.to_string())?;
let res = AccountCategoryEntity::insert(new_category)
.on_conflict(
// force update to ensure a record is returned
OnConflict::column(crate::db::entities::account_category::Column::Name)
.update_column(crate::db::entities::account_category::Column::Name)
.to_owned(),
)
.exec_with_returning(tx)
.await
.map_err(|e| e.to_string())?;
Ok(res.id)
}
@@ -187,6 +207,7 @@ impl AccountCategoryService for AccountCategoryServiceImpl {
if let Some(account_type) = update_request.account_type {
category.account_type = Set(account_type.to_string());
}
category.updated_at = Set(chrono::Utc::now().to_rfc3339());
category.update(tx).await.map_err(|e| e.to_string())?;
Ok(())
} else {

View File

@@ -1,3 +1,4 @@
// TODO: validation for all dto
use std::sync::Arc;
use crate::{
@@ -17,9 +18,11 @@ use crate::{
use sea_orm::{
ActiveModelTrait, ActiveValue::Set, DatabaseConnection, EntityTrait, TransactionTrait,
};
use serde::{Deserialize, Serialize};
pub mod category;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Account {
pub id: i64,
pub name: String,
@@ -43,11 +46,13 @@ impl From<(AccountModel, AccountCategoryModel)> for Account {
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateAccountRequest {
pub name: String,
pub category: CreateAccountCategoryRequest,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UpdateAccountRequest {
pub name: Option<String>,
pub category: Option<UpdateAccountCategoryRequest>,
@@ -125,8 +130,8 @@ impl AccountsService for AccountsServiceImpl {
let new_account = AccountEntity::insert(AccountActiveModel {
name: Set(create_request.name),
created_at: Set(chrono::Utc::now().to_string()),
updated_at: Set(chrono::Utc::now().to_string()),
created_at: Set(chrono::Utc::now().to_rfc3339()),
updated_at: Set(chrono::Utc::now().to_rfc3339()),
account_category_id: Set(category_id),
..Default::default()
})
@@ -162,7 +167,7 @@ impl AccountsService for AccountsServiceImpl {
.update_category_with_tx(id, category_request, &(&tx).into())
.await?;
}
active_model.updated_at = Set(chrono::Utc::now().to_string());
active_model.updated_at = Set(chrono::Utc::now().to_rfc3339());
//
active_model.update(&tx).await.map_err(|e| e.to_string())?;
let res = tx.commit().await.map_err(|e| e.to_string());