Files
medusa-store/packages/medusa-react/src/helpers/index.ts
Zakaria El Asri 2e384842d5 feat: medusa-react admin hooks (#978)
* add: medusa admin hooks + tests

* fix: remove unneeded props

* fix: deps

* fix: deps

* fix: deps

* fix: failing tests

* fix: failing tests

* fix: query key

* add: yarn workspaces

* fix: linting medusa-react

* fix: add prepare script

* fix: buildOptions

* fix: useAdminShippingOptions query

* fix: use qs instead for query params (#1019)

* fix: formatting

* debug: ci pipeline

* debug: log node_modules structure

* debug: use lerna bootstrap

* debug: update node version

* debug: print pkgs in workspace

* debug: print pkgs in workspace

* debug: print pkgs in workspace

* debug: print pkgs in workspace

* debug: add explicit build step

* fix: jsdoc

* debug: run build step

* debug: fix build errors

* debug: add build step to integration tests

* fix: failing test

* cleanup

Co-authored-by: Sebastian Rindom <seb@medusajs.com>
Co-authored-by: Sebastian Rindom <skrindom@gmail.com>
2022-02-02 17:10:56 +01:00

168 lines
3.7 KiB
TypeScript

import { isEmpty } from "lodash"
import { RegionInfo, ProductVariantInfo } from "../types"
type FormatVariantPriceParams = {
variant: ProductVariantInfo
region: RegionInfo
includeTaxes?: boolean
minimumFractionDigits?: number
maximumFractionDigits?: number
locale?: string
}
/**
* Takes a product variant and a region, and converts the variant's price to a localized decimal format
*/
export const formatVariantPrice = ({
variant,
region,
includeTaxes = true,
...rest
}: FormatVariantPriceParams) => {
const amount = computeVariantPrice({ variant, region, includeTaxes })
return convertToLocale({
amount,
currency_code: region?.currency_code,
...rest,
})
}
type ComputeVariantPriceParams = {
variant: ProductVariantInfo
region: RegionInfo
includeTaxes?: boolean
}
/**
* Takes a product variant and region, and returns the variant price as a decimal number
* @param params.variant - product variant
* @param params.region - region
* @param params.includeTaxes - whether to include taxes or not
*/
export const computeVariantPrice = ({
variant,
region,
includeTaxes = true,
}: ComputeVariantPriceParams) => {
const amount = getVariantPrice(variant, region)
return computeAmount({
amount,
region,
includeTaxes,
})
}
/**
* Finds the price amount correspoding to the region selected
* @param variant - the product variant
* @param region - the region
* @returns - the price's amount
*/
export const getVariantPrice = (
variant: ProductVariantInfo,
region: RegionInfo
) => {
let price = variant?.prices?.find(
p => p.currency_code.toLowerCase() === region?.currency_code?.toLowerCase()
)
return price?.amount || 0
}
type ComputeAmountParams = {
amount: number
region: RegionInfo
includeTaxes?: boolean
}
/**
* Takes an amount, a region, and returns the amount as a decimal including or excluding taxes
*/
export const computeAmount = ({
amount,
region,
includeTaxes = true,
}: ComputeAmountParams) => {
const toDecimal = convertToDecimal(amount, region)
const taxRate = includeTaxes ? getTaxRate(region) : 0
const amountWithTaxes = toDecimal * (1 + taxRate)
return amountWithTaxes
}
type FormatAmountParams = {
amount: number
region: RegionInfo
includeTaxes?: boolean
minimumFractionDigits?: number
maximumFractionDigits?: number
locale?: string
}
/**
* Takes an amount and a region, and converts the amount to a localized decimal format
*/
export const formatAmount = ({
amount,
region,
includeTaxes = true,
...rest
}: FormatAmountParams) => {
const taxAwareAmount = computeAmount({
amount,
region,
includeTaxes,
})
return convertToLocale({
amount: taxAwareAmount,
currency_code: region.currency_code,
...rest,
})
}
// we should probably add a more extensive list
const noDivisionCurrencies = ["krw", "jpy", "vnd"]
const convertToDecimal = (amount: number, region: RegionInfo) => {
const divisor = noDivisionCurrencies.includes(
region?.currency_code?.toLowerCase()
)
? 1
: 100
return Math.floor(amount) / divisor
}
const getTaxRate = (region?: RegionInfo) => {
return region && !isEmpty(region) ? region?.tax_rate / 100 : 0
}
const convertToLocale = ({
amount,
currency_code,
minimumFractionDigits,
maximumFractionDigits,
locale = "en-US",
}: ConvertToLocaleParams) => {
return currency_code && !isEmpty(currency_code)
? new Intl.NumberFormat(locale, {
style: "currency",
currency: currency_code,
minimumFractionDigits,
maximumFractionDigits,
}).format(amount)
: amount.toString()
}
type ConvertToLocaleParams = {
amount: number
currency_code: string
minimumFractionDigits?: number
maximumFractionDigits?: number
locale?: string
}