Files
medusa-store/packages/admin-ui/ui/src/utils/prices.ts
2023-03-03 10:09:16 +01:00

154 lines
3.9 KiB
TypeScript

import { LineItemTaxLine, MoneyAmount, Order, Region } from "@medusajs/medusa"
import { PricedVariant } from "@medusajs/medusa/dist/types/pricing"
import { currencies } from "./currencies"
export function normalizeAmount(currency: string, amount: number): number {
const divisor = getDecimalDigits(currency)
return Math.floor(amount) / divisor
}
export function displayAmount(currency: string, amount: number) {
const normalizedAmount = normalizeAmount(currency, amount)
return normalizedAmount.toFixed(
currencies[currency.toUpperCase()].decimal_digits
)
}
export const extractUnitPrice = (
item: PricedVariant,
region: Region,
withTax = true
) => {
let itemPrice = item.original_price
let includesTax = item.original_price_includes_tax
let taxRate = item.original_tax
if (itemPrice === undefined) {
const regionPrice = item.prices.find(
(p) => p.currency_code === region.currency_code
)
if (!regionPrice) {
return 0
}
itemPrice = regionPrice.amount
includesTax = region.includes_tax
taxRate = includesTax
? (itemPrice * region.tax_rate) / (1 + region.tax_rate)
: itemPrice * region.tax_rate
}
if (itemPrice) {
if (includesTax) {
if (withTax) {
return itemPrice
} else {
return itemPrice - (taxRate ?? 0)
}
} else {
if (withTax) {
return itemPrice + (taxRate ?? 0)
} else {
return itemPrice
}
}
}
return 0
}
export const displayUnitPrice = (item, region) => {
const currCode = region.currency_code.toUpperCase()
const price = extractUnitPrice(item, region)
return `${displayAmount(currCode, price)} ${currCode}`
}
export const extractOptionPrice = (price, region) => {
let amount = price
amount = (amount * (1 + region.tax_rate / 100)) / 100
return `${amount} ${region.currency_code.toUpperCase()}`
}
/**
* Checks the list of currencies and returns the divider/multiplier
* that should be used to calculate the persited and display amount.
* @param currency
* @return {number}
*/
export function getDecimalDigits(currency: string) {
const divisionDigits = currencies[currency.toUpperCase()].decimal_digits
return Math.pow(10, divisionDigits)
}
export function persistedPrice(currency: string, amount: number): number {
const multiplier = getDecimalDigits(currency)
return amount * multiplier
}
export const stringDisplayPrice = ({ amount, currencyCode }) => {
if (typeof amount === "undefined" || !currencyCode) {
return `N/A`
}
const display = displayAmount(currencyCode, amount)
return `${display} ${currencyCode.toUpperCase()}`
}
export const getNativeSymbol = (currencyCode: string) => {
return currencies[currencyCode.toUpperCase()].symbol_native
}
type FormatMoneyProps = {
amount: number
currency: string
digits?: number
tax?: number | LineItemTaxLine[]
}
export function formatAmountWithSymbol({
amount,
currency,
digits,
tax = 0,
}: FormatMoneyProps) {
let locale = "en-US"
// We need this to display 'Kr' instead of 'DKK'
if (currency.toLowerCase() === "dkk") {
locale = "da-DK"
}
digits = digits ?? currencies[currency.toUpperCase()].decimal_digits
const normalizedAmount = normalizeAmount(currency, amount)
const taxRate =
tax instanceof Array ? tax.reduce((acc, curr) => acc + curr.rate, 0) : tax
return new Intl.NumberFormat(locale, {
style: "currency",
currency,
minimumFractionDigits: digits,
}).format(normalizedAmount * (1 + taxRate / 100))
}
export const extractNormalizedAmount = (
amounts: Omit<MoneyAmount, "beforeInsert">[],
order: Omit<Order, "beforeInsert">
) => {
let amount = amounts.find((ma) => ma.region_id === order.region_id)
if (!amount) {
amount = amounts.find((ma) => ma.currency_code === order.currency_code)
}
if (amount) {
return normalizeAmount(order.currency_code, amount.amount)
}
return 0
}