Merge branch 'fix/calculation-accuracy' into main
All checks were successful
Deploy / build-and-deploy (push) Successful in 2m37s
All checks were successful
Deploy / build-and-deploy (push) Successful in 2m37s
Combines the decimal migration (int cents → decimal.Decimal via shopspring/decimal) with main's handler refactor (split space.go into domain handlers, WithTx/Paginate helpers, recurring deposit removal). - Repository layer: WithTx pattern + decimal column names/types - Handler layer: decimal arithmetic (.Sub/.Add) instead of int operators - Models: deprecated amount_cents fields kept for SELECT * compatibility - INSERT statements: old columns set to literal 0 for NOT NULL constraints Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
commit
89c5d76e5e
46 changed files with 661 additions and 539 deletions
|
|
@ -14,6 +14,7 @@ import (
|
|||
"git.juancwu.dev/juancwu/budgit/internal/ui/components/paymentmethod"
|
||||
"git.juancwu.dev/juancwu/budgit/internal/ui/components/radio"
|
||||
"git.juancwu.dev/juancwu/budgit/internal/ui/components/tagcombobox"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
type AddExpenseFormProps struct {
|
||||
|
|
@ -215,7 +216,7 @@ templ EditExpenseForm(spaceID string, exp *model.ExpenseWithTagsAndMethod, metho
|
|||
Name: "amount",
|
||||
ID: "edit-amount-" + exp.ID,
|
||||
Type: "number",
|
||||
Value: fmt.Sprintf("%.2f", float64(exp.AmountCents)/100.0),
|
||||
Value: model.FormatDecimal(exp.Amount),
|
||||
Attributes: templ.Attributes{"step": "0.01", "required": "true"},
|
||||
})
|
||||
</div>
|
||||
|
|
@ -345,7 +346,7 @@ templ ItemSelectorSection(listsWithItems []model.ListWithUncheckedItems, oob boo
|
|||
</div>
|
||||
}
|
||||
|
||||
templ BalanceCard(spaceID string, balance int, allocated int, oob bool) {
|
||||
templ BalanceCard(spaceID string, balance decimal.Decimal, allocated decimal.Decimal, oob bool) {
|
||||
<div
|
||||
id="balance-card"
|
||||
class="border rounded-lg p-4 bg-card text-card-foreground"
|
||||
|
|
@ -354,11 +355,11 @@ templ BalanceCard(spaceID string, balance int, allocated int, oob bool) {
|
|||
}
|
||||
>
|
||||
<h2 class="text-lg font-semibold">Current Balance</h2>
|
||||
<p class={ "text-3xl font-bold", templ.KV("text-destructive", balance < 0) }>
|
||||
{ fmt.Sprintf("$%.2f", float64(balance)/100.0) }
|
||||
if allocated > 0 {
|
||||
<p class={ "text-3xl font-bold", templ.KV("text-destructive", balance.LessThan(decimal.Zero)) }>
|
||||
{ model.FormatMoney(balance) }
|
||||
if allocated.GreaterThan(decimal.Zero) {
|
||||
<span class="text-base font-normal text-muted-foreground">
|
||||
({ fmt.Sprintf("$%.2f", float64(allocated)/100.0) } in accounts)
|
||||
({ model.FormatMoney(allocated) } in accounts)
|
||||
</span>
|
||||
}
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -11,9 +11,10 @@ import (
|
|||
"git.juancwu.dev/juancwu/budgit/internal/ui/components/input"
|
||||
"git.juancwu.dev/juancwu/budgit/internal/ui/components/label"
|
||||
"git.juancwu.dev/juancwu/budgit/internal/ui/components/pagination"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
templ BalanceSummaryCard(spaceID string, totalBalance int, availableBalance int, oob bool) {
|
||||
templ BalanceSummaryCard(spaceID string, totalBalance decimal.Decimal, availableBalance decimal.Decimal, oob bool) {
|
||||
<div
|
||||
id="accounts-balance-summary"
|
||||
class="border rounded-lg p-4 bg-card text-card-foreground"
|
||||
|
|
@ -25,20 +26,20 @@ templ BalanceSummaryCard(spaceID string, totalBalance int, availableBalance int,
|
|||
<div class="grid grid-cols-3 gap-4">
|
||||
<div>
|
||||
<p class="text-sm text-muted-foreground">Total Balance</p>
|
||||
<p class={ "text-xl font-bold", templ.KV("text-destructive", totalBalance < 0) }>
|
||||
{ fmt.Sprintf("$%.2f", float64(totalBalance)/100.0) }
|
||||
<p class={ "text-xl font-bold", templ.KV("text-destructive", totalBalance.LessThan(decimal.Zero)) }>
|
||||
{ model.FormatMoney(totalBalance) }
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm text-muted-foreground">Allocated</p>
|
||||
<p class="text-xl font-bold">
|
||||
{ fmt.Sprintf("$%.2f", float64(totalBalance-availableBalance)/100.0) }
|
||||
{ model.FormatMoney(totalBalance.Sub(availableBalance)) }
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm text-muted-foreground">Available</p>
|
||||
<p class={ "text-xl font-bold", templ.KV("text-destructive", availableBalance < 0) }>
|
||||
{ fmt.Sprintf("$%.2f", float64(availableBalance)/100.0) }
|
||||
<p class={ "text-xl font-bold", templ.KV("text-destructive", availableBalance.LessThan(decimal.Zero)) }>
|
||||
{ model.FormatMoney(availableBalance) }
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -60,8 +61,8 @@ templ AccountCard(spaceID string, acct *model.MoneyAccountWithBalance, oob ...bo
|
|||
<div class="flex justify-between items-start mb-3">
|
||||
<div>
|
||||
<h3 class="font-semibold text-lg">{ acct.Name }</h3>
|
||||
<p class={ "text-2xl font-bold", templ.KV("text-destructive", acct.BalanceCents < 0) }>
|
||||
{ fmt.Sprintf("$%.2f", float64(acct.BalanceCents)/100.0) }
|
||||
<p class={ "text-2xl font-bold", templ.KV("text-destructive", acct.Balance.LessThan(decimal.Zero)) }>
|
||||
{ model.FormatMoney(acct.Balance) }
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-1">
|
||||
|
|
@ -359,11 +360,11 @@ templ TransferHistoryItem(spaceID string, t *model.AccountTransferWithAccount) {
|
|||
<div class="flex items-center gap-2">
|
||||
if t.Direction == model.TransferDirectionDeposit {
|
||||
<span class="font-bold text-green-600 whitespace-nowrap">
|
||||
+{ fmt.Sprintf("$%.2f", float64(t.AmountCents)/100.0) }
|
||||
+{ model.FormatMoney(t.Amount) }
|
||||
</span>
|
||||
} else {
|
||||
<span class="font-bold text-destructive whitespace-nowrap">
|
||||
-{ fmt.Sprintf("$%.2f", float64(t.AmountCents)/100.0) }
|
||||
-{ model.FormatMoney(t.Amount) }
|
||||
</span>
|
||||
}
|
||||
@button.Button(button.Props{
|
||||
|
|
@ -382,4 +383,3 @@ templ TransferHistoryItem(spaceID string, t *model.AccountTransferWithAccount) {
|
|||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,11 +73,11 @@ templ RecurringItem(spaceID string, re *model.RecurringExpenseWithTagsAndMethod,
|
|||
<div class="flex items-center gap-1 shrink-0">
|
||||
if re.Type == model.ExpenseTypeExpense {
|
||||
<p class="font-bold text-destructive">
|
||||
- { fmt.Sprintf("$%.2f", float64(re.AmountCents)/100.0) }
|
||||
- { model.FormatMoney(re.Amount) }
|
||||
</p>
|
||||
} else {
|
||||
<p class="font-bold text-green-500">
|
||||
+ { fmt.Sprintf("$%.2f", float64(re.AmountCents)/100.0) }
|
||||
+ { model.FormatMoney(re.Amount) }
|
||||
</p>
|
||||
}
|
||||
// Toggle pause/resume
|
||||
|
|
@ -352,7 +352,7 @@ templ EditRecurringForm(spaceID string, re *model.RecurringExpenseWithTagsAndMet
|
|||
Name: "amount",
|
||||
ID: "edit-recurring-amount-" + re.ID,
|
||||
Type: "number",
|
||||
Value: fmt.Sprintf("%.2f", float64(re.AmountCents)/100.0),
|
||||
Value: model.FormatDecimal(re.Amount),
|
||||
Attributes: templ.Attributes{"step": "0.01", "required": "true"},
|
||||
})
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue