Skip to content

Commit e55912e

Browse files
committed
fix: currency conversion
1 parent f98967f commit e55912e

4 files changed

Lines changed: 41 additions & 38 deletions

File tree

cmd/add.go

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,31 @@ func runAdd(cmd *cobra.Command, args []string) error {
138138
bill.PaymentModeID = methodID
139139
}
140140

141-
// Resolve optional currency
141+
// Fetch user info for locale-aware formatting
142+
locale := "en_US"
143+
userInfo, ok := cache.LoadUserInfo()
144+
if !ok {
145+
userInfo, err = client.GetUserInfo()
146+
if err == nil {
147+
_ = cache.SaveUserInfo(userInfo)
148+
}
149+
}
150+
if userInfo != nil && userInfo.Locale != "" {
151+
locale = userInfo.Locale
152+
} else if userInfo != nil && userInfo.Language != "" {
153+
locale = userInfo.Language
154+
}
155+
156+
// Resolve optional currency and convert amount
142157
if convertTo != "" {
143-
currencyID, err := cache.ResolveCurrency(project, convertTo)
158+
currency, err := cache.ResolveCurrency(project, convertTo)
144159
if err != nil {
145160
return fmt.Errorf("resolving currency: %w", err)
146161
}
147-
bill.OriginalCurrencyID = currencyID
162+
bill.OriginalCurrencyID = currency.ID
163+
bill.Amount = amount * currency.ExchangeRate
164+
origFormatter := format.NewAmountFormatter(locale, currency.Name)
165+
bill.What = fmt.Sprintf("%s (%s)", expenseName, origFormatter.Format(amount))
148166
}
149167

150168
// Add optional comment
@@ -157,22 +175,7 @@ func runAdd(cmd *cobra.Command, args []string) error {
157175
return fmt.Errorf("creating bill: %w", err)
158176
}
159177

160-
// Fetch user info for locale-aware formatting
161-
locale := "en_US"
162-
userInfo, ok := cache.LoadUserInfo()
163-
if !ok {
164-
userInfo, err = client.GetUserInfo()
165-
if err == nil {
166-
_ = cache.SaveUserInfo(userInfo)
167-
}
168-
}
169-
if userInfo != nil && userInfo.Locale != "" {
170-
locale = userInfo.Locale
171-
} else if userInfo != nil && userInfo.Language != "" {
172-
locale = userInfo.Language
173-
}
174-
175178
formatter := format.NewAmountFormatter(locale, project.CurrencyName)
176-
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "Successfully added expense: %s (%s)\n", expenseName, formatter.Format(amount))
179+
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "Successfully added expense: %s (%s)\n", expenseName, formatter.Format(bill.Amount))
177180
return nil
178181
}

cmd/add_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ func TestAddCommandWithAllFlags(t *testing.T) {
233233
{ID: 3, Name: "Credit Card"},
234234
},
235235
Currencies: []api.Currency{
236-
{ID: 2, Name: "€"},
236+
{ID: 2, Name: "€", ExchangeRate: 0.85},
237237
},
238238
}
239239

@@ -288,11 +288,11 @@ func TestAddCommandWithAllFlags(t *testing.T) {
288288
}
289289

290290
// Verify bill data
291-
if receivedBill["what"] != "Dinner" {
291+
if receivedBill["what"] != "Dinner (€ 45.00)" {
292292
t.Errorf("Wrong what: %s", receivedBill["what"])
293293
}
294-
if receivedBill["amount"] != "45.00" {
295-
t.Errorf("Wrong amount: %s", receivedBill["amount"])
294+
if receivedBill["amount"] != "38.25" { // 45.00 * 0.85 exchange rate
295+
t.Errorf("Wrong amount: got %s, want 38.25 (45.00 * 0.85)", receivedBill["amount"])
296296
}
297297
if receivedBill["payer"] != "2" { // Alice's ID
298298
t.Errorf("Wrong payer: %s", receivedBill["payer"])

internal/cache/cache.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -346,33 +346,33 @@ func ResolvePaymentMode(project *api.Project, nameOrID string) (int, error) {
346346
return 0, fmt.Errorf("payment mode not found: %s", nameOrID)
347347
}
348348

349-
// ResolveCurrency finds a currency by name (case-insensitive), ID, or currency code symbol and returns the ID
350-
func ResolveCurrency(project *api.Project, nameOrID string) (int, error) {
349+
// ResolveCurrency finds a currency by name (case-insensitive), ID, or currency code symbol and returns the currency
350+
func ResolveCurrency(project *api.Project, nameOrID string) (*api.Currency, error) {
351351
// Try parsing as ID first
352352
if id, err := strconv.Atoi(nameOrID); err == nil {
353-
for _, cur := range project.Currencies {
354-
if cur.ID == id {
355-
return id, nil
353+
for i := range project.Currencies {
354+
if project.Currencies[i].ID == id {
355+
return &project.Currencies[i], nil
356356
}
357357
}
358358
}
359359

360360
// Try matching by name (case-insensitive)
361361
lowerName := strings.ToLower(nameOrID)
362-
for _, cur := range project.Currencies {
363-
if strings.ToLower(cur.Name) == lowerName {
364-
return cur.ID, nil
362+
for i := range project.Currencies {
363+
if strings.ToLower(project.Currencies[i].Name) == lowerName {
364+
return &project.Currencies[i], nil
365365
}
366366
}
367367

368368
// Try matching by currency code symbol (e.g., "usd" -> "$")
369369
if symbol, ok := currencyCodeToSymbol[lowerName]; ok {
370-
for _, cur := range project.Currencies {
371-
if strings.Contains(cur.Name, symbol) {
372-
return cur.ID, nil
370+
for i := range project.Currencies {
371+
if strings.Contains(project.Currencies[i].Name, symbol) {
372+
return &project.Currencies[i], nil
373373
}
374374
}
375375
}
376376

377-
return 0, fmt.Errorf("currency not found: %s", nameOrID)
377+
return nil, fmt.Errorf("currency not found: %s", nameOrID)
378378
}

internal/cache/cache_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,13 @@ func TestResolveCurrency(t *testing.T) {
164164

165165
for _, tt := range tests {
166166
t.Run(tt.name, func(t *testing.T) {
167-
gotID, err := ResolveCurrency(project, tt.nameOrID)
167+
got, err := ResolveCurrency(project, tt.nameOrID)
168168
if (err != nil) != tt.wantErr {
169169
t.Errorf("ResolveCurrency() error = %v, wantErr %v", err, tt.wantErr)
170170
return
171171
}
172-
if gotID != tt.wantID {
173-
t.Errorf("ResolveCurrency() = %v, want %v", gotID, tt.wantID)
172+
if err == nil && got.ID != tt.wantID {
173+
t.Errorf("ResolveCurrency() ID = %v, want %v", got.ID, tt.wantID)
174174
}
175175
})
176176
}

0 commit comments

Comments
 (0)