chore(utils): currency epsilon (#14225)
* chore(utils): currency epsilon * pending diff * getEpsilonFromDecimalPrecision
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/core-flows": patch
|
||||||
|
"@medusajs/utils": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
chore(utils): currency epsilon
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
import { MathBN, MEDUSA_EPSILON } from "@medusajs/framework/utils"
|
import {
|
||||||
|
MathBN,
|
||||||
|
MEDUSA_DEFAULT_CURRENCY_EPSILON,
|
||||||
|
} from "@medusajs/framework/utils"
|
||||||
import {
|
import {
|
||||||
getLastFulfillmentStatus,
|
getLastFulfillmentStatus,
|
||||||
getLastPaymentStatus,
|
getLastPaymentStatus,
|
||||||
@@ -113,7 +116,7 @@ describe("Aggregate Order Status", () => {
|
|||||||
{
|
{
|
||||||
status: "authorized",
|
status: "authorized",
|
||||||
captured_amount: 10,
|
captured_amount: 10,
|
||||||
refunded_amount: MathBN.sub(10, MEDUSA_EPSILON),
|
refunded_amount: MathBN.sub(10, MEDUSA_DEFAULT_CURRENCY_EPSILON),
|
||||||
amount: 10,
|
amount: 10,
|
||||||
},
|
},
|
||||||
{ status: "canceled" },
|
{ status: "canceled" },
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import type { OrderDetailDTO } from "@medusajs/framework/types"
|
import type { OrderDetailDTO } from "@medusajs/framework/types"
|
||||||
import { isDefined, MathBN, MEDUSA_EPSILON } from "@medusajs/framework/utils"
|
import {
|
||||||
|
defaultCurrencies,
|
||||||
|
getEpsilonFromDecimalPrecision,
|
||||||
|
isDefined,
|
||||||
|
MathBN,
|
||||||
|
} from "@medusajs/framework/utils"
|
||||||
|
|
||||||
export const getLastPaymentStatus = (order: OrderDetailDTO) => {
|
export const getLastPaymentStatus = (order: OrderDetailDTO) => {
|
||||||
const PaymentStatus = {
|
const PaymentStatus = {
|
||||||
@@ -15,6 +20,11 @@ export const getLastPaymentStatus = (order: OrderDetailDTO) => {
|
|||||||
PARTIALLY_AUTHORIZED: "partially_authorized",
|
PARTIALLY_AUTHORIZED: "partially_authorized",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const upperCurCode = order.currency_code?.toUpperCase() as string
|
||||||
|
const currencyEpsilon = getEpsilonFromDecimalPrecision(
|
||||||
|
defaultCurrencies[upperCurCode]?.decimal_digits
|
||||||
|
)
|
||||||
|
|
||||||
let paymentStatus = {}
|
let paymentStatus = {}
|
||||||
for (const status in PaymentStatus) {
|
for (const status in PaymentStatus) {
|
||||||
paymentStatus[PaymentStatus[status]] = 0
|
paymentStatus[PaymentStatus[status]] = 0
|
||||||
@@ -31,7 +41,7 @@ export const getLastPaymentStatus = (order: OrderDetailDTO) => {
|
|||||||
paymentCollection.amount,
|
paymentCollection.amount,
|
||||||
paymentCollection.captured_amount as number
|
paymentCollection.captured_amount as number
|
||||||
),
|
),
|
||||||
MEDUSA_EPSILON
|
currencyEpsilon
|
||||||
)
|
)
|
||||||
paymentStatus[PaymentStatus.CAPTURED] += isGte ? 1 : 0.5
|
paymentStatus[PaymentStatus.CAPTURED] += isGte ? 1 : 0.5
|
||||||
}
|
}
|
||||||
@@ -42,7 +52,7 @@ export const getLastPaymentStatus = (order: OrderDetailDTO) => {
|
|||||||
paymentCollection.amount,
|
paymentCollection.amount,
|
||||||
paymentCollection.refunded_amount as number
|
paymentCollection.refunded_amount as number
|
||||||
),
|
),
|
||||||
MEDUSA_EPSILON
|
currencyEpsilon
|
||||||
)
|
)
|
||||||
paymentStatus[PaymentStatus.REFUNDED] += isGte ? 1 : 0.5
|
paymentStatus[PaymentStatus.REFUNDED] += isGte ? 1 : 0.5
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { BigNumberInput, BigNumberRawValue, IBigNumber } from "@medusajs/types"
|
import { BigNumberInput, BigNumberRawValue, IBigNumber } from "@medusajs/types"
|
||||||
import { BigNumber as BigNumberConstructor } from "bignumber.js"
|
import { BigNumber as BigNumberConstructor } from "bignumber.js"
|
||||||
import { isBigNumber } from "../common/is-big-number"
|
import { isBigNumber } from "../common/is-big-number"
|
||||||
|
import { isDefined } from "../common/is-defined"
|
||||||
import { isString } from "../common/is-string"
|
import { isString } from "../common/is-string"
|
||||||
|
|
||||||
type BigNumberJS = InstanceType<typeof BigNumberConstructor>
|
type BigNumberJS = InstanceType<typeof BigNumberConstructor>
|
||||||
@@ -150,3 +151,18 @@ export class BigNumber implements IBigNumber {
|
|||||||
export const MEDUSA_EPSILON = new BigNumber(
|
export const MEDUSA_EPSILON = new BigNumber(
|
||||||
process.env.MEDUSA_EPSILON || "0.0001"
|
process.env.MEDUSA_EPSILON || "0.0001"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const MEDUSA_DEFAULT_CURRENCY_EPSILON = new BigNumber(
|
||||||
|
process.env.MEDUSA_DEFAULT_CURRENCY_EPSILON || "0.01"
|
||||||
|
)
|
||||||
|
|
||||||
|
export const getEpsilonFromDecimalPrecision = (decimalDigits?: number) => {
|
||||||
|
if (!isDefined(decimalDigits)) {
|
||||||
|
return MEDUSA_DEFAULT_CURRENCY_EPSILON
|
||||||
|
}
|
||||||
|
|
||||||
|
const epsilon = new BigNumberJS(1).dividedBy(
|
||||||
|
new BigNumberJS(10).pow(decimalDigits)
|
||||||
|
)
|
||||||
|
return new BigNumber(epsilon.toString())
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { BigNumberInput, CartLikeWithTotals } from "@medusajs/types"
|
import { BigNumberInput, CartLikeWithTotals } from "@medusajs/types"
|
||||||
import { BigNumber } from "../big-number"
|
import { defaultCurrencies } from "../../defaults/currencies"
|
||||||
|
import { BigNumber, getEpsilonFromDecimalPrecision } from "../big-number"
|
||||||
import { calculateCreditLinesTotal } from "../credit-lines"
|
import { calculateCreditLinesTotal } from "../credit-lines"
|
||||||
import { GetItemTotalInput, getLineItemsTotals } from "../line-item"
|
import { GetItemTotalInput, getLineItemsTotals } from "../line-item"
|
||||||
import { MathBN } from "../math"
|
import { MathBN } from "../math"
|
||||||
@@ -14,6 +15,7 @@ interface TotalsConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface DecorateCartLikeInputDTO {
|
export interface DecorateCartLikeInputDTO {
|
||||||
|
currency_code?: string
|
||||||
credit_lines?: {
|
credit_lines?: {
|
||||||
amount: BigNumberInput
|
amount: BigNumberInput
|
||||||
}[]
|
}[]
|
||||||
@@ -198,6 +200,7 @@ export function decorateCartTotals(
|
|||||||
creditLines,
|
creditLines,
|
||||||
includesTax: false,
|
includesTax: false,
|
||||||
taxRate: creditLinesSumTaxRate,
|
taxRate: creditLinesSumTaxRate,
|
||||||
|
currencyCode: cartLike.currency_code,
|
||||||
})
|
})
|
||||||
|
|
||||||
const taxTotal = MathBN.add(itemsTaxTotal, shippingTaxTotal)
|
const taxTotal = MathBN.add(itemsTaxTotal, shippingTaxTotal)
|
||||||
@@ -276,6 +279,11 @@ export function decorateCartTotals(
|
|||||||
...(cart.items?.map((item) => item.return_requested_total ?? 0) ?? [0])
|
...(cart.items?.map((item) => item.return_requested_total ?? 0) ?? [0])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const upperCurCode = cart.currency_code?.toUpperCase() as string
|
||||||
|
const currencyEpsilon = getEpsilonFromDecimalPrecision(
|
||||||
|
defaultCurrencies[upperCurCode]?.decimal_digits
|
||||||
|
)
|
||||||
|
|
||||||
const pendingDifference = new BigNumber(
|
const pendingDifference = new BigNumber(
|
||||||
MathBN.sub(
|
MathBN.sub(
|
||||||
MathBN.sub(cart.total, pendingReturnTotal),
|
MathBN.sub(cart.total, pendingReturnTotal),
|
||||||
@@ -283,7 +291,12 @@ export function decorateCartTotals(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
cart.summary.pending_difference = pendingDifference
|
cart.summary.pending_difference = MathBN.lte(
|
||||||
|
MathBN.abs(pendingDifference),
|
||||||
|
currencyEpsilon
|
||||||
|
)
|
||||||
|
? MathBN.convert(0)
|
||||||
|
: pendingDifference
|
||||||
}
|
}
|
||||||
|
|
||||||
return cart
|
return cart
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
import { BigNumberInput } from "@medusajs/types"
|
import { BigNumberInput } from "@medusajs/types"
|
||||||
import { isDefined } from "../../common"
|
import { isDefined } from "../../common"
|
||||||
import { BigNumber, MEDUSA_EPSILON } from "../big-number"
|
import { defaultCurrencies } from "../../defaults/currencies"
|
||||||
|
import { BigNumber, getEpsilonFromDecimalPrecision } from "../big-number"
|
||||||
import { MathBN } from "../math"
|
import { MathBN } from "../math"
|
||||||
|
|
||||||
export function calculateCreditLinesTotal({
|
export function calculateCreditLinesTotal({
|
||||||
creditLines,
|
creditLines,
|
||||||
includesTax,
|
includesTax,
|
||||||
taxRate,
|
taxRate,
|
||||||
|
currencyCode,
|
||||||
}: {
|
}: {
|
||||||
creditLines: { amount: BigNumberInput }[]
|
creditLines: { amount: BigNumberInput }[]
|
||||||
includesTax?: boolean
|
includesTax?: boolean
|
||||||
taxRate?: BigNumberInput
|
taxRate?: BigNumberInput
|
||||||
|
currencyCode?: string
|
||||||
}) {
|
}) {
|
||||||
// the sum of all creditLine amounts excluding tax
|
// the sum of all creditLine amounts excluding tax
|
||||||
let creditLinesSubtotal = MathBN.convert(0)
|
let creditLinesSubtotal = MathBN.convert(0)
|
||||||
@@ -46,7 +49,12 @@ export function calculateCreditLinesTotal({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const isZero = MathBN.lte(creditLinesTotal, MEDUSA_EPSILON)
|
const upperCurCode = currencyCode?.toUpperCase() as string
|
||||||
|
const currencyEpsilon = getEpsilonFromDecimalPrecision(
|
||||||
|
defaultCurrencies[upperCurCode]?.decimal_digits
|
||||||
|
)
|
||||||
|
|
||||||
|
const isZero = MathBN.lte(creditLinesTotal, currencyEpsilon)
|
||||||
return {
|
return {
|
||||||
creditLinesTotal: isZero ? MathBN.convert(0) : creditLinesTotal,
|
creditLinesTotal: isZero ? MathBN.convert(0) : creditLinesTotal,
|
||||||
creditLinesSubtotal: isZero ? MathBN.convert(0) : creditLinesSubtotal,
|
creditLinesSubtotal: isZero ? MathBN.convert(0) : creditLinesSubtotal,
|
||||||
|
|||||||
Reference in New Issue
Block a user