Fare engine updates, seat class amount updates

This commit is contained in:
Stephanos A
2026-07-08 18:16:57 +03:00
parent 9e208861c7
commit 3760bcdb66
15 changed files with 243 additions and 99 deletions

View File

@@ -30,23 +30,59 @@ export class CurrencyService {
private readonly configService: ConfigService,
) {}
/**
* Converts a stored display-currency minor amount to the charge major amount
* sent to the payment provider, without hitting the DB for an exchange rate.
* Use this when the payment method's settlement currency matches the booking's
* displayCurrency — the rate is already baked into displayTotalMinor.
*/
displayMinorToChargeMajor(displayMinor: number, currency: string): number {
const decimals = CHARGE_CURRENCY_DECIMALS[currency.toUpperCase()];
if (decimals === undefined) {
throw new BadRequestException(`Unsupported charge currency: ${currency}`);
}
return this.roundTo(displayMinor / 100, decimals);
}
async convertEtbMinorToChargeMinor(
amountMinorEtb: number,
targetCurrency: string,
): Promise<number> {
const target = targetCurrency.toUpperCase();
if (CHARGE_CURRENCY_DECIMALS[target] === undefined) {
throw new BadRequestException(`Unsupported charge currency: ${targetCurrency}`);
}
if (target === Currency.ETB) {
return amountMinorEtb;
}
// Convert ETB minor → target minor: apply exchange rate, keep as minor units.
const rate = await this.getRateOrThrow(Currency.ETB, target as Currency);
return Math.round(amountMinorEtb * rate);
}
/**
* Converts an ETB minor-unit amount to the charge major-unit amount sent to the
* payment provider. Applies the exchange rate for foreign currencies then divides
* by 100 to yield major units (e.g. 300000 ETB minor → 3000.00 ETB major).
*/
async convertEtbMinorToChargeMajor(
amountMinorEtb: number,
targetCurrency: string,
): Promise<number> {
const target = targetCurrency.toUpperCase();
const decimals = CHARGE_CURRENCY_DECIMALS[target];
if (decimals === undefined) {
if (CHARGE_CURRENCY_DECIMALS[target] === undefined) {
throw new BadRequestException(`Unsupported charge currency: ${targetCurrency}`);
}
const decimals = CHARGE_CURRENCY_DECIMALS[target];
const sourceMajor = amountMinorEtb / 100;
if (target === Currency.ETB) {
return this.roundTo(sourceMajor, decimals);
return this.roundTo(amountMinorEtb / 100, decimals);
}
const rate = await this.getRateOrThrow(Currency.ETB, target as Currency);
return this.roundTo(sourceMajor * rate, decimals);
return this.roundTo((amountMinorEtb * rate) / 100, decimals);
}
async getRateOrThrow(