/** * Pure helper functions for computing quote prices, protection amounts, and extras. */ import type { Quote } from '../../../types'; /** * Compute the final net/gross price for a quote, factoring in protection extras. * Returns values in major currency units (i.e. divided by 100). */ export function computeFinalPrice( quote: Quote, fullyProtection: boolean, ): { net: number; gross: number } { const { price, availableExtras } = quote; if (fullyProtection) { const full = availableExtras.find((e) => e.key === 'protection:full')?.price; if (full) { return { net: (price.net + full.net) / 100, gross: (price.gross + full.gross) / 100, }; } } const base = availableExtras.find((e) => e.key === 'protection:base')?.price; if (base) { return { net: (price.net + base.net) / 100, gross: (price.gross + base.gross) / 100, }; } return { net: price.net / 100, gross: price.gross / 100 }; } /** * Compute the protected amount for a quote based on protection level. */ export function computeProtectedAmount(quote: Quote, fullyProtection: boolean): number { const { availableExtras, service } = quote; const protectionExtra = fullyProtection ? availableExtras.find((e) => e.key === 'protection:full') || availableExtras.find((e) => e.key === 'protection:base') : availableExtras.find((e) => e.key === 'protection:base'); if (!protectionExtra) return service.includedProtection || 0; return protectionExtra.metadata?.protectedAmount || 0; } /** * Build the list of extra keys to include in a booking, based on protection level. */ export function buildExtras(quote: Quote, fullyProtection: boolean): string[] { const extras: string[] = []; if (fullyProtection && quote.availableExtras.find((e) => e.key === 'protection:full')) { extras.push('protection:full'); } else if (quote.availableExtras.find((e) => e.key === 'protection:base')) { extras.push('protection:base'); } return extras; }