feat(order): receive return and additional calculations (#7314)
This commit is contained in:
committed by
GitHub
parent
d680c7ee4c
commit
4ef70d37bf
@@ -634,4 +634,94 @@ describe("Total calculation", function () {
|
||||
original_shipping_total: 27.5,
|
||||
})
|
||||
})
|
||||
|
||||
it("should calculate order with items + taxes + adjustments", function () {
|
||||
const cart = {
|
||||
items: [
|
||||
{
|
||||
unit_price: 50,
|
||||
quantity: 2,
|
||||
fulfilled_quantity: 2,
|
||||
shipped_quantity: 2,
|
||||
return_requested_quantity: 2,
|
||||
return_received_quantity: 1,
|
||||
return_dismissed_quantity: 1,
|
||||
written_off_quantity: 0,
|
||||
tax_lines: [
|
||||
{
|
||||
rate: 10,
|
||||
},
|
||||
],
|
||||
adjustments: [
|
||||
{
|
||||
amount: 20,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const serialized = JSON.parse(JSON.stringify(decorateCartTotals(cart)))
|
||||
|
||||
expect(serialized).toEqual({
|
||||
items: [
|
||||
{
|
||||
unit_price: 50,
|
||||
quantity: 2,
|
||||
fulfilled_quantity: 2,
|
||||
shipped_quantity: 2,
|
||||
return_requested_quantity: 2,
|
||||
return_received_quantity: 1,
|
||||
return_dismissed_quantity: 1,
|
||||
written_off_quantity: 0,
|
||||
tax_lines: [
|
||||
{
|
||||
rate: 10,
|
||||
total: 8,
|
||||
subtotal: 10,
|
||||
},
|
||||
],
|
||||
adjustments: [
|
||||
{
|
||||
amount: 20,
|
||||
subtotal: 20,
|
||||
total: 22,
|
||||
},
|
||||
],
|
||||
subtotal: 100,
|
||||
total: 88,
|
||||
original_total: 110,
|
||||
discount_total: 20,
|
||||
discount_tax_total: 2,
|
||||
tax_total: 8,
|
||||
original_tax_total: 10,
|
||||
fulfilled_total: 88,
|
||||
shipped_total: 88,
|
||||
return_requested_total: 88,
|
||||
return_received_total: 44,
|
||||
return_dismissed_total: 44,
|
||||
write_off_total: 0,
|
||||
},
|
||||
],
|
||||
total: 88,
|
||||
subtotal: 100,
|
||||
tax_total: 8,
|
||||
discount_total: 20,
|
||||
discount_tax_total: 2,
|
||||
original_total: 90,
|
||||
original_tax_total: 10,
|
||||
item_total: 88,
|
||||
item_subtotal: 100,
|
||||
item_tax_total: 8,
|
||||
original_item_total: 110,
|
||||
original_item_subtotal: 100,
|
||||
original_item_tax_total: 10,
|
||||
fulfilled_total: 88,
|
||||
shipped_total: 88,
|
||||
return_requested_total: 88,
|
||||
return_received_total: 44,
|
||||
return_dismissed_total: 44,
|
||||
write_off_total: 0,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -43,6 +43,15 @@ export function decorateCartTotals(
|
||||
): CartLikeWithTotals {
|
||||
transformPropertiesToBigNumber(cartLike)
|
||||
|
||||
const optionalFields = {
|
||||
fulfilled_quantity: "fulfilled_total",
|
||||
shipped_quantity: "shipped_total",
|
||||
return_requested_quantity: "return_requested_total",
|
||||
return_received_quantity: "return_received_total",
|
||||
return_dismissed_quantity: "return_dismissed_total",
|
||||
written_off_quantity: "write_off_total",
|
||||
}
|
||||
|
||||
const items = (cartLike.items ?? []) as unknown as GetItemTotalInput[]
|
||||
const shippingMethods = (cartLike.shipping_methods ??
|
||||
[]) as unknown as GetShippingMethodTotalInput[]
|
||||
@@ -51,12 +60,15 @@ export function decorateCartTotals(
|
||||
|
||||
const itemsTotals = getLineItemsTotals(items, {
|
||||
includeTax,
|
||||
extraQuantityFields: optionalFields,
|
||||
})
|
||||
|
||||
const shippingMethodsTotals = getShippingMethodsTotals(shippingMethods, {
|
||||
includeTax,
|
||||
})
|
||||
|
||||
const extraTotals = {}
|
||||
|
||||
let subtotal = MathBN.convert(0)
|
||||
|
||||
let discountTotal = MathBN.convert(0)
|
||||
@@ -117,6 +129,13 @@ export function decorateCartTotals(
|
||||
itemOriginalTaxTotal
|
||||
)
|
||||
|
||||
for (const key of Object.values(optionalFields)) {
|
||||
if (key in itemTotals) {
|
||||
extraTotals[key] ??= MathBN.convert(0)
|
||||
extraTotals[key] = MathBN.add(extraTotals[key], itemTotals[key] ?? 0)
|
||||
}
|
||||
}
|
||||
|
||||
return itemTotals
|
||||
})
|
||||
|
||||
@@ -213,6 +232,10 @@ export function decorateCartTotals(
|
||||
cart.original_item_total = new BigNumber(itemsOriginalTotal)
|
||||
cart.original_item_subtotal = new BigNumber(itemsOriginalSubtotal)
|
||||
cart.original_item_tax_total = new BigNumber(itemsOriginalTaxTotal)
|
||||
|
||||
for (const key of Object.keys(extraTotals)) {
|
||||
cart[key] = new BigNumber(extraTotals[key])
|
||||
}
|
||||
}
|
||||
|
||||
if (cart.shipping_methods) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import { calculateTaxTotal } from "../tax"
|
||||
|
||||
interface GetLineItemsTotalsContext {
|
||||
includeTax?: boolean
|
||||
extraQuantityFields?: Record<string, string>
|
||||
}
|
||||
|
||||
export interface GetItemTotalInput {
|
||||
@@ -15,6 +16,13 @@ export interface GetItemTotalInput {
|
||||
is_tax_inclusive?: boolean
|
||||
tax_lines?: Pick<TaxLineDTO, "rate">[]
|
||||
adjustments?: Pick<AdjustmentLineDTO, "amount">[]
|
||||
|
||||
fulfilled_quantity?: BigNumber
|
||||
shipped_quantity?: BigNumber
|
||||
return_requested_quantity?: BigNumber
|
||||
return_received_quantity?: BigNumber
|
||||
return_dismissed_quantity?: BigNumber
|
||||
written_off_quantity?: BigNumber
|
||||
}
|
||||
|
||||
export interface GetItemTotalOutput {
|
||||
@@ -31,6 +39,13 @@ export interface GetItemTotalOutput {
|
||||
|
||||
tax_total: BigNumber
|
||||
original_tax_total: BigNumber
|
||||
|
||||
fulfilled_total?: BigNumber
|
||||
shipped_total?: BigNumber
|
||||
return_requested_total?: BigNumber
|
||||
return_received_total?: BigNumber
|
||||
return_dismissed_total?: BigNumber
|
||||
write_off_total?: BigNumber
|
||||
}
|
||||
|
||||
export function getLineItemsTotals(
|
||||
@@ -43,6 +58,7 @@ export function getLineItemsTotals(
|
||||
for (const item of items) {
|
||||
itemsTotals[item.id ?? index] = getLineItemTotals(item, {
|
||||
includeTax: context.includeTax || item.is_tax_inclusive,
|
||||
extraQuantityFields: context.extraQuantityFields,
|
||||
})
|
||||
index++
|
||||
}
|
||||
@@ -122,5 +138,17 @@ function getLineItemTotals(
|
||||
totals.original_total = new BigNumber(originalTotal)
|
||||
}
|
||||
|
||||
const totalPerUnit = MathBN.div(totals.total, item.quantity)
|
||||
const optionalFields = {
|
||||
...(context.extraQuantityFields ?? {}),
|
||||
}
|
||||
|
||||
for (const field in optionalFields) {
|
||||
if (field in item) {
|
||||
const totalField = optionalFields[field]
|
||||
totals[totalField] = new BigNumber(MathBN.mult(totalPerUnit, item[field]))
|
||||
}
|
||||
}
|
||||
|
||||
return totals
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user