Merged in chore/price-calculation-tests (pull request #3072)
chore: Add more price calculation tests * Add tests and refactor types for getVoucherPrice * Add tests for sumPackagesRequestedPrice * Add tests for calculateVat Approved-by: Joakim Jäderberg
This commit is contained in:
@@ -2,7 +2,11 @@ import { describe, expect, it } from "vitest"
|
||||
|
||||
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||
|
||||
import { getAdditionalPrice, getRedemptionPrice } from "./helpers"
|
||||
import {
|
||||
getAdditionalPrice,
|
||||
getRedemptionPrice,
|
||||
getVoucherPrice,
|
||||
} from "./helpers"
|
||||
|
||||
type GetAdditionalPriceParams = Parameters<typeof getAdditionalPrice>
|
||||
describe("getAdditionalPrice", () => {
|
||||
@@ -307,3 +311,150 @@ describe("getRedemptionPrice", () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("getVoucherPrice", () => {
|
||||
it("returns price 0 and default currency when rooms are empty", () => {
|
||||
const result = getVoucherPrice([], 1)
|
||||
|
||||
expect(result).toEqual({
|
||||
local: { price: 0, currency: CurrencyEnum.Voucher },
|
||||
requested: undefined,
|
||||
})
|
||||
})
|
||||
|
||||
it("returns price for single room with voucher price", () => {
|
||||
const nights = 1
|
||||
const result = getVoucherPrice(
|
||||
[
|
||||
{
|
||||
adults: 1,
|
||||
breakfast: false,
|
||||
roomFeatures: [],
|
||||
roomRate: {
|
||||
voucher: {
|
||||
numberOfVouchers: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
nights
|
||||
)
|
||||
|
||||
expect(result).toEqual({
|
||||
local: {
|
||||
price: 1,
|
||||
currency: CurrencyEnum.Voucher,
|
||||
additionalPrice: 0,
|
||||
},
|
||||
requested: undefined,
|
||||
})
|
||||
})
|
||||
|
||||
it("returns price for single room with multiple nights", () => {
|
||||
const nights = 3
|
||||
const result = getVoucherPrice(
|
||||
[
|
||||
{
|
||||
adults: 1,
|
||||
breakfast: false,
|
||||
roomFeatures: [],
|
||||
roomRate: {
|
||||
voucher: {
|
||||
numberOfVouchers: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
nights
|
||||
)
|
||||
|
||||
expect(result).toEqual({
|
||||
local: {
|
||||
price: 3,
|
||||
currency: CurrencyEnum.Voucher,
|
||||
additionalPrice: 0,
|
||||
},
|
||||
requested: undefined,
|
||||
})
|
||||
})
|
||||
|
||||
it("returns price for multiple rooms with multiple nights", () => {
|
||||
const nights = 3
|
||||
const result = getVoucherPrice(
|
||||
[
|
||||
{
|
||||
adults: 1,
|
||||
breakfast: false,
|
||||
roomFeatures: [],
|
||||
roomRate: {
|
||||
voucher: {
|
||||
numberOfVouchers: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
adults: 1,
|
||||
breakfast: false,
|
||||
roomFeatures: [],
|
||||
roomRate: {
|
||||
voucher: {
|
||||
numberOfVouchers: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
nights
|
||||
)
|
||||
|
||||
expect(result).toEqual({
|
||||
local: {
|
||||
price: 5,
|
||||
currency: CurrencyEnum.Voucher,
|
||||
additionalPrice: 0,
|
||||
},
|
||||
requested: undefined,
|
||||
})
|
||||
})
|
||||
|
||||
it("does not return price for room without voucher", () => {
|
||||
const nights = 3
|
||||
const result = getVoucherPrice(
|
||||
[
|
||||
{
|
||||
adults: 1,
|
||||
breakfast: false,
|
||||
roomFeatures: [],
|
||||
roomRate: {
|
||||
redemption: {
|
||||
localPrice: {
|
||||
pointsPerStay: 150,
|
||||
currency: CurrencyEnum.POINTS,
|
||||
additionalPricePerStay: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
adults: 1,
|
||||
breakfast: false,
|
||||
roomFeatures: [],
|
||||
roomRate: {
|
||||
voucher: {
|
||||
numberOfVouchers: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
nights
|
||||
)
|
||||
|
||||
expect(result).toEqual({
|
||||
local: {
|
||||
price: 2,
|
||||
currency: CurrencyEnum.Voucher,
|
||||
additionalPrice: 0,
|
||||
},
|
||||
requested: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -14,7 +14,6 @@ import type {
|
||||
CorporateChequeProduct,
|
||||
PriceProduct,
|
||||
Product,
|
||||
VoucherProduct,
|
||||
} from "@scandic-hotels/trpc/types/roomAvailability"
|
||||
import type { User } from "@scandic-hotels/trpc/types/user"
|
||||
|
||||
@@ -417,13 +416,17 @@ function getCorporateChequePrice(rooms: TRoom[], nights: number) {
|
||||
)
|
||||
}
|
||||
|
||||
interface TRoomVoucher extends TRoom {
|
||||
roomRate: VoucherProduct
|
||||
type VoucherRoom = PriceCalculationRoom & {
|
||||
roomRate: {
|
||||
voucher: {
|
||||
numberOfVouchers: number
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getVoucherPrice(rooms: TRoom[], nights: number) {
|
||||
export function getVoucherPrice(rooms: PriceCalculationRoom[], nights: number) {
|
||||
return rooms
|
||||
.filter((room): room is TRoomVoucher => "voucher" in room.roomRate)
|
||||
.filter((room): room is VoucherRoom => "voucher" in room.roomRate)
|
||||
.reduce<Price>(
|
||||
(total, room) => {
|
||||
const voucher = room.roomRate.voucher
|
||||
@@ -450,7 +453,7 @@ function getVoucherPrice(rooms: TRoom[], nights: number) {
|
||||
)
|
||||
}
|
||||
|
||||
type GetRedemptionPriceRoom = {
|
||||
type PriceCalculationRoom = {
|
||||
adults: number
|
||||
breakfast:
|
||||
| { localPrice: { price: number; currency?: CurrencyEnum } }
|
||||
@@ -465,7 +468,7 @@ type GetRedemptionPriceRoom = {
|
||||
// We don't care about roomRate unless it's RedemptionProduct
|
||||
roomRate: object
|
||||
}
|
||||
type RedemptionRoom = GetRedemptionPriceRoom & {
|
||||
type RedemptionRoom = PriceCalculationRoom & {
|
||||
roomRate: {
|
||||
redemption: {
|
||||
localPrice: {
|
||||
@@ -478,7 +481,7 @@ type RedemptionRoom = GetRedemptionPriceRoom & {
|
||||
}
|
||||
|
||||
export function getRedemptionPrice(
|
||||
rooms: GetRedemptionPriceRoom[],
|
||||
rooms: PriceCalculationRoom[],
|
||||
nights: number,
|
||||
pointsCurrency?: CurrencyEnum
|
||||
) {
|
||||
|
||||
@@ -4,7 +4,12 @@ import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert"
|
||||
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||
import { dt } from "@scandic-hotels/common/dt"
|
||||
|
||||
import { filterOverlappingDates, sumPackages } from "./index"
|
||||
import {
|
||||
calculateVat,
|
||||
filterOverlappingDates,
|
||||
sumPackages,
|
||||
sumPackagesRequestedPrice,
|
||||
} from "./index"
|
||||
|
||||
import type { specialAlertsSchema } from "@scandic-hotels/trpc/routers/hotels/schemas/hotel/specialAlerts"
|
||||
import type { z } from "zod"
|
||||
@@ -98,3 +103,42 @@ describe("sumPackages", () => {
|
||||
expect(result).toEqual({ currency: CurrencyEnum.SEK, price: 350 })
|
||||
})
|
||||
})
|
||||
|
||||
describe("sumPackagesRequestedPrice", () => {
|
||||
it("returns 0 price for null packages", () => {
|
||||
const result = sumPackagesRequestedPrice(null)
|
||||
expect(result).toEqual({ currency: undefined, price: 0 })
|
||||
})
|
||||
|
||||
it("returns 0 price for undefined packages", () => {
|
||||
const result = sumPackagesRequestedPrice(undefined)
|
||||
expect(result).toEqual({ currency: undefined, price: 0 })
|
||||
})
|
||||
|
||||
it("returns 0 price for empty packages", () => {
|
||||
const result = sumPackagesRequestedPrice([])
|
||||
expect(result).toEqual({ currency: undefined, price: 0 })
|
||||
})
|
||||
|
||||
it("sums prices of packages", () => {
|
||||
const result = sumPackagesRequestedPrice([
|
||||
{ requestedPrice: { totalPrice: 100, currency: CurrencyEnum.SEK } },
|
||||
{ requestedPrice: { totalPrice: 200, currency: CurrencyEnum.SEK } },
|
||||
{ requestedPrice: { totalPrice: 50, currency: CurrencyEnum.SEK } },
|
||||
])
|
||||
expect(result).toEqual({ currency: CurrencyEnum.SEK, price: 350 })
|
||||
})
|
||||
})
|
||||
|
||||
describe("calculateVat", () => {
|
||||
it("calculates VAT correctly", () => {
|
||||
expect(calculateVat(100, 25)).toEqual({
|
||||
priceExclVat: 80,
|
||||
vatAmount: 20,
|
||||
})
|
||||
expect(calculateVat(5, 100)).toEqual({
|
||||
priceExclVat: 2.5,
|
||||
vatAmount: 2.5,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -9,7 +9,6 @@ import { ChildBedTypeEnum } from "@scandic-hotels/trpc/enums/childBedTypeEnum"
|
||||
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
||||
|
||||
import type { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||
import type { Packages } from "@scandic-hotels/trpc/types/packages"
|
||||
import type { JSX } from "react"
|
||||
|
||||
import type { RoomPackageCodes } from "../../types/components/selectRate/roomFilter"
|
||||
@@ -63,7 +62,12 @@ export function sumPackages(
|
||||
)
|
||||
}
|
||||
|
||||
export function sumPackagesRequestedPrice(packages: Packages | null) {
|
||||
export function sumPackagesRequestedPrice(
|
||||
packages:
|
||||
| { requestedPrice: { totalPrice: number; currency?: CurrencyEnum } }[]
|
||||
| null
|
||||
| undefined
|
||||
) {
|
||||
if (!packages || !packages.length) {
|
||||
return {
|
||||
currency: undefined,
|
||||
|
||||
Reference in New Issue
Block a user