fix(SW-3616): Handle EuroBonus point type everywhere * Add tests to formatPrice * formatPrice * More work replacing config with api points type * More work replacing config with api points type * More fixing with currency * maybe actually fixed it * Fix MyStay * Clean up * Fix comments * Merge branch 'master' into fix/refactor-currency-display * Fix calculateTotalPrice for EB points + SF points + cash Approved-by: Joakim Jäderberg
111 lines
3.1 KiB
TypeScript
111 lines
3.1 KiB
TypeScript
import { CurrencyEnum } from "../constants/currency"
|
|
import { PointType } from "../constants/pointType"
|
|
import { logger } from "../logger"
|
|
|
|
import type { IntlShape } from "react-intl"
|
|
|
|
/**
|
|
* Function to parse number with single decimal if any
|
|
* @param n
|
|
* @returns number in float type with single digit decimal if any
|
|
*/
|
|
export function getSingleDecimal(n: Number | string) {
|
|
return parseFloat(Number(n).toFixed(1))
|
|
}
|
|
|
|
/**
|
|
* Function to parse number for i18n format for prices with currency
|
|
* @param intl - react-intl object
|
|
* @param price - number to be formatted
|
|
* @param currency - currency code
|
|
* @param additionalPrice - number (obtained in reward nights and Corporate cheque scenarios)
|
|
* @param additionalPriceCurrency - currency code (obtained in reward nights and Corporate cheque scenarios)
|
|
* @param pointsType - type of points when currency is points
|
|
* @returns localized and formatted number in string type with currency
|
|
*/
|
|
export function formatPrice(
|
|
intl: IntlShape,
|
|
price: number,
|
|
currency: string | CurrencyEnum,
|
|
additionalPrice?: number,
|
|
additionalPriceCurrency?: string,
|
|
pointsType?: PointType | null
|
|
) {
|
|
const localizedPrice = intl.formatNumber(price, {
|
|
minimumFractionDigits: 0,
|
|
maximumFractionDigits: 2,
|
|
})
|
|
|
|
let formattedAdditionalPrice: string = ""
|
|
if (additionalPrice && additionalPriceCurrency) {
|
|
const localizedAdditionalPrice = intl.formatNumber(additionalPrice, {
|
|
minimumFractionDigits: 0,
|
|
maximumFractionDigits: 2,
|
|
})
|
|
formattedAdditionalPrice = ` + ${localizedAdditionalPrice} ${additionalPriceCurrency}`
|
|
}
|
|
|
|
const currencyText = getCurrencyText(intl, price, currency, pointsType)
|
|
|
|
return `${localizedPrice} ${currencyText}${formattedAdditionalPrice}`
|
|
}
|
|
|
|
function getCurrencyText(
|
|
intl: IntlShape,
|
|
price: number,
|
|
currency: string | CurrencyEnum,
|
|
pointsType?: PointType | null
|
|
) {
|
|
if (currency === CurrencyEnum.Voucher) {
|
|
return intl.formatMessage(
|
|
{
|
|
id: "price.numberOfVouchers",
|
|
defaultMessage:
|
|
"{numberOfVouchers, plural, one {Voucher} other {Vouchers}}",
|
|
},
|
|
{
|
|
numberOfVouchers: price,
|
|
}
|
|
)
|
|
}
|
|
|
|
if (currency === CurrencyEnum.POINTS) {
|
|
if (!pointsType) return currency
|
|
|
|
switch (pointsType) {
|
|
case PointType.SCANDIC: {
|
|
return intl.formatMessage(
|
|
{
|
|
id: "price.numberOfScandicPoints",
|
|
defaultMessage:
|
|
"{numberOfScandicPoints, plural, one {Point} other {Points}}",
|
|
},
|
|
{
|
|
numberOfScandicPoints: price,
|
|
}
|
|
)
|
|
}
|
|
case PointType.EUROBONUS: {
|
|
return intl.formatMessage(
|
|
{
|
|
id: "price.numberOfEuroBonusPoints",
|
|
defaultMessage:
|
|
"{numberOfEuroBonusPoints, plural, one {EB Point} other {EB Points}}",
|
|
},
|
|
{
|
|
numberOfEuroBonusPoints: price,
|
|
}
|
|
)
|
|
}
|
|
default: {
|
|
const _exhaustiveCheck: never = pointsType
|
|
void _exhaustiveCheck
|
|
logger.warn(`Unknown point type provided: ${pointsType}`)
|
|
return currency
|
|
}
|
|
}
|
|
}
|
|
|
|
return currency
|
|
}
|