import { injectable } from "inversify" ; import type { Card } from "../card/Card" ; import type { Vendor } from "./Vendor" ; import type { Currency } from "./Currency" ; import { difference , sum } from "lodash" ; export interface PriceLookupResult { price : number ; missing : Card [ ] ; } @ injectable ( ) export class PriceService { param value param currency return formatPrice ( value , currency ) { return new Intl . NumberFormat ( "en-US" , { style : "currency" , currency : currency . id , minimumFractionDigits : currency . fractionDigits , maximumFractionDigits : currency . fractionDigits , } ) . format ( value ) ; } param cards param vendor param currency return getPrice ( cards , vendor , currency ) { const missing = cards . filter ( ( card ) => ! this . #hasPrice ( card , vendor ) ) ; const price = sum ( difference ( cards , missing ) . map ( ( card ) => this . #getCardPrice ( card , vendor , currency ) ) ) ; return { price , missing } ; } #hasPrice ( card , vendor ) { return card . prices . has ( vendor ) ; } #getCardPrice ( card , vendor , currency ) { if ( ! this . #hasPrice ( card , vendor ) ) { throw new TypeError ( `No price exists for this vendor: ${ vendor . id }` ) ; } const price = card . prices . get ( vendor ) ! ; if ( currency == null ) { return price ; } const priceInUsd = price / vendor . currency . conversionRate ; return priceInUsd * currency . conversionRate ; } }