chore(utils): currency epsilon (#14225)
* chore(utils): currency epsilon * pending diff * getEpsilonFromDecimalPrecision
This commit is contained in:
committed by
GitHub
parent
8bb2ac654c
commit
b3cb904e9b
6
.changeset/busy-cars-bathe.md
Normal file
6
.changeset/busy-cars-bathe.md
Normal file
@@ -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 {
|
||||
getLastFulfillmentStatus,
|
||||
getLastPaymentStatus,
|
||||
@@ -113,7 +116,7 @@ describe("Aggregate Order Status", () => {
|
||||
{
|
||||
status: "authorized",
|
||||
captured_amount: 10,
|
||||
refunded_amount: MathBN.sub(10, MEDUSA_EPSILON),
|
||||
refunded_amount: MathBN.sub(10, MEDUSA_DEFAULT_CURRENCY_EPSILON),
|
||||
amount: 10,
|
||||
},
|
||||
{ status: "canceled" },
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
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) => {
|
||||
const PaymentStatus = {
|
||||
@@ -15,6 +20,11 @@ export const getLastPaymentStatus = (order: OrderDetailDTO) => {
|
||||
PARTIALLY_AUTHORIZED: "partially_authorized",
|
||||
}
|
||||
|
||||
const upperCurCode = order.currency_code?.toUpperCase() as string
|
||||
const currencyEpsilon = getEpsilonFromDecimalPrecision(
|
||||
defaultCurrencies[upperCurCode]?.decimal_digits
|
||||
)
|
||||
|
||||
let paymentStatus = {}
|
||||
for (const status in PaymentStatus) {
|
||||
paymentStatus[PaymentStatus[status]] = 0
|
||||
@@ -31,7 +41,7 @@ export const getLastPaymentStatus = (order: OrderDetailDTO) => {
|
||||
paymentCollection.amount,
|
||||
paymentCollection.captured_amount as number
|
||||
),
|
||||
MEDUSA_EPSILON
|
||||
currencyEpsilon
|
||||
)
|
||||
paymentStatus[PaymentStatus.CAPTURED] += isGte ? 1 : 0.5
|
||||
}
|
||||
@@ -42,7 +52,7 @@ export const getLastPaymentStatus = (order: OrderDetailDTO) => {
|
||||
paymentCollection.amount,
|
||||
paymentCollection.refunded_amount as number
|
||||
),
|
||||
MEDUSA_EPSILON
|
||||
currencyEpsilon
|
||||
)
|
||||
paymentStatus[PaymentStatus.REFUNDED] += isGte ? 1 : 0.5
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { BigNumberInput, BigNumberRawValue, IBigNumber } from "@medusajs/types"
|
||||
import { BigNumber as BigNumberConstructor } from "bignumber.js"
|
||||
import { isBigNumber } from "../common/is-big-number"
|
||||
import { isDefined } from "../common/is-defined"
|
||||
import { isString } from "../common/is-string"
|
||||
|
||||
type BigNumberJS = InstanceType<typeof BigNumberConstructor>
|
||||
@@ -150,3 +151,18 @@ export class BigNumber implements IBigNumber {
|
||||
export const MEDUSA_EPSILON = new BigNumber(
|
||||
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 { BigNumber } from "../big-number"
|
||||
import { defaultCurrencies } from "../../defaults/currencies"
|
||||
import { BigNumber, getEpsilonFromDecimalPrecision } from "../big-number"
|
||||
import { calculateCreditLinesTotal } from "../credit-lines"
|
||||
import { GetItemTotalInput, getLineItemsTotals } from "../line-item"
|
||||
import { MathBN } from "../math"
|
||||
@@ -14,6 +15,7 @@ interface TotalsConfig {
|
||||
}
|
||||
|
||||
export interface DecorateCartLikeInputDTO {
|
||||
currency_code?: string
|
||||
credit_lines?: {
|
||||
amount: BigNumberInput
|
||||
}[]
|
||||
@@ -198,6 +200,7 @@ export function decorateCartTotals(
|
||||
creditLines,
|
||||
includesTax: false,
|
||||
taxRate: creditLinesSumTaxRate,
|
||||
currencyCode: cartLike.currency_code,
|
||||
})
|
||||
|
||||
const taxTotal = MathBN.add(itemsTaxTotal, shippingTaxTotal)
|
||||
@@ -276,6 +279,11 @@ export function decorateCartTotals(
|
||||
...(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(
|
||||
MathBN.sub(
|
||||
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
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { BigNumberInput } from "@medusajs/types"
|
||||
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"
|
||||
|
||||
export function calculateCreditLinesTotal({
|
||||
creditLines,
|
||||
includesTax,
|
||||
taxRate,
|
||||
currencyCode,
|
||||
}: {
|
||||
creditLines: { amount: BigNumberInput }[]
|
||||
includesTax?: boolean
|
||||
taxRate?: BigNumberInput
|
||||
currencyCode?: string
|
||||
}) {
|
||||
// the sum of all creditLine amounts excluding tax
|
||||
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 {
|
||||
creditLinesTotal: isZero ? MathBN.convert(0) : creditLinesTotal,
|
||||
creditLinesSubtotal: isZero ? MathBN.convert(0) : creditLinesSubtotal,
|
||||
|
||||
Reference in New Issue
Block a user