Skip to content

Commit 6e78790

Browse files
committed
✨ feat: store liability account balances as negative values
1 parent b9b6a9a commit 6e78790

2 files changed

Lines changed: 23 additions & 3 deletions

File tree

src/cli/account.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,20 @@ pub fn handle_account_command(storage: &Storage, cmd: AccountCommands) -> Envelo
7676
))
7777
})?;
7878

79-
let starting_balance = Money::parse(&balance).map_err(|e| {
79+
let mut starting_balance = Money::parse(&balance).map_err(|e| {
8080
crate::error::EnvelopeError::Validation(format!(
8181
"Invalid balance format: '{}'. Use format like '1000.00' or '1000'. Error: {}",
8282
balance, e
8383
))
8484
})?;
8585

86+
// For liability accounts (credit cards, lines of credit), balances represent
87+
// debt owed and should be stored as negative values. Users naturally enter
88+
// positive numbers when specifying debt, so we negate them.
89+
if account_type.is_liability() && starting_balance.cents() > 0 {
90+
starting_balance = Money::from_cents(-starting_balance.cents());
91+
}
92+
8693
let account = service.create(&name, account_type, starting_balance, !off_budget)?;
8794

8895
println!("Created account: {}", account.name);

src/tui/dialogs/account.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,12 +212,19 @@ impl AccountFormState {
212212
let account_type = self.selected_account_type();
213213

214214
let balance_str = self.balance_input.value().trim();
215-
let starting_balance = if balance_str.is_empty() {
215+
let mut starting_balance = if balance_str.is_empty() {
216216
Money::zero()
217217
} else {
218218
Money::parse(balance_str).map_err(|_| "Invalid balance")?
219219
};
220220

221+
// For liability accounts (credit cards, lines of credit), balances represent
222+
// debt owed and should be stored as negative values. Users naturally enter
223+
// positive numbers when specifying debt, so we negate them.
224+
if account_type.is_liability() && starting_balance.cents() > 0 {
225+
starting_balance = Money::from_cents(-starting_balance.cents());
226+
}
227+
221228
let mut account = Account::with_starting_balance(name, account_type, starting_balance);
222229
account.on_budget = self.on_budget;
223230

@@ -602,12 +609,18 @@ fn save_account(app: &mut App) -> Result<(), String> {
602609

603610
// Update starting balance
604611
let balance_str = app.account_form.balance_input.value().trim();
605-
existing.starting_balance = if balance_str.is_empty() {
612+
let mut new_balance = if balance_str.is_empty() {
606613
Money::zero()
607614
} else {
608615
Money::parse(balance_str).map_err(|_| "Invalid balance")?
609616
};
610617

618+
// For liability accounts, negate positive balances (debt is stored as negative)
619+
if existing.account_type.is_liability() && new_balance.cents() > 0 {
620+
new_balance = Money::from_cents(-new_balance.cents());
621+
}
622+
existing.starting_balance = new_balance;
623+
611624
existing.updated_at = chrono::Utc::now();
612625

613626
let account_name = existing.name.clone();

0 commit comments

Comments
 (0)