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
158 lines
3.9 KiB
TypeScript
158 lines
3.9 KiB
TypeScript
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
|
import { PointType } from "@scandic-hotels/common/constants/pointType"
|
|
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
|
|
|
import type { IntlShape } from "react-intl"
|
|
|
|
import type { Room } from "@/types/stores/my-stay"
|
|
|
|
export function calculateTotalPrice(
|
|
rooms: Pick<
|
|
Room,
|
|
| "cheques"
|
|
| "vouchers"
|
|
| "roomPointType"
|
|
| "roomPoints"
|
|
| "totalPoints"
|
|
| "totalPrice"
|
|
| "isCancelled"
|
|
>[],
|
|
currency: CurrencyEnum,
|
|
intl: IntlShape,
|
|
allRoomsAreCancelled: boolean
|
|
) {
|
|
const totals = rooms.reduce(
|
|
(total, room) => {
|
|
if (!allRoomsAreCancelled && room.isCancelled) {
|
|
return total
|
|
}
|
|
|
|
if (room.cheques) {
|
|
total.cheques = total.cheques + room.cheques
|
|
}
|
|
|
|
if (room.vouchers) {
|
|
total.vouchers = total.vouchers + room.vouchers
|
|
}
|
|
|
|
// If roomPointType isn't Scandic, these should be counted as partnerPoints.
|
|
// If they're not Scandic points, we can ignore them on roomPoints as they
|
|
// are included in totalPoints, which in turn never contain partner points.
|
|
if (
|
|
room.roomPoints &&
|
|
room.roomPointType &&
|
|
room.roomPointType !== "Scandic"
|
|
) {
|
|
total.partnerPoints = total.partnerPoints + room.roomPoints
|
|
}
|
|
|
|
if (room.totalPoints) {
|
|
total.scandicPoints = total.scandicPoints + room.totalPoints
|
|
}
|
|
|
|
// room.totalPrice is a negative value when
|
|
// its a vouchers booking (╯°□°)╯︵ ┻━┻
|
|
if (room.totalPrice > 0) {
|
|
total.cash = total.cash + room.totalPrice
|
|
}
|
|
|
|
return total
|
|
},
|
|
{
|
|
cash: 0,
|
|
cheques: 0,
|
|
scandicPoints: 0,
|
|
partnerPoints: 0,
|
|
vouchers: 0,
|
|
}
|
|
)
|
|
|
|
const priceParts: string[] = []
|
|
if (totals.vouchers) {
|
|
priceParts.push(
|
|
`${totals.vouchers} ${intl.formatMessage(
|
|
{
|
|
id: "price.numberOfVouchers",
|
|
defaultMessage:
|
|
"{numberOfVouchers, plural, one {Voucher} other {Vouchers}}",
|
|
},
|
|
{
|
|
numberOfVouchers: totals.vouchers,
|
|
}
|
|
)}`
|
|
)
|
|
}
|
|
|
|
if (totals.cheques) {
|
|
priceParts.push(`${totals.cheques} ${CurrencyEnum.CC}`)
|
|
}
|
|
|
|
if (totals.partnerPoints) {
|
|
// We can assume that all rooms has the same point type
|
|
const roomPointType = rooms[0]?.roomPointType || PointType.SCANDIC
|
|
const currencyText = getPointsCurrencyText(
|
|
totals.partnerPoints,
|
|
roomPointType,
|
|
intl
|
|
)
|
|
priceParts.push(`${totals.partnerPoints} ${currencyText}`)
|
|
}
|
|
|
|
if (totals.scandicPoints) {
|
|
const currencyText = getPointsCurrencyText(
|
|
totals.scandicPoints,
|
|
PointType.SCANDIC,
|
|
intl
|
|
)
|
|
priceParts.push(`${totals.scandicPoints} ${currencyText}`)
|
|
}
|
|
|
|
if (totals.cash) {
|
|
const cashPrice = formatPrice(intl, totals.cash, currency)
|
|
priceParts.push(cashPrice)
|
|
}
|
|
|
|
return priceParts.join(" + ")
|
|
}
|
|
|
|
export function isAllRoomsCancelled(rooms: Room[]) {
|
|
return !rooms.some((room) => room.isCancelled === false)
|
|
}
|
|
|
|
function getPointsCurrencyText(
|
|
points: number,
|
|
pointsType: PointType,
|
|
intl: IntlShape
|
|
) {
|
|
switch (pointsType) {
|
|
case PointType.SCANDIC: {
|
|
return intl.formatMessage(
|
|
{
|
|
id: "price.numberOfScandicPoints",
|
|
defaultMessage:
|
|
"{numberOfScandicPoints, plural, one {Point} other {Points}}",
|
|
},
|
|
{
|
|
numberOfScandicPoints: points,
|
|
}
|
|
)
|
|
}
|
|
case PointType.EUROBONUS: {
|
|
return intl.formatMessage(
|
|
{
|
|
id: "price.numberOfEuroBonusPoints",
|
|
defaultMessage:
|
|
"{numberOfEuroBonusPoints, plural, one {EB Point} other {EB Points}}",
|
|
},
|
|
{
|
|
numberOfEuroBonusPoints: points,
|
|
}
|
|
)
|
|
}
|
|
default: {
|
|
const _exhaustiveCheck: never = pointsType
|
|
return "Points"
|
|
}
|
|
}
|
|
}
|