mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-14 00:01:03 +00:00
fix(costs): keep convertBooked at five parameters and update the tests to as-typed display rows
The display-currency check is its own helper (inDisplayCurrency), used by the Costs model and the shared trip page. The tests that pinned #2525's reading of a display-currency bill through the trip currency now pin the as-typed reading, which the balances use too; read in the trip currency, such a bill and its repayment may stay a euro cent apart.
This commit is contained in:
@@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach, vi } from 'vitest'
|
||||
import { renderHook, waitFor } from '@testing-library/react'
|
||||
import { http, HttpResponse } from 'msw'
|
||||
import { server } from '../../tests/helpers/msw/server'
|
||||
import { bookedInTrip, convertBooked, convertedLine, crossRate, fetchExchangeRates, fetchFreshRates, freshRates, clearExchangeRateCache, tripAmountOf, useExchangeRates, withFallbackFx } from './useExchangeRates'
|
||||
import { bookedInTrip, convertBooked, convertedLine, inDisplayCurrency, crossRate, fetchExchangeRates, fetchFreshRates, freshRates, clearExchangeRateCache, tripAmountOf, useExchangeRates, withFallbackFx } from './useExchangeRates'
|
||||
|
||||
const FX_URL = 'https://api.frankfurter.dev/v2/rates'
|
||||
|
||||
@@ -198,16 +198,11 @@ describe('convertBooked', () => {
|
||||
})
|
||||
|
||||
// #2965: read in dollars, a bill entered in dollars counts as typed, as the balances net it.
|
||||
it('shows a row in the display currency as typed, whatever rate it was frozen at', () => {
|
||||
const liveUsd = (amount: number, from: string | null | undefined): number => {
|
||||
const rates: Record<string, number> = { USD: 1, EUR: 1 / 1.1398 }
|
||||
const r = rates[(from || 'USD').toUpperCase()]
|
||||
return r && r > 0 ? amount / r : amount
|
||||
}
|
||||
expect(convertBooked(801.76, 'USD', 1.17, 'EUR', liveUsd, 'USD')).toBe(801.76)
|
||||
expect(convertBooked(801.76, 'usd', 1.17, 'EUR', liveUsd, 'USD')).toBe(801.76)
|
||||
// Another currency still goes through the trip currency.
|
||||
expect(convertBooked(801.76, 'USD', 1.17, 'EUR', liveUsd, 'GBP')).toBeCloseTo((801.76 / 1.17) * 1.1398, 6)
|
||||
it('knows a row entered in the display currency, a NULL currency being the trip one', () => {
|
||||
expect(inDisplayCurrency('usd', 'EUR', 'USD')).toBe(true)
|
||||
expect(inDisplayCurrency(null, 'EUR', 'eur')).toBe(true)
|
||||
expect(inDisplayCurrency(null, 'EUR', 'USD')).toBe(false)
|
||||
expect(inDisplayCurrency('USD', 'EUR', 'GBP')).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -133,19 +133,27 @@ export function convertBooked(
|
||||
frozenRate: number | null | undefined,
|
||||
tripCurrency: string,
|
||||
convertLive: (amount: number, from: string | null | undefined) => number,
|
||||
displayCurrency?: string,
|
||||
): number {
|
||||
const trip = (tripCurrency || 'EUR').toUpperCase()
|
||||
// A row entered in the display currency is shown as typed (#2965): through the
|
||||
// trip currency at its frozen rate and back at today's, it drifted off the
|
||||
// amount entered, and the balances (which net such rows as typed) disagreed.
|
||||
if (displayCurrency && (rowCurrency || trip).toUpperCase() === displayCurrency.toUpperCase()) return amount
|
||||
const inTrip = bookedInTrip(amount, rowCurrency, frozenRate, trip)
|
||||
if (inTrip != null) return convertLive(inTrip, trip)
|
||||
// A NULL currency means the trip's own, and then there was never anything to freeze.
|
||||
return convertLive(amount, (rowCurrency || trip).toUpperCase())
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a row was entered in the display currency (#2965). Such a row counts as typed:
|
||||
* through the trip currency at its frozen rate and back at today's it drifted off the
|
||||
* amount entered, and the balances, which net such rows as typed, would disagree.
|
||||
*/
|
||||
export function inDisplayCurrency(
|
||||
rowCurrency: string | null | undefined,
|
||||
tripCurrency: string,
|
||||
displayCurrency: string,
|
||||
): boolean {
|
||||
return ((rowCurrency || tripCurrency) || '').toUpperCase() === (displayCurrency || '').toUpperCase()
|
||||
}
|
||||
|
||||
/**
|
||||
* The amount a row was booked at in the trip currency, when it was booked through one: a
|
||||
* foreign currency with a frozen rate. Null for a row in the trip currency, and for one
|
||||
|
||||
Reference in New Issue
Block a user