fix(utils,core-flows): subtotal calculation and returns location (#13497)
* fix(utils,core-flows): subtotal calculation and returns location * changeset * fix test * var * rm extra field from test * fix original total * fix partial refunds and pending difference * fix test * fix test * test * extract to util * original total and update payment when receive return * original_subtotal * default fields * test * calculate pending difference * revert claims test * pending difference * creadit line fix * if
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/utils": patch
|
||||||
|
"@medusajs/types": patch
|
||||||
|
"@medusajs/core-flows": patch
|
||||||
|
"@medusajs/order": patch
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix(utils): subtotal calculation discounting returned items
|
||||||
@@ -22,8 +22,10 @@ medusaIntegrationTestRunner({
|
|||||||
let returnReason
|
let returnReason
|
||||||
let inventoryItem
|
let inventoryItem
|
||||||
let inventoryItemExtra
|
let inventoryItemExtra
|
||||||
|
let inventoryItemExtra2
|
||||||
let location
|
let location
|
||||||
let productExtra
|
let productExtra
|
||||||
|
let productExtra2
|
||||||
const shippingProviderId = "manual_test-provider"
|
const shippingProviderId = "manual_test-provider"
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@@ -123,6 +125,31 @@ medusaIntegrationTestRunner({
|
|||||||
)
|
)
|
||||||
).data.product
|
).data.product
|
||||||
|
|
||||||
|
productExtra2 = (
|
||||||
|
await api.post(
|
||||||
|
"/admin/products",
|
||||||
|
{
|
||||||
|
title: "Extra product 2, same price",
|
||||||
|
shipping_profile_id: shippingProfile.id,
|
||||||
|
options: [{ title: "size", values: ["large", "small"] }],
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
title: "my variant 2",
|
||||||
|
sku: "variant-sku-2",
|
||||||
|
options: { size: "large" },
|
||||||
|
prices: [
|
||||||
|
{
|
||||||
|
currency_code: "usd",
|
||||||
|
amount: 25,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
).data.product
|
||||||
|
|
||||||
returnReason = (
|
returnReason = (
|
||||||
await api.post(
|
await api.post(
|
||||||
"/admin/return-reasons",
|
"/admin/return-reasons",
|
||||||
@@ -269,6 +296,10 @@ medusaIntegrationTestRunner({
|
|||||||
await api.get(`/admin/inventory-items?sku=variant-sku`, adminHeaders)
|
await api.get(`/admin/inventory-items?sku=variant-sku`, adminHeaders)
|
||||||
).data.inventory_items[0]
|
).data.inventory_items[0]
|
||||||
|
|
||||||
|
inventoryItemExtra2 = (
|
||||||
|
await api.get(`/admin/inventory-items?sku=variant-sku-2`, adminHeaders)
|
||||||
|
).data.inventory_items[0]
|
||||||
|
|
||||||
await api.post(
|
await api.post(
|
||||||
`/admin/inventory-items/${inventoryItemExtra.id}/location-levels`,
|
`/admin/inventory-items/${inventoryItemExtra.id}/location-levels`,
|
||||||
{
|
{
|
||||||
@@ -278,6 +309,15 @@ medusaIntegrationTestRunner({
|
|||||||
adminHeaders
|
adminHeaders
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await api.post(
|
||||||
|
`/admin/inventory-items/${inventoryItemExtra2.id}/location-levels`,
|
||||||
|
{
|
||||||
|
location_id: location.id,
|
||||||
|
stocked_quantity: 2,
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
const remoteLink = container.resolve(
|
const remoteLink = container.resolve(
|
||||||
ContainerRegistrationKeys.REMOTE_LINK
|
ContainerRegistrationKeys.REMOTE_LINK
|
||||||
)
|
)
|
||||||
@@ -323,6 +363,14 @@ medusaIntegrationTestRunner({
|
|||||||
inventory_item_id: inventoryItemExtra.id,
|
inventory_item_id: inventoryItemExtra.id,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
[Modules.PRODUCT]: {
|
||||||
|
variant_id: productExtra2.variants[0].id,
|
||||||
|
},
|
||||||
|
[Modules.INVENTORY]: {
|
||||||
|
inventory_item_id: inventoryItemExtra2.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
// create reservation for inventory item that is initially on the order
|
// create reservation for inventory item that is initially on the order
|
||||||
@@ -440,6 +488,95 @@ medusaIntegrationTestRunner({
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe("Exchanges lifecycle", () => {
|
describe("Exchanges lifecycle", () => {
|
||||||
|
it("test full exchange flow", async () => {
|
||||||
|
const orderBefore = (
|
||||||
|
await api.get(`/admin/orders/${order.id}`, adminHeaders)
|
||||||
|
).data.order
|
||||||
|
|
||||||
|
let result = await api.post(
|
||||||
|
"/admin/exchanges",
|
||||||
|
{
|
||||||
|
order_id: order.id,
|
||||||
|
description: "Test",
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(result.data.exchange.created_by).toEqual(expect.any(String))
|
||||||
|
|
||||||
|
const exchangeId = result.data.exchange.id
|
||||||
|
|
||||||
|
const item = order.items[0]
|
||||||
|
|
||||||
|
result = await api.post(
|
||||||
|
`/admin/exchanges/${exchangeId}/inbound/items`,
|
||||||
|
{
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
id: item.id,
|
||||||
|
reason_id: returnReason.id,
|
||||||
|
quantity: 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
// New Item
|
||||||
|
result = await api.post(
|
||||||
|
`/admin/exchanges/${exchangeId}/outbound/items`,
|
||||||
|
{
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
variant_id: productExtra2.variants[0].id,
|
||||||
|
quantity: 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
result = await api.post(
|
||||||
|
`/admin/exchanges/${exchangeId}/request`,
|
||||||
|
{},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
const returnId = result.data.exchange.return_id
|
||||||
|
|
||||||
|
result = (await api.get(`/admin/orders/${order.id}`, adminHeaders)).data
|
||||||
|
.order
|
||||||
|
|
||||||
|
expect(orderBefore.total).toBe(61)
|
||||||
|
expect(result.total).toBe(112)
|
||||||
|
|
||||||
|
// receive return
|
||||||
|
await api.post(`/admin/returns/${returnId}/receive`, {}, adminHeaders)
|
||||||
|
await api.post(
|
||||||
|
`/admin/returns/${returnId}/receive-items`,
|
||||||
|
{
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
id: item.id,
|
||||||
|
quantity: 2,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
await api.post(
|
||||||
|
`/admin/returns/${returnId}/receive/confirm`,
|
||||||
|
{},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
result = (await api.get(`/admin/orders/${order.id}`, adminHeaders)).data
|
||||||
|
.order
|
||||||
|
|
||||||
|
expect(orderBefore.total).toBe(61)
|
||||||
|
expect(result.total).toBe(62) // +1 is from taxes of the new item
|
||||||
|
})
|
||||||
|
|
||||||
it("Full flow with 2 orders", async () => {
|
it("Full flow with 2 orders", async () => {
|
||||||
let result = await api.post(
|
let result = await api.post(
|
||||||
"/admin/exchanges",
|
"/admin/exchanges",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
AdminStockLocation,
|
AdminStockLocation,
|
||||||
MedusaContainer,
|
MedusaContainer,
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
|
import { ContainerRegistrationKeys, Modules } from "@medusajs/utils"
|
||||||
import {
|
import {
|
||||||
adminHeaders,
|
adminHeaders,
|
||||||
generatePublishableKey,
|
generatePublishableKey,
|
||||||
@@ -175,6 +176,26 @@ export async function createOrderSeeder({
|
|||||||
adminHeaders
|
adminHeaders
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const remoteLink = container.resolve(ContainerRegistrationKeys.LINK)
|
||||||
|
await remoteLink.create([
|
||||||
|
{
|
||||||
|
[Modules.SALES_CHANNEL]: {
|
||||||
|
sales_channel_id: salesChannel.id,
|
||||||
|
},
|
||||||
|
[Modules.STOCK_LOCATION]: {
|
||||||
|
stock_location_id: stockLocation.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[Modules.PRODUCT]: {
|
||||||
|
variant_id: product.variants[0].id,
|
||||||
|
},
|
||||||
|
[Modules.INVENTORY]: {
|
||||||
|
inventory_item_id: inventoryItem.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create shipping options for each shipping profile provided
|
* Create shipping options for each shipping profile provided
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -32,7 +32,35 @@ medusaIntegrationTestRunner({
|
|||||||
adminHeaders
|
adminHeaders
|
||||||
)
|
)
|
||||||
|
|
||||||
await api.post(`/admin/claims/${claim.id}/request`, {}, adminHeaders)
|
const createdClaim = await api.post(
|
||||||
|
`/admin/claims/${claim.id}/request`,
|
||||||
|
{},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
const returnOrder = createdClaim.data.return
|
||||||
|
const returnId = returnOrder.id
|
||||||
|
await api.post(`/admin/returns/${returnId}/receive`, {}, adminHeaders)
|
||||||
|
|
||||||
|
let lineItem = returnOrder.items[0].item
|
||||||
|
await api.post(
|
||||||
|
`/admin/returns/${returnId}/receive-items`,
|
||||||
|
{
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
id: lineItem.id,
|
||||||
|
quantity: returnOrder.items[0].quantity,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
await api.post(
|
||||||
|
`/admin/returns/${returnId}/receive/confirm`,
|
||||||
|
{},
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@@ -64,10 +92,6 @@ medusaIntegrationTestRunner({
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe("with outstanding amount due to claim", () => {
|
describe("with outstanding amount due to claim", () => {
|
||||||
beforeEach(async () => {
|
|
||||||
await createClaim({ order })
|
|
||||||
})
|
|
||||||
|
|
||||||
it("should capture an authorized payment", async () => {
|
it("should capture an authorized payment", async () => {
|
||||||
const payment = order.payment_collections[0].payments[0]
|
const payment = order.payment_collections[0].payments[0]
|
||||||
|
|
||||||
@@ -189,6 +213,8 @@ medusaIntegrationTestRunner({
|
|||||||
adminHeaders
|
adminHeaders
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await createClaim({ order })
|
||||||
|
|
||||||
const refundReason = (
|
const refundReason = (
|
||||||
await api.post(
|
await api.post(
|
||||||
`/admin/refund-reasons`,
|
`/admin/refund-reasons`,
|
||||||
@@ -253,6 +279,8 @@ medusaIntegrationTestRunner({
|
|||||||
)
|
)
|
||||||
).data.refund_reason
|
).data.refund_reason
|
||||||
|
|
||||||
|
await createClaim({ order })
|
||||||
|
|
||||||
await api.post(
|
await api.post(
|
||||||
`/admin/payments/${payment.id}/refund`,
|
`/admin/payments/${payment.id}/refund`,
|
||||||
{
|
{
|
||||||
@@ -311,6 +339,8 @@ medusaIntegrationTestRunner({
|
|||||||
adminHeaders
|
adminHeaders
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await createClaim({ order })
|
||||||
|
|
||||||
await api.post(
|
await api.post(
|
||||||
`/admin/payments/${payment.id}/refund`,
|
`/admin/payments/${payment.id}/refund`,
|
||||||
{ amount: 25 },
|
{ amount: 25 },
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
|
||||||
import {
|
import {
|
||||||
ContainerRegistrationKeys,
|
ContainerRegistrationKeys,
|
||||||
Modules,
|
Modules,
|
||||||
RuleOperator,
|
RuleOperator,
|
||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
|
|
||||||
import {
|
import {
|
||||||
adminHeaders,
|
adminHeaders,
|
||||||
createAdminUser,
|
createAdminUser,
|
||||||
@@ -478,6 +478,16 @@ medusaIntegrationTestRunner({
|
|||||||
adminHeaders
|
adminHeaders
|
||||||
)
|
)
|
||||||
|
|
||||||
|
expect(result.data.order_preview.summary).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
transaction_total: 0,
|
||||||
|
current_order_total: 61,
|
||||||
|
pending_difference: 11,
|
||||||
|
paid_total: 0,
|
||||||
|
refunded_total: 0,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
expect(result.data.order_preview).toEqual(
|
expect(result.data.order_preview).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: order.id,
|
id: order.id,
|
||||||
|
|||||||
@@ -1,8 +1,18 @@
|
|||||||
import { createOrderChangeWorkflow, createOrderWorkflow, } from "@medusajs/core-flows"
|
import {
|
||||||
|
createOrderChangeWorkflow,
|
||||||
|
createOrderWorkflow,
|
||||||
|
} from "@medusajs/core-flows"
|
||||||
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
|
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
|
||||||
import { CreateOrderLineItemDTO, IOrderModuleService, OrderDTO, } from "@medusajs/types"
|
import {
|
||||||
|
CreateOrderLineItemDTO,
|
||||||
|
IOrderModuleService,
|
||||||
|
OrderDTO,
|
||||||
|
} from "@medusajs/types"
|
||||||
import { Modules, ProductStatus } from "@medusajs/utils"
|
import { Modules, ProductStatus } from "@medusajs/utils"
|
||||||
import { adminHeaders, createAdminUser, } from "../../../helpers/create-admin-user"
|
import {
|
||||||
|
adminHeaders,
|
||||||
|
createAdminUser,
|
||||||
|
} from "../../../helpers/create-admin-user"
|
||||||
|
|
||||||
jest.setTimeout(50000)
|
jest.setTimeout(50000)
|
||||||
|
|
||||||
@@ -288,6 +298,7 @@ medusaIntegrationTestRunner({
|
|||||||
discount_total: 1.1,
|
discount_total: 1.1,
|
||||||
discount_tax_total: 0.1,
|
discount_tax_total: 0.1,
|
||||||
original_total: 61,
|
original_total: 61,
|
||||||
|
original_subtotal: 60,
|
||||||
original_tax_total: 1,
|
original_tax_total: 1,
|
||||||
item_total: 50,
|
item_total: 50,
|
||||||
item_subtotal: 50,
|
item_subtotal: 50,
|
||||||
@@ -433,6 +444,7 @@ medusaIntegrationTestRunner({
|
|||||||
subtotal: 50,
|
subtotal: 50,
|
||||||
total: 50,
|
total: 50,
|
||||||
original_total: 50,
|
original_total: 50,
|
||||||
|
original_subtotal: 50,
|
||||||
discount_total: 0,
|
discount_total: 0,
|
||||||
discount_tax_total: 0,
|
discount_tax_total: 0,
|
||||||
discount_subtotal: 0,
|
discount_subtotal: 0,
|
||||||
@@ -490,6 +502,10 @@ medusaIntegrationTestRunner({
|
|||||||
precision: 20,
|
precision: 20,
|
||||||
value: "0",
|
value: "0",
|
||||||
},
|
},
|
||||||
|
raw_original_subtotal: {
|
||||||
|
precision: 20,
|
||||||
|
value: "50",
|
||||||
|
},
|
||||||
raw_return_dismissed_total: {
|
raw_return_dismissed_total: {
|
||||||
precision: 20,
|
precision: 20,
|
||||||
value: "0",
|
value: "0",
|
||||||
|
|||||||
@@ -31,24 +31,43 @@ export const addOrderTransactionStep = createStep(
|
|||||||
return new StepResponse(null)
|
return new StepResponse(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const existingQuery: any[] = []
|
||||||
for (const trx of trxsData) {
|
for (const trx of trxsData) {
|
||||||
const existing = await service.listOrderTransactions(
|
existingQuery.push({
|
||||||
{
|
order_id: trx.order_id,
|
||||||
order_id: trx.order_id,
|
reference: trx.reference,
|
||||||
reference: trx.reference,
|
reference_id: trx.reference_id,
|
||||||
reference_id: trx.reference_id,
|
})
|
||||||
},
|
}
|
||||||
{
|
|
||||||
select: ["id"],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (existing.length) {
|
const existing = await service.listOrderTransactions(
|
||||||
return new StepResponse(null)
|
{
|
||||||
|
$or: existingQuery,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
select: ["order_id", "reference", "reference_id"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const existingSet = new Set<string>(
|
||||||
|
existing.map(
|
||||||
|
(trx) => `${trx.order_id}-${trx.reference}-${trx.reference_id}`
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
const selectedData: CreateOrderTransactionDTO[] = []
|
||||||
|
for (const trx of trxsData) {
|
||||||
|
if (
|
||||||
|
!existingSet.has(`${trx.order_id}-${trx.reference}-${trx.reference_id}`)
|
||||||
|
) {
|
||||||
|
selectedData.push(trx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const created = await service.addOrderTransactions(trxsData)
|
if (!selectedData.length) {
|
||||||
|
return new StepResponse(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
const created = await service.addOrderTransactions(selectedData)
|
||||||
|
|
||||||
return new StepResponse(
|
return new StepResponse(
|
||||||
(Array.isArray(data)
|
(Array.isArray(data)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
MedusaError,
|
MedusaError,
|
||||||
OrderStatus,
|
OrderStatus,
|
||||||
arrayDifference,
|
arrayDifference,
|
||||||
|
deepFlatMap,
|
||||||
isPresent,
|
isPresent,
|
||||||
} from "@medusajs/framework/utils"
|
} from "@medusajs/framework/utils"
|
||||||
|
|
||||||
@@ -21,6 +22,58 @@ export function throwIfOrderIsCancelled({ order }: { order: OrderDTO }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function throwIfManagedItemsNotStockedAtReturnLocation({
|
||||||
|
order,
|
||||||
|
orderReturn,
|
||||||
|
inputItems,
|
||||||
|
}: {
|
||||||
|
order: Pick<OrderDTO, "items">
|
||||||
|
orderReturn: Pick<ReturnDTO, "location_id">
|
||||||
|
inputItems: OrderWorkflow.CreateOrderFulfillmentWorkflowInput["items"]
|
||||||
|
}) {
|
||||||
|
if (!orderReturn?.location_id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const inputItemIds = new Set(inputItems.map((i) => i.id))
|
||||||
|
const requestedOrderItems = order.items?.filter((oi: any) =>
|
||||||
|
inputItemIds.has(oi.id)
|
||||||
|
)
|
||||||
|
|
||||||
|
const invalidManagedItems: string[] = []
|
||||||
|
|
||||||
|
for (const orderItem of requestedOrderItems ?? []) {
|
||||||
|
const variant = (orderItem as any)?.variant
|
||||||
|
if (!variant?.manage_inventory) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
let hasStockAtLocation = false
|
||||||
|
deepFlatMap(
|
||||||
|
orderItem,
|
||||||
|
"variant.inventory_items.inventory.location_levels",
|
||||||
|
({ location_levels }) => {
|
||||||
|
if (location_levels?.location_id === orderReturn.location_id) {
|
||||||
|
hasStockAtLocation = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!hasStockAtLocation) {
|
||||||
|
invalidManagedItems.push(orderItem.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invalidManagedItems.length) {
|
||||||
|
throw new MedusaError(
|
||||||
|
MedusaError.Types.INVALID_DATA,
|
||||||
|
`Cannot request item return at location ${
|
||||||
|
orderReturn.location_id
|
||||||
|
} for managed inventory items: ${invalidManagedItems.join(", ")}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function throwIfItemsDoesNotExistsInOrder({
|
export function throwIfItemsDoesNotExistsInOrder({
|
||||||
order,
|
order,
|
||||||
inputItems,
|
inputItems,
|
||||||
|
|||||||
@@ -6,7 +6,12 @@ import {
|
|||||||
OrderWorkflow,
|
OrderWorkflow,
|
||||||
ReturnDTO,
|
ReturnDTO,
|
||||||
} from "@medusajs/framework/types"
|
} from "@medusajs/framework/types"
|
||||||
import { ChangeActionType, OrderChangeStatus } from "@medusajs/framework/utils"
|
import {
|
||||||
|
ChangeActionType,
|
||||||
|
OrderChangeStatus,
|
||||||
|
deepFlatMap,
|
||||||
|
isDefined,
|
||||||
|
} from "@medusajs/framework/utils"
|
||||||
import {
|
import {
|
||||||
WorkflowData,
|
WorkflowData,
|
||||||
WorkflowResponse,
|
WorkflowResponse,
|
||||||
@@ -23,6 +28,7 @@ import { updateOrderChangesStep } from "../../steps/update-order-changes"
|
|||||||
import {
|
import {
|
||||||
throwIfIsCancelled,
|
throwIfIsCancelled,
|
||||||
throwIfItemsDoesNotExistsInOrder,
|
throwIfItemsDoesNotExistsInOrder,
|
||||||
|
throwIfManagedItemsNotStockedAtReturnLocation,
|
||||||
throwIfOrderChangeIsNotActive,
|
throwIfOrderChangeIsNotActive,
|
||||||
} from "../../utils/order-validation"
|
} from "../../utils/order-validation"
|
||||||
import { createOrderChangeActionsWorkflow } from "../create-order-change-actions"
|
import { createOrderChangeActionsWorkflow } from "../create-order-change-actions"
|
||||||
@@ -105,6 +111,11 @@ export const orderClaimRequestItemReturnValidationStep = createStep(
|
|||||||
throwIfIsCancelled(orderReturn, "Return")
|
throwIfIsCancelled(orderReturn, "Return")
|
||||||
throwIfOrderChangeIsNotActive({ orderChange })
|
throwIfOrderChangeIsNotActive({ orderChange })
|
||||||
throwIfItemsDoesNotExistsInOrder({ order, inputItems: items })
|
throwIfItemsDoesNotExistsInOrder({ order, inputItems: items })
|
||||||
|
throwIfManagedItemsNotStockedAtReturnLocation({
|
||||||
|
order,
|
||||||
|
orderReturn,
|
||||||
|
inputItems: items,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -154,34 +165,23 @@ export const orderClaimRequestItemReturnWorkflow = createWorkflow(
|
|||||||
}).then(() => {
|
}).then(() => {
|
||||||
return useRemoteQueryStep({
|
return useRemoteQueryStep({
|
||||||
entry_point: "return",
|
entry_point: "return",
|
||||||
fields: ["id", "status", "order_id", "canceled_at"],
|
fields: ["id", "status", "order_id", "location_id", "canceled_at"],
|
||||||
variables: { id: orderClaim.return_id },
|
variables: { id: orderClaim.return_id },
|
||||||
list: false,
|
list: false,
|
||||||
throw_if_key_not_found: true,
|
throw_if_key_not_found: true,
|
||||||
}).config({ name: "return-query" }) as ReturnDTO
|
}).config({ name: "return-query" }) as ReturnDTO
|
||||||
})
|
})
|
||||||
|
|
||||||
const createdReturn = when({ orderClaim }, ({ orderClaim }) => {
|
|
||||||
return !orderClaim.return_id
|
|
||||||
}).then(() => {
|
|
||||||
return createReturnsStep([
|
|
||||||
{
|
|
||||||
order_id: orderClaim.order_id,
|
|
||||||
claim_id: orderClaim.id,
|
|
||||||
},
|
|
||||||
])
|
|
||||||
})
|
|
||||||
|
|
||||||
const orderReturn: ReturnDTO = transform(
|
|
||||||
{ createdReturn, existingOrderReturn },
|
|
||||||
({ createdReturn, existingOrderReturn }) => {
|
|
||||||
return existingOrderReturn ?? (createdReturn?.[0] as ReturnDTO)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const order: OrderDTO = useRemoteQueryStep({
|
const order: OrderDTO = useRemoteQueryStep({
|
||||||
entry_point: "orders",
|
entry_point: "orders",
|
||||||
fields: ["id", "status", "items.*"],
|
fields: [
|
||||||
|
"id",
|
||||||
|
"status",
|
||||||
|
"items.*",
|
||||||
|
"items.variant.manage_inventory",
|
||||||
|
"items.variant.inventory_items.inventory_item_id",
|
||||||
|
"items.variant.inventory_items.inventory.location_levels.location_id",
|
||||||
|
],
|
||||||
variables: { id: orderClaim.order_id },
|
variables: { id: orderClaim.order_id },
|
||||||
list: false,
|
list: false,
|
||||||
throw_if_key_not_found: true,
|
throw_if_key_not_found: true,
|
||||||
@@ -202,6 +202,51 @@ export const orderClaimRequestItemReturnWorkflow = createWorkflow(
|
|||||||
name: "order-change-query",
|
name: "order-change-query",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const pickItemLocationId = transform(
|
||||||
|
{ order, input },
|
||||||
|
({ order, input }) => {
|
||||||
|
if (input.location_id) {
|
||||||
|
return input.location_id
|
||||||
|
}
|
||||||
|
|
||||||
|
// pick the first item location
|
||||||
|
const item = order?.items?.find(
|
||||||
|
(item) => item.id === input.items[0].id
|
||||||
|
) as any
|
||||||
|
|
||||||
|
let locationId: string | undefined
|
||||||
|
deepFlatMap(
|
||||||
|
item,
|
||||||
|
"variant.inventory_items.inventory.location_levels",
|
||||||
|
({ location_levels }) => {
|
||||||
|
if (!locationId && isDefined(location_levels?.location_id)) {
|
||||||
|
locationId = location_levels.location_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return locationId
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const createdReturn = when({ orderClaim }, ({ orderClaim }) => {
|
||||||
|
return !orderClaim.return_id
|
||||||
|
}).then(() => {
|
||||||
|
return createReturnsStep([
|
||||||
|
{
|
||||||
|
order_id: orderClaim.order_id,
|
||||||
|
claim_id: orderClaim.id,
|
||||||
|
location_id: pickItemLocationId,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
const orderReturn: ReturnDTO = transform(
|
||||||
|
{ createdReturn, existingOrderReturn },
|
||||||
|
({ createdReturn, existingOrderReturn }) => {
|
||||||
|
return existingOrderReturn ?? (createdReturn?.[0] as ReturnDTO)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
when({ createdReturn }, ({ createdReturn }) => {
|
when({ createdReturn }, ({ createdReturn }) => {
|
||||||
return !!createdReturn?.length
|
return !!createdReturn?.length
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
|
|||||||
+2
-2
@@ -13,8 +13,8 @@ import {
|
|||||||
} from "@medusajs/framework/workflows-sdk"
|
} from "@medusajs/framework/workflows-sdk"
|
||||||
import { useRemoteQueryStep } from "../../common"
|
import { useRemoteQueryStep } from "../../common"
|
||||||
import { updatePaymentCollectionStep } from "../../payment-collection"
|
import { updatePaymentCollectionStep } from "../../payment-collection"
|
||||||
import { createOrderPaymentCollectionWorkflow } from "./create-order-payment-collection"
|
|
||||||
import { cancelPaymentCollectionWorkflow } from "../../payment-collection/workflows/cancel-payment-collection"
|
import { cancelPaymentCollectionWorkflow } from "../../payment-collection/workflows/cancel-payment-collection"
|
||||||
|
import { createOrderPaymentCollectionWorkflow } from "./create-order-payment-collection"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The details of the order payment collection to create or update.
|
* The details of the order payment collection to create or update.
|
||||||
@@ -65,7 +65,7 @@ export const createOrUpdateOrderPaymentCollectionWorkflow = createWorkflow(
|
|||||||
) => {
|
) => {
|
||||||
const order = useRemoteQueryStep({
|
const order = useRemoteQueryStep({
|
||||||
entry_point: "order",
|
entry_point: "order",
|
||||||
fields: ["id", "summary", "currency_code", "region_id"],
|
fields: ["id", "summary", "total", "currency_code", "region_id"],
|
||||||
variables: { id: input.order_id },
|
variables: { id: input.order_id },
|
||||||
throw_if_key_not_found: true,
|
throw_if_key_not_found: true,
|
||||||
list: false,
|
list: false,
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ export const createOrderCreditLinesWorkflow = createWorkflow(
|
|||||||
) => {
|
) => {
|
||||||
const orderQuery = useQueryGraphStep({
|
const orderQuery = useQueryGraphStep({
|
||||||
entity: "orders",
|
entity: "orders",
|
||||||
fields: ["id", "status", "summary"],
|
fields: ["id", "status", "summary", "total"],
|
||||||
filters: { id: input.id },
|
filters: { id: input.id },
|
||||||
options: { throwIfKeyNotFound: true },
|
options: { throwIfKeyNotFound: true },
|
||||||
}).config({ name: "get-order" })
|
}).config({ name: "get-order" })
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import {
|
|||||||
createWorkflow,
|
createWorkflow,
|
||||||
transform,
|
transform,
|
||||||
} from "@medusajs/framework/workflows-sdk"
|
} from "@medusajs/framework/workflows-sdk"
|
||||||
import { createRemoteLinkStep, useRemoteQueryStep } from "../../common"
|
|
||||||
import { createPaymentCollectionsStep } from "../../cart"
|
import { createPaymentCollectionsStep } from "../../cart"
|
||||||
|
import { createRemoteLinkStep, useRemoteQueryStep } from "../../common"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The details of the payment collection to create.
|
* The details of the payment collection to create.
|
||||||
@@ -46,12 +46,10 @@ export const createOrderPaymentCollectionWorkflowId =
|
|||||||
*/
|
*/
|
||||||
export const createOrderPaymentCollectionWorkflow = createWorkflow(
|
export const createOrderPaymentCollectionWorkflow = createWorkflow(
|
||||||
createOrderPaymentCollectionWorkflowId,
|
createOrderPaymentCollectionWorkflowId,
|
||||||
(
|
(input: WorkflowData<CreateOrderPaymentCollectionWorkflowInput>) => {
|
||||||
input: WorkflowData<CreateOrderPaymentCollectionWorkflowInput>
|
|
||||||
) => {
|
|
||||||
const order = useRemoteQueryStep({
|
const order = useRemoteQueryStep({
|
||||||
entry_point: "order",
|
entry_point: "order",
|
||||||
fields: ["id", "summary", "currency_code", "region_id"],
|
fields: ["id", "summary", "total", "currency_code", "region_id"],
|
||||||
variables: { id: input.order_id },
|
variables: { id: input.order_id },
|
||||||
throw_if_key_not_found: true,
|
throw_if_key_not_found: true,
|
||||||
list: false,
|
list: false,
|
||||||
|
|||||||
+68
-23
@@ -6,14 +6,19 @@ import {
|
|||||||
OrderWorkflow,
|
OrderWorkflow,
|
||||||
ReturnDTO,
|
ReturnDTO,
|
||||||
} from "@medusajs/framework/types"
|
} from "@medusajs/framework/types"
|
||||||
import { ChangeActionType, OrderChangeStatus } from "@medusajs/framework/utils"
|
|
||||||
import {
|
import {
|
||||||
WorkflowData,
|
ChangeActionType,
|
||||||
WorkflowResponse,
|
deepFlatMap,
|
||||||
|
isDefined,
|
||||||
|
OrderChangeStatus,
|
||||||
|
} from "@medusajs/framework/utils"
|
||||||
|
import {
|
||||||
createStep,
|
createStep,
|
||||||
createWorkflow,
|
createWorkflow,
|
||||||
transform,
|
transform,
|
||||||
when,
|
when,
|
||||||
|
WorkflowData,
|
||||||
|
WorkflowResponse,
|
||||||
} from "@medusajs/framework/workflows-sdk"
|
} from "@medusajs/framework/workflows-sdk"
|
||||||
import { useRemoteQueryStep } from "../../../common"
|
import { useRemoteQueryStep } from "../../../common"
|
||||||
import { updateOrderExchangesStep } from "../../steps/exchange/update-order-exchanges"
|
import { updateOrderExchangesStep } from "../../steps/exchange/update-order-exchanges"
|
||||||
@@ -23,6 +28,7 @@ import { updateOrderChangesStep } from "../../steps/update-order-changes"
|
|||||||
import {
|
import {
|
||||||
throwIfIsCancelled,
|
throwIfIsCancelled,
|
||||||
throwIfItemsDoesNotExistsInOrder,
|
throwIfItemsDoesNotExistsInOrder,
|
||||||
|
throwIfManagedItemsNotStockedAtReturnLocation,
|
||||||
throwIfOrderChangeIsNotActive,
|
throwIfOrderChangeIsNotActive,
|
||||||
} from "../../utils/order-validation"
|
} from "../../utils/order-validation"
|
||||||
import { createOrderChangeActionsWorkflow } from "../create-order-change-actions"
|
import { createOrderChangeActionsWorkflow } from "../create-order-change-actions"
|
||||||
@@ -106,6 +112,11 @@ export const exchangeRequestItemReturnValidationStep = createStep(
|
|||||||
throwIfIsCancelled(orderReturn, "Return")
|
throwIfIsCancelled(orderReturn, "Return")
|
||||||
throwIfOrderChangeIsNotActive({ orderChange })
|
throwIfOrderChangeIsNotActive({ orderChange })
|
||||||
throwIfItemsDoesNotExistsInOrder({ order, inputItems: items })
|
throwIfItemsDoesNotExistsInOrder({ order, inputItems: items })
|
||||||
|
throwIfManagedItemsNotStockedAtReturnLocation({
|
||||||
|
order,
|
||||||
|
orderReturn,
|
||||||
|
inputItems: items,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -144,7 +155,7 @@ export const orderExchangeRequestItemReturnWorkflow = createWorkflow(
|
|||||||
): WorkflowResponse<OrderPreviewDTO> {
|
): WorkflowResponse<OrderPreviewDTO> {
|
||||||
const orderExchange = useRemoteQueryStep({
|
const orderExchange = useRemoteQueryStep({
|
||||||
entry_point: "order_exchange",
|
entry_point: "order_exchange",
|
||||||
fields: ["id", "order_id", "return_id", "canceled_at"],
|
fields: ["id", "order_id", "return_id", "location_id", "canceled_at"],
|
||||||
variables: { id: input.exchange_id },
|
variables: { id: input.exchange_id },
|
||||||
list: false,
|
list: false,
|
||||||
throw_if_key_not_found: true,
|
throw_if_key_not_found: true,
|
||||||
@@ -162,27 +173,16 @@ export const orderExchangeRequestItemReturnWorkflow = createWorkflow(
|
|||||||
}).config({ name: "return-query" }) as ReturnDTO
|
}).config({ name: "return-query" }) as ReturnDTO
|
||||||
})
|
})
|
||||||
|
|
||||||
const createdReturn = when({ orderExchange }, ({ orderExchange }) => {
|
|
||||||
return !orderExchange.return_id
|
|
||||||
}).then(() => {
|
|
||||||
return createReturnsStep([
|
|
||||||
{
|
|
||||||
order_id: orderExchange.order_id,
|
|
||||||
exchange_id: orderExchange.id,
|
|
||||||
},
|
|
||||||
])
|
|
||||||
})
|
|
||||||
|
|
||||||
const orderReturn: ReturnDTO = transform(
|
|
||||||
{ createdReturn, existingOrderReturn, orderExchange },
|
|
||||||
({ createdReturn, existingOrderReturn, orderExchange }) => {
|
|
||||||
return existingOrderReturn ?? (createdReturn?.[0] as ReturnDTO)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const order: OrderDTO = useRemoteQueryStep({
|
const order: OrderDTO = useRemoteQueryStep({
|
||||||
entry_point: "orders",
|
entry_point: "orders",
|
||||||
fields: ["id", "status", "items.*"],
|
fields: [
|
||||||
|
"id",
|
||||||
|
"status",
|
||||||
|
"items.*",
|
||||||
|
"items.variant.manage_inventory",
|
||||||
|
"items.variant.inventory_items.inventory_item_id",
|
||||||
|
"items.variant.inventory_items.inventory.location_levels.location_id",
|
||||||
|
],
|
||||||
variables: { id: orderExchange.order_id },
|
variables: { id: orderExchange.order_id },
|
||||||
list: false,
|
list: false,
|
||||||
throw_if_key_not_found: true,
|
throw_if_key_not_found: true,
|
||||||
@@ -204,6 +204,51 @@ export const orderExchangeRequestItemReturnWorkflow = createWorkflow(
|
|||||||
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
|
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const pickItemLocationId = transform(
|
||||||
|
{ order, input },
|
||||||
|
({ order, input }) => {
|
||||||
|
if (input.location_id) {
|
||||||
|
return input.location_id
|
||||||
|
}
|
||||||
|
|
||||||
|
// pick the first item location
|
||||||
|
const item = order?.items?.find(
|
||||||
|
(item) => item.id === input.items[0].id
|
||||||
|
) as any
|
||||||
|
|
||||||
|
let locationId: string | undefined
|
||||||
|
deepFlatMap(
|
||||||
|
item,
|
||||||
|
"variant.inventory_items.inventory.location_levels",
|
||||||
|
({ location_levels }) => {
|
||||||
|
if (!locationId && isDefined(location_levels?.location_id)) {
|
||||||
|
locationId = location_levels.location_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return locationId
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const createdReturn = when({ orderExchange }, ({ orderExchange }) => {
|
||||||
|
return !orderExchange.return_id
|
||||||
|
}).then(() => {
|
||||||
|
return createReturnsStep([
|
||||||
|
{
|
||||||
|
order_id: orderExchange.order_id,
|
||||||
|
location_id: pickItemLocationId,
|
||||||
|
exchange_id: orderExchange.id,
|
||||||
|
},
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
const orderReturn: ReturnDTO = transform(
|
||||||
|
{ createdReturn, existingOrderReturn, orderExchange },
|
||||||
|
({ createdReturn, existingOrderReturn, orderExchange }) => {
|
||||||
|
return existingOrderReturn ?? (createdReturn?.[0] as ReturnDTO)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
when({ createdReturn }, ({ createdReturn }) => {
|
when({ createdReturn }, ({ createdReturn }) => {
|
||||||
return !!createdReturn?.length
|
return !!createdReturn?.length
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
|
|||||||
@@ -234,6 +234,7 @@ export const markOrderFulfillmentAsDeliveredWorkflow = createWorkflow(
|
|||||||
fields: [
|
fields: [
|
||||||
"id",
|
"id",
|
||||||
"summary",
|
"summary",
|
||||||
|
"total",
|
||||||
"currency_code",
|
"currency_code",
|
||||||
"region_id",
|
"region_id",
|
||||||
"fulfillments.id",
|
"fulfillments.id",
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ export const createOrderRefundCreditLinesWorkflow = createWorkflow(
|
|||||||
) {
|
) {
|
||||||
const orderQuery = useQueryGraphStep({
|
const orderQuery = useQueryGraphStep({
|
||||||
entity: "orders",
|
entity: "orders",
|
||||||
fields: ["id", "status", "summary", "payment_collections.id"],
|
fields: ["id", "status", "summary", "total", "payment_collections.id"],
|
||||||
filters: { id: input.order_id },
|
filters: { id: input.order_id },
|
||||||
options: { throwIfKeyNotFound: true },
|
options: { throwIfKeyNotFound: true },
|
||||||
}).config({ name: "get-order" })
|
}).config({ name: "get-order" })
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export const refundCapturedPaymentsWorkflow = createWorkflow(
|
|||||||
"id",
|
"id",
|
||||||
"status",
|
"status",
|
||||||
"summary",
|
"summary",
|
||||||
|
"total",
|
||||||
"payment_collections.payments.id",
|
"payment_collections.payments.id",
|
||||||
"payment_collections.payments.amount",
|
"payment_collections.payments.amount",
|
||||||
"payment_collections.payments.refunds.id",
|
"payment_collections.payments.refunds.id",
|
||||||
|
|||||||
+10
-1
@@ -34,6 +34,7 @@ import {
|
|||||||
throwIfIsCancelled,
|
throwIfIsCancelled,
|
||||||
throwIfOrderChangeIsNotActive,
|
throwIfOrderChangeIsNotActive,
|
||||||
} from "../../utils/order-validation"
|
} from "../../utils/order-validation"
|
||||||
|
import { createOrUpdateOrderPaymentCollectionWorkflow } from "../create-or-update-order-payment-collection"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The data to validate that a return receival can be confirmed.
|
* The data to validate that a return receival can be confirmed.
|
||||||
@@ -363,7 +364,15 @@ export const confirmReturnReceiveWorkflow = createWorkflow(
|
|||||||
orderId: order.id,
|
orderId: order.id,
|
||||||
confirmed_by: input.confirmed_by,
|
confirmed_by: input.confirmed_by,
|
||||||
}),
|
}),
|
||||||
adjustInventoryLevelsStep(inventoryAdjustment),
|
adjustInventoryLevelsStep(inventoryAdjustment)
|
||||||
|
)
|
||||||
|
|
||||||
|
parallelize(
|
||||||
|
createOrUpdateOrderPaymentCollectionWorkflow.runAsStep({
|
||||||
|
input: {
|
||||||
|
order_id: order.id,
|
||||||
|
},
|
||||||
|
}),
|
||||||
emitEventStep({
|
emitEventStep({
|
||||||
eventName: OrderWorkflowEvents.RETURN_RECEIVED,
|
eventName: OrderWorkflowEvents.RETURN_RECEIVED,
|
||||||
data: {
|
data: {
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import {
|
import {
|
||||||
|
AdditionalData,
|
||||||
BigNumberInput,
|
BigNumberInput,
|
||||||
CreateOrderShippingMethodDTO,
|
CreateOrderShippingMethodDTO,
|
||||||
FulfillmentWorkflow,
|
FulfillmentWorkflow,
|
||||||
OrderDTO,
|
OrderDTO,
|
||||||
ReturnDTO,
|
|
||||||
OrderWorkflow,
|
OrderWorkflow,
|
||||||
|
ReturnDTO,
|
||||||
ShippingOptionDTO,
|
ShippingOptionDTO,
|
||||||
WithCalculatedPrice,
|
WithCalculatedPrice,
|
||||||
AdditionalData,
|
|
||||||
} from "@medusajs/framework/types"
|
} from "@medusajs/framework/types"
|
||||||
import {
|
import {
|
||||||
MathBN,
|
MathBN,
|
||||||
@@ -25,6 +25,7 @@ import {
|
|||||||
parallelize,
|
parallelize,
|
||||||
transform,
|
transform,
|
||||||
} from "@medusajs/framework/workflows-sdk"
|
} from "@medusajs/framework/workflows-sdk"
|
||||||
|
import { pricingContextResult } from "../../../cart/utils/schemas"
|
||||||
import {
|
import {
|
||||||
createRemoteLinkStep,
|
createRemoteLinkStep,
|
||||||
emitEventStep,
|
emitEventStep,
|
||||||
@@ -38,7 +39,6 @@ import {
|
|||||||
throwIfOrderIsCancelled,
|
throwIfOrderIsCancelled,
|
||||||
} from "../../utils/order-validation"
|
} from "../../utils/order-validation"
|
||||||
import { validateReturnReasons } from "../../utils/validate-return-reason"
|
import { validateReturnReasons } from "../../utils/validate-return-reason"
|
||||||
import { pricingContextResult } from "../../../cart/utils/schemas"
|
|
||||||
|
|
||||||
function prepareShippingMethodData({
|
function prepareShippingMethodData({
|
||||||
orderId,
|
orderId,
|
||||||
@@ -423,6 +423,7 @@ export const createAndCompleteReturnOrderWorkflow = createWorkflow(
|
|||||||
|
|
||||||
const returnCreated = createCompleteReturnStep({
|
const returnCreated = createCompleteReturnStep({
|
||||||
order_id: input.order_id,
|
order_id: input.order_id,
|
||||||
|
location_id: input.location_id,
|
||||||
items: input.items,
|
items: input.items,
|
||||||
shipping_method: shippingMethodData,
|
shipping_method: shippingMethodData,
|
||||||
created_by: input.created_by,
|
created_by: input.created_by,
|
||||||
|
|||||||
@@ -146,31 +146,33 @@ export const refundPaymentWorkflow = createWorkflow(
|
|||||||
|
|
||||||
const order = useRemoteQueryStep({
|
const order = useRemoteQueryStep({
|
||||||
entry_point: "order",
|
entry_point: "order",
|
||||||
fields: ["id", "summary", "currency_code", "region_id"],
|
fields: ["id", "summary", "total", "currency_code", "region_id"],
|
||||||
variables: { id: orderPaymentCollection.order.id },
|
variables: { id: orderPaymentCollection.order.id },
|
||||||
throw_if_key_not_found: true,
|
throw_if_key_not_found: true,
|
||||||
list: false,
|
list: false,
|
||||||
}).config({ name: "order" })
|
}).config({ name: "order" })
|
||||||
|
|
||||||
validateRefundStep({ order, payment, amount: input.amount })
|
validateRefundStep({ order, payment, amount: input.amount })
|
||||||
refundPaymentStep(input)
|
const refundPayment = refundPaymentStep(input)
|
||||||
|
|
||||||
when({ orderPaymentCollection }, ({ orderPaymentCollection }) => {
|
when({ orderPaymentCollection }, ({ orderPaymentCollection }) => {
|
||||||
return !!orderPaymentCollection?.order?.id
|
return !!orderPaymentCollection?.order?.id
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
const orderTransactionData = transform(
|
const orderTransactionData = transform(
|
||||||
{ input, payment, orderPaymentCollection },
|
{ input, refundPayment, orderPaymentCollection, order },
|
||||||
({ input, payment, orderPaymentCollection }) => {
|
({ input, refundPayment, orderPaymentCollection, order }) => {
|
||||||
return {
|
return refundPayment.refunds?.map((refund) => {
|
||||||
order_id: orderPaymentCollection.order.id,
|
return {
|
||||||
amount: MathBN.mult(
|
order_id: orderPaymentCollection.order.id,
|
||||||
input.amount ?? payment.raw_amount ?? payment.amount,
|
amount: MathBN.mult(
|
||||||
-1
|
input.amount ?? refund.raw_amount ?? refund.amount,
|
||||||
),
|
-1
|
||||||
currency_code: payment.currency_code ?? order.currency_code,
|
),
|
||||||
reference_id: payment.id,
|
currency_code: refundPayment.currency_code ?? order.currency_code,
|
||||||
reference: "refund",
|
reference_id: refund.id,
|
||||||
}
|
reference: "refund",
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1578,7 +1578,7 @@ export interface CreateOrderReturnDTO extends BaseOrderBundledActionsDTO {
|
|||||||
/**
|
/**
|
||||||
* The ID of the location to return the items to.
|
* The ID of the location to return the items to.
|
||||||
*/
|
*/
|
||||||
location_id?: string
|
location_id?: string | null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The items of the return.
|
* The items of the return.
|
||||||
|
|||||||
@@ -73,6 +73,10 @@ export interface OrderExchangeRequestItemReturnWorkflowInput {
|
|||||||
* The ID of the return that's associated with the exchange.
|
* The ID of the return that's associated with the exchange.
|
||||||
*/
|
*/
|
||||||
return_id: string
|
return_id: string
|
||||||
|
/**
|
||||||
|
* The ID of the location to return the items to.
|
||||||
|
*/
|
||||||
|
location_id?: string
|
||||||
/**
|
/**
|
||||||
* The ID of the exchange to add the inbound items to.
|
* The ID of the exchange to add the inbound items to.
|
||||||
*/
|
*/
|
||||||
@@ -95,6 +99,10 @@ export interface OrderClaimRequestItemReturnWorkflowInput {
|
|||||||
* The ID of the return that's associated with the claim.
|
* The ID of the return that's associated with the claim.
|
||||||
*/
|
*/
|
||||||
return_id: string
|
return_id: string
|
||||||
|
/**
|
||||||
|
* The ID of the location to return the items to.
|
||||||
|
*/
|
||||||
|
location_id?: string
|
||||||
/**
|
/**
|
||||||
* The ID of the claim to add the items to.
|
* The ID of the claim to add the items to.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ describe("Total calculation", function () {
|
|||||||
subtotal: 60,
|
subtotal: 60,
|
||||||
total: 66,
|
total: 66,
|
||||||
original_total: 66,
|
original_total: 66,
|
||||||
|
original_subtotal: 60,
|
||||||
discount_total: 0,
|
discount_total: 0,
|
||||||
discount_subtotal: 0,
|
discount_subtotal: 0,
|
||||||
discount_tax_total: 0,
|
discount_tax_total: 0,
|
||||||
@@ -60,6 +61,7 @@ describe("Total calculation", function () {
|
|||||||
subtotal: 5,
|
subtotal: 5,
|
||||||
total: 7.5,
|
total: 7.5,
|
||||||
original_total: 7.5,
|
original_total: 7.5,
|
||||||
|
original_subtotal: 5,
|
||||||
discount_total: 0,
|
discount_total: 0,
|
||||||
discount_subtotal: 0,
|
discount_subtotal: 0,
|
||||||
discount_tax_total: 0,
|
discount_tax_total: 0,
|
||||||
@@ -78,6 +80,7 @@ describe("Total calculation", function () {
|
|||||||
item_tax_total: 8.5,
|
item_tax_total: 8.5,
|
||||||
item_discount_total: 0,
|
item_discount_total: 0,
|
||||||
original_total: 73.5,
|
original_total: 73.5,
|
||||||
|
original_subtotal: 65,
|
||||||
original_tax_total: 8.5,
|
original_tax_total: 8.5,
|
||||||
original_item_subtotal: 65,
|
original_item_subtotal: 65,
|
||||||
original_item_total: 73.5,
|
original_item_total: 73.5,
|
||||||
@@ -132,6 +135,7 @@ describe("Total calculation", function () {
|
|||||||
subtotal: 100,
|
subtotal: 100,
|
||||||
total: 99,
|
total: 99,
|
||||||
original_total: 110,
|
original_total: 110,
|
||||||
|
original_subtotal: 100,
|
||||||
discount_total: 11,
|
discount_total: 11,
|
||||||
discount_subtotal: 10,
|
discount_subtotal: 10,
|
||||||
discount_tax_total: 1,
|
discount_tax_total: 1,
|
||||||
@@ -146,6 +150,7 @@ describe("Total calculation", function () {
|
|||||||
discount_subtotal: 10,
|
discount_subtotal: 10,
|
||||||
discount_tax_total: 1,
|
discount_tax_total: 1,
|
||||||
original_total: 110,
|
original_total: 110,
|
||||||
|
original_subtotal: 100,
|
||||||
original_tax_total: 10,
|
original_tax_total: 10,
|
||||||
item_total: 99,
|
item_total: 99,
|
||||||
item_subtotal: 100,
|
item_subtotal: 100,
|
||||||
@@ -253,6 +258,7 @@ describe("Total calculation", function () {
|
|||||||
subtotal: 90,
|
subtotal: 90,
|
||||||
total: 89.1,
|
total: 89.1,
|
||||||
original_total: 99,
|
original_total: 99,
|
||||||
|
original_subtotal: 90,
|
||||||
discount_total: 9.9,
|
discount_total: 9.9,
|
||||||
discount_subtotal: 9,
|
discount_subtotal: 9,
|
||||||
discount_tax_total: 0.9,
|
discount_tax_total: 0.9,
|
||||||
@@ -280,6 +286,7 @@ describe("Total calculation", function () {
|
|||||||
subtotal: 9,
|
subtotal: 9,
|
||||||
total: 6.6,
|
total: 6.6,
|
||||||
original_total: 9.9,
|
original_total: 9.9,
|
||||||
|
original_subtotal: 9,
|
||||||
discount_total: 3.3,
|
discount_total: 3.3,
|
||||||
discount_subtotal: 3,
|
discount_subtotal: 3,
|
||||||
discount_tax_total: 0.3,
|
discount_tax_total: 0.3,
|
||||||
@@ -308,6 +315,7 @@ describe("Total calculation", function () {
|
|||||||
subtotal: 90,
|
subtotal: 90,
|
||||||
total: 89.1,
|
total: 89.1,
|
||||||
original_total: 99,
|
original_total: 99,
|
||||||
|
original_subtotal: 90,
|
||||||
discount_total: 9.9,
|
discount_total: 9.9,
|
||||||
discount_subtotal: 9,
|
discount_subtotal: 9,
|
||||||
discount_tax_total: 0.9,
|
discount_tax_total: 0.9,
|
||||||
@@ -334,6 +342,7 @@ describe("Total calculation", function () {
|
|||||||
subtotal: 9,
|
subtotal: 9,
|
||||||
total: 6.6,
|
total: 6.6,
|
||||||
original_total: 9.9,
|
original_total: 9.9,
|
||||||
|
original_subtotal: 9,
|
||||||
discount_total: 3.3,
|
discount_total: 3.3,
|
||||||
discount_subtotal: 3,
|
discount_subtotal: 3,
|
||||||
discount_tax_total: 0.3,
|
discount_tax_total: 0.3,
|
||||||
@@ -348,6 +357,7 @@ describe("Total calculation", function () {
|
|||||||
discount_subtotal: 24,
|
discount_subtotal: 24,
|
||||||
discount_tax_total: 2.4,
|
discount_tax_total: 2.4,
|
||||||
original_total: 217.8,
|
original_total: 217.8,
|
||||||
|
original_subtotal: 198,
|
||||||
original_tax_total: 19.8,
|
original_tax_total: 19.8,
|
||||||
item_total: 95.7,
|
item_total: 95.7,
|
||||||
item_subtotal: 99,
|
item_subtotal: 99,
|
||||||
@@ -431,6 +441,7 @@ describe("Total calculation", function () {
|
|||||||
subtotal: 90.9090909090909,
|
subtotal: 90.9090909090909,
|
||||||
total: 100,
|
total: 100,
|
||||||
original_total: 100,
|
original_total: 100,
|
||||||
|
original_subtotal: 90.9090909090909,
|
||||||
discount_total: 0,
|
discount_total: 0,
|
||||||
discount_tax_total: 0,
|
discount_tax_total: 0,
|
||||||
tax_total: 9.090909090909092,
|
tax_total: 9.090909090909092,
|
||||||
@@ -444,6 +455,7 @@ describe("Total calculation", function () {
|
|||||||
discount_total: 0,
|
discount_total: 0,
|
||||||
discount_tax_total: 0,
|
discount_tax_total: 0,
|
||||||
original_total: 100,
|
original_total: 100,
|
||||||
|
original_subtotal: 90.9090909090909,
|
||||||
original_tax_total: 9.090909090909092,
|
original_tax_total: 9.090909090909092,
|
||||||
item_total: 100,
|
item_total: 100,
|
||||||
item_subtotal: 90.9090909090909,
|
item_subtotal: 90.9090909090909,
|
||||||
@@ -478,6 +490,7 @@ describe("Total calculation", function () {
|
|||||||
discount_tax_total: 0,
|
discount_tax_total: 0,
|
||||||
tax_total: 10,
|
tax_total: 10,
|
||||||
original_tax_total: 10,
|
original_tax_total: 10,
|
||||||
|
original_subtotal: 100,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
total: 110,
|
total: 110,
|
||||||
@@ -487,6 +500,7 @@ describe("Total calculation", function () {
|
|||||||
discount_total: 0,
|
discount_total: 0,
|
||||||
discount_tax_total: 0,
|
discount_tax_total: 0,
|
||||||
original_total: 110,
|
original_total: 110,
|
||||||
|
original_subtotal: 100,
|
||||||
original_tax_total: 10,
|
original_tax_total: 10,
|
||||||
item_total: 110,
|
item_total: 110,
|
||||||
item_subtotal: 100,
|
item_subtotal: 100,
|
||||||
@@ -516,6 +530,7 @@ describe("Total calculation", function () {
|
|||||||
],
|
],
|
||||||
subtotal: 90.9090909090909,
|
subtotal: 90.9090909090909,
|
||||||
total: 100,
|
total: 100,
|
||||||
|
original_subtotal: 90.9090909090909,
|
||||||
original_total: 100,
|
original_total: 100,
|
||||||
discount_total: 0,
|
discount_total: 0,
|
||||||
discount_tax_total: 0,
|
discount_tax_total: 0,
|
||||||
@@ -537,6 +552,7 @@ describe("Total calculation", function () {
|
|||||||
subtotal: 100,
|
subtotal: 100,
|
||||||
total: 110,
|
total: 110,
|
||||||
original_total: 110,
|
original_total: 110,
|
||||||
|
original_subtotal: 100,
|
||||||
discount_total: 0,
|
discount_total: 0,
|
||||||
discount_tax_total: 0,
|
discount_tax_total: 0,
|
||||||
tax_total: 10,
|
tax_total: 10,
|
||||||
@@ -550,6 +566,7 @@ describe("Total calculation", function () {
|
|||||||
discount_total: 0,
|
discount_total: 0,
|
||||||
discount_tax_total: 0,
|
discount_tax_total: 0,
|
||||||
original_total: 210,
|
original_total: 210,
|
||||||
|
original_subtotal: 190.9090909090909,
|
||||||
original_tax_total: 19.09090909090909,
|
original_tax_total: 19.09090909090909,
|
||||||
item_total: 210,
|
item_total: 210,
|
||||||
item_subtotal: 190.9090909090909,
|
item_subtotal: 190.9090909090909,
|
||||||
@@ -606,6 +623,7 @@ describe("Total calculation", function () {
|
|||||||
is_tax_inclusive: true,
|
is_tax_inclusive: true,
|
||||||
|
|
||||||
original_total: 120,
|
original_total: 120,
|
||||||
|
original_subtotal: 100,
|
||||||
original_tax_total: 20,
|
original_tax_total: 20,
|
||||||
|
|
||||||
discount_subtotal: 8.333333333333334,
|
discount_subtotal: 8.333333333333334,
|
||||||
@@ -637,6 +655,7 @@ describe("Total calculation", function () {
|
|||||||
original_item_total: 120,
|
original_item_total: 120,
|
||||||
original_tax_total: 20,
|
original_tax_total: 20,
|
||||||
original_total: 120,
|
original_total: 120,
|
||||||
|
original_subtotal: 100,
|
||||||
|
|
||||||
discount_subtotal: 8.333333333333334,
|
discount_subtotal: 8.333333333333334,
|
||||||
discount_tax_total: 1.6666666666666667,
|
discount_tax_total: 1.6666666666666667,
|
||||||
@@ -712,6 +731,7 @@ describe("Total calculation", function () {
|
|||||||
subtotal: 100,
|
subtotal: 100,
|
||||||
total: 88,
|
total: 88,
|
||||||
original_total: 110,
|
original_total: 110,
|
||||||
|
original_subtotal: 100,
|
||||||
discount_total: 22,
|
discount_total: 22,
|
||||||
discount_subtotal: 20,
|
discount_subtotal: 20,
|
||||||
discount_tax_total: 2,
|
discount_tax_total: 2,
|
||||||
@@ -739,6 +759,7 @@ describe("Total calculation", function () {
|
|||||||
subtotal: 25,
|
subtotal: 25,
|
||||||
total: 25.3,
|
total: 25.3,
|
||||||
original_total: 27.5,
|
original_total: 27.5,
|
||||||
|
original_subtotal: 25,
|
||||||
discount_total: 2.2,
|
discount_total: 2.2,
|
||||||
discount_subtotal: 2,
|
discount_subtotal: 2,
|
||||||
discount_tax_total: 0.2,
|
discount_tax_total: 0.2,
|
||||||
@@ -753,6 +774,7 @@ describe("Total calculation", function () {
|
|||||||
discount_subtotal: 22,
|
discount_subtotal: 22,
|
||||||
discount_tax_total: 2.2,
|
discount_tax_total: 2.2,
|
||||||
original_total: 137.5,
|
original_total: 137.5,
|
||||||
|
original_subtotal: 125,
|
||||||
original_tax_total: 12.5,
|
original_tax_total: 12.5,
|
||||||
item_total: 88,
|
item_total: 88,
|
||||||
item_subtotal: 100,
|
item_subtotal: 100,
|
||||||
@@ -836,8 +858,8 @@ describe("Total calculation", function () {
|
|||||||
tax_lines: [
|
tax_lines: [
|
||||||
{
|
{
|
||||||
rate: 10,
|
rate: 10,
|
||||||
total: 8,
|
total: 0,
|
||||||
subtotal: 10,
|
subtotal: 0,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
adjustments: [
|
adjustments: [
|
||||||
@@ -847,14 +869,15 @@ describe("Total calculation", function () {
|
|||||||
total: 22,
|
total: 22,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
subtotal: 100,
|
subtotal: 0,
|
||||||
total: 88,
|
total: 0,
|
||||||
original_total: 110,
|
original_total: 0,
|
||||||
discount_total: 22,
|
original_subtotal: 0,
|
||||||
discount_subtotal: 20,
|
discount_total: 0,
|
||||||
discount_tax_total: 2,
|
discount_subtotal: 0,
|
||||||
tax_total: 8,
|
discount_tax_total: 0,
|
||||||
original_tax_total: 10,
|
tax_total: 0,
|
||||||
|
original_tax_total: 0,
|
||||||
refundable_total_per_unit: 0,
|
refundable_total_per_unit: 0,
|
||||||
refundable_total: 0,
|
refundable_total: 0,
|
||||||
fulfilled_total: 88,
|
fulfilled_total: 88,
|
||||||
@@ -865,21 +888,22 @@ describe("Total calculation", function () {
|
|||||||
write_off_total: 44,
|
write_off_total: 44,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
total: 48,
|
total: -40,
|
||||||
subtotal: 100,
|
subtotal: 0,
|
||||||
tax_total: 8,
|
tax_total: 0,
|
||||||
discount_total: 22,
|
discount_total: 0,
|
||||||
discount_subtotal: 20,
|
discount_subtotal: 0,
|
||||||
discount_tax_total: 2,
|
discount_tax_total: 0,
|
||||||
original_total: 110,
|
original_total: 0,
|
||||||
original_tax_total: 10,
|
original_subtotal: 0,
|
||||||
item_total: 88,
|
original_tax_total: 0,
|
||||||
item_subtotal: 100,
|
item_total: 0,
|
||||||
item_tax_total: 8,
|
item_subtotal: 0,
|
||||||
item_discount_total: 22,
|
item_tax_total: 0,
|
||||||
original_item_total: 110,
|
item_discount_total: 0,
|
||||||
original_item_subtotal: 100,
|
original_item_total: 0,
|
||||||
original_item_tax_total: 10,
|
original_item_subtotal: 0,
|
||||||
|
original_item_tax_total: 0,
|
||||||
fulfilled_total: 88,
|
fulfilled_total: 88,
|
||||||
shipped_total: 88,
|
shipped_total: 88,
|
||||||
return_requested_total: 0,
|
return_requested_total: 0,
|
||||||
@@ -923,6 +947,7 @@ describe("Total calculation", function () {
|
|||||||
{
|
{
|
||||||
rate: 19,
|
rate: 19,
|
||||||
subtotal: 22.61,
|
subtotal: 22.61,
|
||||||
|
total: 0,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
adjustments: [
|
adjustments: [
|
||||||
@@ -935,6 +960,7 @@ describe("Total calculation", function () {
|
|||||||
subtotal: 119,
|
subtotal: 119,
|
||||||
total: 0,
|
total: 0,
|
||||||
original_total: 141.61,
|
original_total: 141.61,
|
||||||
|
original_subtotal: 119,
|
||||||
discount_total: 141.61,
|
discount_total: 141.61,
|
||||||
discount_subtotal: 119,
|
discount_subtotal: 119,
|
||||||
discount_tax_total: 22.61,
|
discount_tax_total: 22.61,
|
||||||
@@ -949,6 +975,7 @@ describe("Total calculation", function () {
|
|||||||
discount_subtotal: 119,
|
discount_subtotal: 119,
|
||||||
discount_tax_total: 22.61,
|
discount_tax_total: 22.61,
|
||||||
original_total: 141.61,
|
original_total: 141.61,
|
||||||
|
original_subtotal: 119,
|
||||||
original_tax_total: 22.61,
|
original_tax_total: 22.61,
|
||||||
item_total: 0,
|
item_total: 0,
|
||||||
item_subtotal: 119,
|
item_subtotal: 119,
|
||||||
@@ -1026,6 +1053,7 @@ describe("Total calculation", function () {
|
|||||||
discount_total: 0,
|
discount_total: 0,
|
||||||
is_tax_inclusive: true,
|
is_tax_inclusive: true,
|
||||||
original_tax_total: 19,
|
original_tax_total: 19,
|
||||||
|
original_subtotal: 100,
|
||||||
original_total: 119,
|
original_total: 119,
|
||||||
quantity: 1,
|
quantity: 1,
|
||||||
subtotal: 100,
|
subtotal: 100,
|
||||||
@@ -1045,6 +1073,7 @@ describe("Total calculation", function () {
|
|||||||
original_item_tax_total: 19,
|
original_item_tax_total: 19,
|
||||||
original_item_total: 119,
|
original_item_total: 119,
|
||||||
original_tax_total: 19,
|
original_tax_total: 19,
|
||||||
|
original_subtotal: 100,
|
||||||
original_total: 119,
|
original_total: 119,
|
||||||
subtotal: 100,
|
subtotal: 100,
|
||||||
tax_total: 19,
|
tax_total: 19,
|
||||||
@@ -1069,6 +1098,7 @@ describe("Total calculation", function () {
|
|||||||
discount_total: 0,
|
discount_total: 0,
|
||||||
is_tax_inclusive: false,
|
is_tax_inclusive: false,
|
||||||
original_tax_total: 22.61,
|
original_tax_total: 22.61,
|
||||||
|
original_subtotal: 119,
|
||||||
original_total: 141.61,
|
original_total: 141.61,
|
||||||
quantity: 1,
|
quantity: 1,
|
||||||
subtotal: 119,
|
subtotal: 119,
|
||||||
@@ -1088,6 +1118,7 @@ describe("Total calculation", function () {
|
|||||||
original_item_tax_total: 22.61,
|
original_item_tax_total: 22.61,
|
||||||
original_item_total: 141.61,
|
original_item_total: 141.61,
|
||||||
original_tax_total: 22.61,
|
original_tax_total: 22.61,
|
||||||
|
original_subtotal: 119,
|
||||||
original_total: 141.61,
|
original_total: 141.61,
|
||||||
subtotal: 119,
|
subtotal: 119,
|
||||||
tax_total: 22.61,
|
tax_total: 22.61,
|
||||||
@@ -1113,6 +1144,7 @@ describe("Total calculation", function () {
|
|||||||
is_tax_inclusive: true,
|
is_tax_inclusive: true,
|
||||||
original_tax_total: 19,
|
original_tax_total: 19,
|
||||||
original_total: 119,
|
original_total: 119,
|
||||||
|
original_subtotal: 100,
|
||||||
quantity: 1,
|
quantity: 1,
|
||||||
subtotal: 100,
|
subtotal: 100,
|
||||||
tax_lines: [
|
tax_lines: [
|
||||||
@@ -1132,6 +1164,7 @@ describe("Total calculation", function () {
|
|||||||
discount_total: 0,
|
discount_total: 0,
|
||||||
is_tax_inclusive: false,
|
is_tax_inclusive: false,
|
||||||
original_tax_total: 22.61,
|
original_tax_total: 22.61,
|
||||||
|
original_subtotal: 119,
|
||||||
original_total: 141.61,
|
original_total: 141.61,
|
||||||
quantity: 1,
|
quantity: 1,
|
||||||
subtotal: 119,
|
subtotal: 119,
|
||||||
@@ -1150,6 +1183,7 @@ describe("Total calculation", function () {
|
|||||||
original_item_subtotal: 219,
|
original_item_subtotal: 219,
|
||||||
original_item_tax_total: 41.61,
|
original_item_tax_total: 41.61,
|
||||||
original_item_total: 260.61,
|
original_item_total: 260.61,
|
||||||
|
original_subtotal: 219,
|
||||||
original_tax_total: 41.61,
|
original_tax_total: 41.61,
|
||||||
original_total: 260.61,
|
original_total: 260.61,
|
||||||
subtotal: 219,
|
subtotal: 219,
|
||||||
@@ -1206,6 +1240,7 @@ describe("Total calculation", function () {
|
|||||||
discount_total: 119,
|
discount_total: 119,
|
||||||
is_tax_inclusive: true,
|
is_tax_inclusive: true,
|
||||||
original_tax_total: 19,
|
original_tax_total: 19,
|
||||||
|
original_subtotal: 100,
|
||||||
original_total: 119,
|
original_total: 119,
|
||||||
quantity: 1,
|
quantity: 1,
|
||||||
subtotal: 100,
|
subtotal: 100,
|
||||||
@@ -1213,6 +1248,7 @@ describe("Total calculation", function () {
|
|||||||
{
|
{
|
||||||
rate: 19,
|
rate: 19,
|
||||||
subtotal: 19,
|
subtotal: 19,
|
||||||
|
total: 0,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
tax_total: 0,
|
tax_total: 0,
|
||||||
@@ -1224,6 +1260,7 @@ describe("Total calculation", function () {
|
|||||||
original_item_tax_total: 19,
|
original_item_tax_total: 19,
|
||||||
original_item_total: 119,
|
original_item_total: 119,
|
||||||
original_tax_total: 19,
|
original_tax_total: 19,
|
||||||
|
original_subtotal: 100,
|
||||||
original_total: 119,
|
original_total: 119,
|
||||||
subtotal: 100,
|
subtotal: 100,
|
||||||
tax_total: 0,
|
tax_total: 0,
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ import { BigNumber } from "../big-number"
|
|||||||
import { MathBN } from "../math"
|
import { MathBN } from "../math"
|
||||||
|
|
||||||
export function calculateAdjustmentTotal({
|
export function calculateAdjustmentTotal({
|
||||||
|
item,
|
||||||
adjustments,
|
adjustments,
|
||||||
taxRate,
|
taxRate,
|
||||||
}: {
|
}: {
|
||||||
|
item?: { quantity: BigNumberInput }
|
||||||
adjustments: Pick<AdjustmentLineDTO, "amount" | "is_tax_inclusive">[]
|
adjustments: Pick<AdjustmentLineDTO, "amount" | "is_tax_inclusive">[]
|
||||||
taxRate?: BigNumberInput
|
taxRate?: BigNumberInput
|
||||||
}) {
|
}) {
|
||||||
@@ -40,9 +42,24 @@ export function calculateAdjustmentTotal({
|
|||||||
adj["total"] = new BigNumber(adjustmentsTotal)
|
adj["total"] = new BigNumber(adjustmentsTotal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const quantity = item?.quantity || MathBN.convert(1)
|
||||||
|
|
||||||
|
let adjustmentPerItem = MathBN.convert(0)
|
||||||
|
let adjustmentSubtotalPerItem = MathBN.convert(0)
|
||||||
|
let adjustmentTaxTotalPerItem = MathBN.convert(0)
|
||||||
|
|
||||||
|
if (!MathBN.eq(quantity, 0)) {
|
||||||
|
adjustmentPerItem = MathBN.div(adjustmentsTotal, quantity)
|
||||||
|
adjustmentSubtotalPerItem = MathBN.div(adjustmentsSubtotal, quantity)
|
||||||
|
adjustmentTaxTotalPerItem = MathBN.div(adjustmentsTaxTotal, quantity)
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
adjustmentsTotal,
|
adjustmentsTotal,
|
||||||
adjustmentsSubtotal,
|
adjustmentsSubtotal,
|
||||||
adjustmentsTaxTotal,
|
adjustmentsTaxTotal,
|
||||||
|
adjustmentPerItem,
|
||||||
|
adjustmentSubtotalPerItem,
|
||||||
|
adjustmentTaxTotalPerItem,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,8 @@ export function decorateCartTotals(
|
|||||||
let shippingDiscountTotal = MathBN.convert(0)
|
let shippingDiscountTotal = MathBN.convert(0)
|
||||||
|
|
||||||
const cartItems = items.map((item, index) => {
|
const cartItems = items.map((item, index) => {
|
||||||
const itemTotals = Object.assign(item, itemsTotals[item.id ?? index] ?? {})
|
const rawTotals = itemsTotals[item.id ?? index] ?? {}
|
||||||
|
const itemTotals = Object.assign(item, rawTotals)
|
||||||
const itemSubtotal = itemTotals.subtotal
|
const itemSubtotal = itemTotals.subtotal
|
||||||
|
|
||||||
const itemTotal = MathBN.convert(itemTotals.total)
|
const itemTotal = MathBN.convert(itemTotals.total)
|
||||||
@@ -208,6 +209,10 @@ export function decorateCartTotals(
|
|||||||
|
|
||||||
// TODO: Gift Card calculations
|
// TODO: Gift Card calculations
|
||||||
const originalTotal = MathBN.add(itemsOriginalTotal, shippingOriginalTotal)
|
const originalTotal = MathBN.add(itemsOriginalTotal, shippingOriginalTotal)
|
||||||
|
const originalSubtotal = MathBN.add(
|
||||||
|
itemsOriginalSubtotal,
|
||||||
|
shippingOriginalSubtotal
|
||||||
|
)
|
||||||
|
|
||||||
// TODO: subtract (cart.gift_card_total + cart.gift_card_tax_total)
|
// TODO: subtract (cart.gift_card_total + cart.gift_card_tax_total)
|
||||||
const tempTotal = MathBN.add(subtotal, taxTotal)
|
const tempTotal = MathBN.add(subtotal, taxTotal)
|
||||||
@@ -231,6 +236,7 @@ export function decorateCartTotals(
|
|||||||
// cart.gift_card_tax_total = giftCardTotal.tax_total || 0
|
// cart.gift_card_tax_total = giftCardTotal.tax_total || 0
|
||||||
|
|
||||||
cart.original_total = new BigNumber(originalTotal)
|
cart.original_total = new BigNumber(originalTotal)
|
||||||
|
cart.original_subtotal = new BigNumber(originalSubtotal)
|
||||||
cart.original_tax_total = new BigNumber(originalTaxTotal)
|
cart.original_tax_total = new BigNumber(originalTaxTotal)
|
||||||
|
|
||||||
// cart.original_gift_card_total =
|
// cart.original_gift_card_total =
|
||||||
@@ -264,5 +270,22 @@ export function decorateCartTotals(
|
|||||||
cart.original_shipping_total = new BigNumber(shippingOriginalTotal)
|
cart.original_shipping_total = new BigNumber(shippingOriginalTotal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate pending return total
|
||||||
|
if (cart.summary) {
|
||||||
|
const pendingReturnTotal = MathBN.sum(
|
||||||
|
0,
|
||||||
|
...(cart.items?.map((item) => item.return_requested_total ?? 0) ?? [0])
|
||||||
|
)
|
||||||
|
|
||||||
|
const pendingDifference = new BigNumber(
|
||||||
|
MathBN.sub(
|
||||||
|
MathBN.sub(cart.total, pendingReturnTotal),
|
||||||
|
cart.summary?.transaction_total ?? 0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
cart.summary.pending_difference = pendingDifference
|
||||||
|
}
|
||||||
|
|
||||||
return cart
|
return cart
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ export interface GetItemTotalOutput {
|
|||||||
unit_price: BigNumber
|
unit_price: BigNumber
|
||||||
|
|
||||||
subtotal: BigNumber
|
subtotal: BigNumber
|
||||||
|
original_subtotal: BigNumber
|
||||||
|
|
||||||
total: BigNumber
|
total: BigNumber
|
||||||
original_total: BigNumber
|
original_total: BigNumber
|
||||||
@@ -76,8 +77,7 @@ export function getLineItemsTotals(
|
|||||||
function setRefundableTotal(
|
function setRefundableTotal(
|
||||||
item: GetItemTotalInput,
|
item: GetItemTotalInput,
|
||||||
discountsTotal: BigNumberInput,
|
discountsTotal: BigNumberInput,
|
||||||
totals: GetItemTotalOutput,
|
totals: GetItemTotalOutput
|
||||||
context: GetLineItemsTotalsContext
|
|
||||||
) {
|
) {
|
||||||
const itemDetail = item.detail!
|
const itemDetail = item.detail!
|
||||||
const totalReturnedQuantity = MathBN.sum(
|
const totalReturnedQuantity = MathBN.sum(
|
||||||
@@ -127,54 +127,107 @@ function getLineItemTotals(
|
|||||||
? MathBN.div(totalItemPrice, MathBN.add(1, sumTaxRate))
|
? MathBN.div(totalItemPrice, MathBN.add(1, sumTaxRate))
|
||||||
: totalItemPrice
|
: totalItemPrice
|
||||||
|
|
||||||
|
// Proportional discounts to current quantity and compute taxes on the current net amount
|
||||||
const {
|
const {
|
||||||
adjustmentsTotal: discountsTotal,
|
adjustmentsTotal: discountsTotal,
|
||||||
adjustmentsSubtotal: discountsSubtotal,
|
adjustmentsSubtotal: discountsSubtotalFull,
|
||||||
adjustmentsTaxTotal: discountTaxTotal,
|
adjustmentSubtotalPerItem,
|
||||||
} = calculateAdjustmentTotal({
|
} = calculateAdjustmentTotal({
|
||||||
|
item,
|
||||||
adjustments: item.adjustments || [],
|
adjustments: item.adjustments || [],
|
||||||
taxRate: sumTaxRate,
|
taxRate: sumTaxRate,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const itemDetail = item.detail!
|
||||||
|
const totalReturnedQuantity = MathBN.sum(
|
||||||
|
itemDetail?.return_received_quantity ?? 0,
|
||||||
|
itemDetail?.return_dismissed_quantity ?? 0
|
||||||
|
)
|
||||||
|
|
||||||
|
const currentQuantity = MathBN.sub(item.quantity, totalReturnedQuantity)
|
||||||
|
const currentTotalItemPrice = MathBN.mult(item.unit_price, currentQuantity)
|
||||||
|
const currentSubtotal = isTaxInclusive
|
||||||
|
? MathBN.div(currentTotalItemPrice, MathBN.add(1, sumTaxRate))
|
||||||
|
: currentTotalItemPrice
|
||||||
|
|
||||||
|
const currentDiscountsSubtotal = MathBN.mult(
|
||||||
|
adjustmentSubtotalPerItem ?? 0,
|
||||||
|
currentQuantity
|
||||||
|
)
|
||||||
|
|
||||||
const taxTotal = calculateTaxTotal({
|
const taxTotal = calculateTaxTotal({
|
||||||
taxLines: item.tax_lines || [],
|
taxLines: item.tax_lines || [],
|
||||||
taxableAmount: MathBN.sub(subtotal, discountsSubtotal),
|
taxableAmount: MathBN.sub(currentSubtotal, currentDiscountsSubtotal),
|
||||||
setTotalField: "total",
|
setTotalField: "total",
|
||||||
})
|
})
|
||||||
|
|
||||||
const originalTaxTotal = calculateTaxTotal({
|
const originalTaxTotal = calculateTaxTotal({
|
||||||
taxLines: item.tax_lines || [],
|
taxLines: item.tax_lines || [],
|
||||||
taxableAmount: subtotal,
|
taxableAmount: currentSubtotal,
|
||||||
setTotalField: "subtotal",
|
setTotalField: "subtotal",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Compute full-quantity net total after discounts and taxes to derive per-unit totals
|
||||||
|
const fullDiscountedTaxable = MathBN.sub(subtotal, discountsSubtotalFull ?? 0)
|
||||||
|
const taxTotalFull = calculateTaxTotal({
|
||||||
|
taxLines: item.tax_lines || [],
|
||||||
|
taxableAmount: fullDiscountedTaxable,
|
||||||
|
})
|
||||||
|
const fullNetTotal = MathBN.sum(fullDiscountedTaxable, taxTotalFull)
|
||||||
|
|
||||||
const totals: GetItemTotalOutput = {
|
const totals: GetItemTotalOutput = {
|
||||||
quantity: item.quantity,
|
quantity: item.quantity,
|
||||||
unit_price: item.unit_price,
|
unit_price: item.unit_price,
|
||||||
|
|
||||||
subtotal: new BigNumber(subtotal),
|
subtotal: new BigNumber(currentSubtotal),
|
||||||
|
|
||||||
total: new BigNumber(
|
total: new BigNumber(
|
||||||
MathBN.sum(MathBN.sub(subtotal, discountsSubtotal), taxTotal)
|
MathBN.sum(
|
||||||
|
MathBN.sub(currentSubtotal, currentDiscountsSubtotal),
|
||||||
|
taxTotal
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
original_subtotal: new BigNumber(
|
||||||
|
MathBN.sub(
|
||||||
|
isTaxInclusive
|
||||||
|
? currentTotalItemPrice
|
||||||
|
: MathBN.add(currentSubtotal, originalTaxTotal),
|
||||||
|
originalTaxTotal
|
||||||
|
)
|
||||||
),
|
),
|
||||||
|
|
||||||
original_total: new BigNumber(
|
original_total: new BigNumber(
|
||||||
isTaxInclusive ? totalItemPrice : MathBN.add(subtotal, originalTaxTotal)
|
isTaxInclusive
|
||||||
|
? currentTotalItemPrice
|
||||||
|
: MathBN.add(currentSubtotal, originalTaxTotal)
|
||||||
),
|
),
|
||||||
|
|
||||||
discount_total: new BigNumber(discountsTotal),
|
// Discount values prorated to the current quantity
|
||||||
discount_subtotal: new BigNumber(discountsSubtotal),
|
discount_subtotal: new BigNumber(currentDiscountsSubtotal),
|
||||||
discount_tax_total: new BigNumber(discountTaxTotal),
|
discount_tax_total: new BigNumber(MathBN.sub(originalTaxTotal, taxTotal)),
|
||||||
|
discount_total: new BigNumber(
|
||||||
|
MathBN.add(
|
||||||
|
currentDiscountsSubtotal,
|
||||||
|
MathBN.sub(originalTaxTotal, taxTotal)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
tax_total: new BigNumber(taxTotal),
|
tax_total: new BigNumber(taxTotal),
|
||||||
original_tax_total: new BigNumber(originalTaxTotal),
|
original_tax_total: new BigNumber(originalTaxTotal),
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDefined(item.detail?.return_requested_quantity)) {
|
if (
|
||||||
setRefundableTotal(item, discountsTotal, totals, context)
|
isDefined(item.detail?.return_requested_quantity) ||
|
||||||
|
isDefined(item.detail?.return_received_quantity) ||
|
||||||
|
isDefined(item.detail?.return_dismissed_quantity)
|
||||||
|
) {
|
||||||
|
setRefundableTotal(item, discountsTotal, totals)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Per-unit total should be based on full-quantity net total to support lifecycle totals consistently
|
||||||
const div = MathBN.eq(item.quantity, 0) ? 1 : item.quantity
|
const div = MathBN.eq(item.quantity, 0) ? 1 : item.quantity
|
||||||
const totalPerUnit = MathBN.div(totals.total, div)
|
const totalPerUnit = MathBN.div(fullNetTotal, div)
|
||||||
|
|
||||||
const optionalFields = {
|
const optionalFields = {
|
||||||
...(context.extraQuantityFields ?? {}),
|
...(context.extraQuantityFields ?? {}),
|
||||||
@@ -183,10 +236,9 @@ function getLineItemTotals(
|
|||||||
for (const field in optionalFields) {
|
for (const field in optionalFields) {
|
||||||
const totalField = optionalFields[field]
|
const totalField = optionalFields[field]
|
||||||
|
|
||||||
let target = item[totalField]
|
let target = field.includes(".")
|
||||||
if (field.includes(".")) {
|
? pickValueFromObject(field, item)
|
||||||
target = pickValueFromObject(field, item)
|
: item[field]
|
||||||
}
|
|
||||||
|
|
||||||
if (!isDefined(target)) {
|
if (!isDefined(target)) {
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ export interface GetShippingMethodTotalOutput {
|
|||||||
amount: BigNumber
|
amount: BigNumber
|
||||||
|
|
||||||
subtotal: BigNumber
|
subtotal: BigNumber
|
||||||
|
original_subtotal: BigNumber
|
||||||
|
|
||||||
total: BigNumber
|
total: BigNumber
|
||||||
original_total: BigNumber
|
original_total: BigNumber
|
||||||
@@ -96,6 +97,14 @@ export function getShippingMethodTotals(
|
|||||||
total: new BigNumber(
|
total: new BigNumber(
|
||||||
MathBN.sum(MathBN.sub(subtotal, discountsSubtotal), taxTotal)
|
MathBN.sum(MathBN.sub(subtotal, discountsSubtotal), taxTotal)
|
||||||
),
|
),
|
||||||
|
original_subtotal: new BigNumber(
|
||||||
|
MathBN.sub(
|
||||||
|
isTaxInclusive
|
||||||
|
? shippingMethodAmount
|
||||||
|
: MathBN.add(subtotal, originalTaxTotal),
|
||||||
|
originalTaxTotal
|
||||||
|
)
|
||||||
|
),
|
||||||
original_total: new BigNumber(
|
original_total: new BigNumber(
|
||||||
isTaxInclusive
|
isTaxInclusive
|
||||||
? shippingMethodAmount
|
? shippingMethodAmount
|
||||||
|
|||||||
@@ -11,10 +11,6 @@ export function calculateTaxTotal({
|
|||||||
taxableAmount: BigNumberInput
|
taxableAmount: BigNumberInput
|
||||||
setTotalField?: string
|
setTotalField?: string
|
||||||
}) {
|
}) {
|
||||||
if (MathBN.lte(taxableAmount, 0)) {
|
|
||||||
return MathBN.convert(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
let taxTotal = MathBN.convert(0)
|
let taxTotal = MathBN.convert(0)
|
||||||
|
|
||||||
for (const taxLine of taxLines) {
|
for (const taxLine of taxLines) {
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ export type AdminPostClaimsAddItemsReqSchemaType = z.infer<
|
|||||||
>
|
>
|
||||||
|
|
||||||
export const AdminPostClaimsRequestReturnItemsReqSchema = z.object({
|
export const AdminPostClaimsRequestReturnItemsReqSchema = z.object({
|
||||||
|
location_id: z.string().optional(),
|
||||||
items: z.array(
|
items: z.array(
|
||||||
z.object({
|
z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export const defaultAdminListOrderFields = [
|
|||||||
"region_id",
|
"region_id",
|
||||||
"*items",
|
"*items",
|
||||||
"summary",
|
"summary",
|
||||||
|
"total",
|
||||||
"metadata",
|
"metadata",
|
||||||
"created_at",
|
"created_at",
|
||||||
"updated_at",
|
"updated_at",
|
||||||
@@ -31,6 +32,7 @@ export const defaultAdminOrderFields = [
|
|||||||
"*shipping_methods.tax_lines",
|
"*shipping_methods.tax_lines",
|
||||||
"*shipping_methods.adjustments",
|
"*shipping_methods.adjustments",
|
||||||
"summary",
|
"summary",
|
||||||
|
"total",
|
||||||
"metadata",
|
"metadata",
|
||||||
"created_at",
|
"created_at",
|
||||||
"updated_at",
|
"updated_at",
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ export type AdminPostExchangesAddItemsReqSchemaType = z.infer<
|
|||||||
>
|
>
|
||||||
|
|
||||||
export const AdminPostExchangesReturnRequestItemsReqSchema = z.object({
|
export const AdminPostExchangesReturnRequestItemsReqSchema = z.object({
|
||||||
|
location_id: z.string().optional(),
|
||||||
items: z.array(
|
items: z.array(
|
||||||
z.object({
|
z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ export const defaultAdminOrderFields = [
|
|||||||
"status",
|
"status",
|
||||||
"version",
|
"version",
|
||||||
"summary",
|
"summary",
|
||||||
|
"total",
|
||||||
"metadata",
|
"metadata",
|
||||||
"created_at",
|
"created_at",
|
||||||
"updated_at",
|
"updated_at",
|
||||||
@@ -19,6 +20,7 @@ export const defaultAdminRetrieveOrderFields = [
|
|||||||
"discount_total",
|
"discount_total",
|
||||||
"discount_tax_total",
|
"discount_tax_total",
|
||||||
"original_total",
|
"original_total",
|
||||||
|
"original_subtotal",
|
||||||
"original_tax_total",
|
"original_tax_total",
|
||||||
"item_total",
|
"item_total",
|
||||||
"item_subtotal",
|
"item_subtotal",
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export const defaultStoreRetrieveOrderFields = [
|
|||||||
"discount_subtotal",
|
"discount_subtotal",
|
||||||
"discount_tax_total",
|
"discount_tax_total",
|
||||||
"original_total",
|
"original_total",
|
||||||
|
"original_subtotal",
|
||||||
"original_tax_total",
|
"original_tax_total",
|
||||||
"item_total",
|
"item_total",
|
||||||
"item_subtotal",
|
"item_subtotal",
|
||||||
|
|||||||
@@ -2934,6 +2934,7 @@ moduleIntegrationTestRunner<ICartModuleService>({
|
|||||||
subtotal: 100,
|
subtotal: 100,
|
||||||
total: 0,
|
total: 0,
|
||||||
original_total: 100,
|
original_total: 100,
|
||||||
|
original_subtotal: 100,
|
||||||
discount_total: 100,
|
discount_total: 100,
|
||||||
discount_subtotal: 100,
|
discount_subtotal: 100,
|
||||||
discount_tax_total: 0,
|
discount_tax_total: 0,
|
||||||
@@ -2951,6 +2952,10 @@ moduleIntegrationTestRunner<ICartModuleService>({
|
|||||||
value: "100",
|
value: "100",
|
||||||
precision: 20,
|
precision: 20,
|
||||||
},
|
},
|
||||||
|
raw_original_subtotal: {
|
||||||
|
value: "100",
|
||||||
|
precision: 20,
|
||||||
|
},
|
||||||
raw_discount_total: {
|
raw_discount_total: {
|
||||||
value: "100",
|
value: "100",
|
||||||
precision: 20,
|
precision: 20,
|
||||||
@@ -3042,6 +3047,7 @@ moduleIntegrationTestRunner<ICartModuleService>({
|
|||||||
subtotal: 400,
|
subtotal: 400,
|
||||||
total: 200,
|
total: 200,
|
||||||
original_total: 400,
|
original_total: 400,
|
||||||
|
original_subtotal: 400,
|
||||||
discount_total: 200,
|
discount_total: 200,
|
||||||
discount_subtotal: 200,
|
discount_subtotal: 200,
|
||||||
discount_tax_total: 0,
|
discount_tax_total: 0,
|
||||||
@@ -3059,6 +3065,10 @@ moduleIntegrationTestRunner<ICartModuleService>({
|
|||||||
value: "400",
|
value: "400",
|
||||||
precision: 20,
|
precision: 20,
|
||||||
},
|
},
|
||||||
|
raw_original_subtotal: {
|
||||||
|
value: "400",
|
||||||
|
precision: 20,
|
||||||
|
},
|
||||||
raw_discount_total: {
|
raw_discount_total: {
|
||||||
value: "200",
|
value: "200",
|
||||||
precision: 20,
|
precision: 20,
|
||||||
@@ -3104,6 +3114,7 @@ moduleIntegrationTestRunner<ICartModuleService>({
|
|||||||
subtotal: 10,
|
subtotal: 10,
|
||||||
total: 10,
|
total: 10,
|
||||||
original_total: 10,
|
original_total: 10,
|
||||||
|
original_subtotal: 10,
|
||||||
discount_total: 0,
|
discount_total: 0,
|
||||||
discount_subtotal: 0,
|
discount_subtotal: 0,
|
||||||
discount_tax_total: 0,
|
discount_tax_total: 0,
|
||||||
@@ -3121,6 +3132,10 @@ moduleIntegrationTestRunner<ICartModuleService>({
|
|||||||
value: "10",
|
value: "10",
|
||||||
precision: 20,
|
precision: 20,
|
||||||
},
|
},
|
||||||
|
raw_original_subtotal: {
|
||||||
|
value: "10",
|
||||||
|
precision: 20,
|
||||||
|
},
|
||||||
raw_discount_total: {
|
raw_discount_total: {
|
||||||
value: "0",
|
value: "0",
|
||||||
precision: 20,
|
precision: 20,
|
||||||
@@ -3166,6 +3181,7 @@ moduleIntegrationTestRunner<ICartModuleService>({
|
|||||||
discount_subtotal: 300,
|
discount_subtotal: 300,
|
||||||
discount_tax_total: 0,
|
discount_tax_total: 0,
|
||||||
original_total: 510,
|
original_total: 510,
|
||||||
|
original_subtotal: 510,
|
||||||
original_tax_total: 0,
|
original_tax_total: 0,
|
||||||
item_total: 200,
|
item_total: 200,
|
||||||
item_subtotal: 500,
|
item_subtotal: 500,
|
||||||
@@ -3217,6 +3233,10 @@ moduleIntegrationTestRunner<ICartModuleService>({
|
|||||||
value: "510",
|
value: "510",
|
||||||
precision: 20,
|
precision: 20,
|
||||||
},
|
},
|
||||||
|
raw_original_subtotal: {
|
||||||
|
value: "510",
|
||||||
|
precision: 20,
|
||||||
|
},
|
||||||
raw_original_tax_total: {
|
raw_original_tax_total: {
|
||||||
value: "0",
|
value: "0",
|
||||||
precision: 20,
|
precision: 20,
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ moduleIntegrationTestRunner<IOrderModuleService>({
|
|||||||
const serializedOrder = JSON.parse(
|
const serializedOrder = JSON.parse(
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
await service.retrieveOrder(created.id, {
|
await service.retrieveOrder(created.id, {
|
||||||
select: ["id", "summary"],
|
select: ["id", "summary", "total"],
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -246,7 +246,7 @@ moduleIntegrationTestRunner<IOrderModuleService>({
|
|||||||
const serializedOrder2 = JSON.parse(
|
const serializedOrder2 = JSON.parse(
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
await service.retrieveOrder(created.id, {
|
await service.retrieveOrder(created.id, {
|
||||||
select: ["id", "summary"],
|
select: ["id", "summary", "total"],
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -271,7 +271,7 @@ moduleIntegrationTestRunner<IOrderModuleService>({
|
|||||||
const serializedOrder3 = JSON.parse(
|
const serializedOrder3 = JSON.parse(
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
await service.retrieveOrder(created.id, {
|
await service.retrieveOrder(created.id, {
|
||||||
select: ["id", "summary"],
|
select: ["id", "summary", "total"],
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -290,7 +290,7 @@ moduleIntegrationTestRunner<IOrderModuleService>({
|
|||||||
const serializedOrder4 = JSON.parse(
|
const serializedOrder4 = JSON.parse(
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
await service.retrieveOrder(created.id, {
|
await service.retrieveOrder(created.id, {
|
||||||
select: ["id", "summary"],
|
select: ["id", "summary", "total"],
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ moduleIntegrationTestRunner<IOrderModuleService>({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const changedOrder = await service.retrieveOrder(createdOrder.id, {
|
const changedOrder = await service.retrieveOrder(createdOrder.id, {
|
||||||
select: ["total", "items.detail", "summary"],
|
select: ["total", "items.detail", "summary", "total"],
|
||||||
relations: ["items"],
|
relations: ["items"],
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -492,7 +492,7 @@ moduleIntegrationTestRunner<IOrderModuleService>({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const modified = await service.retrieveOrder(createdOrder.id, {
|
const modified = await service.retrieveOrder(createdOrder.id, {
|
||||||
select: ["total", "items.detail", "summary"],
|
select: ["total", "items.detail", "summary", "total"],
|
||||||
relations: ["items"],
|
relations: ["items"],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -358,6 +358,7 @@ export default class OrderModuleService
|
|||||||
"discount_tax_total",
|
"discount_tax_total",
|
||||||
"original_total",
|
"original_total",
|
||||||
"original_tax_total",
|
"original_tax_total",
|
||||||
|
"pending_difference",
|
||||||
"item_total",
|
"item_total",
|
||||||
"item_subtotal",
|
"item_subtotal",
|
||||||
"item_tax_total",
|
"item_tax_total",
|
||||||
@@ -370,9 +371,13 @@ export default class OrderModuleService
|
|||||||
"original_shipping_tax_total",
|
"original_shipping_tax_total",
|
||||||
"original_shipping_subtotal",
|
"original_shipping_subtotal",
|
||||||
"original_shipping_total",
|
"original_shipping_total",
|
||||||
|
"original_total",
|
||||||
|
"original_subtotal",
|
||||||
|
"original_tax_total",
|
||||||
"credit_line_total",
|
"credit_line_total",
|
||||||
"credit_line_tax_total",
|
"credit_line_tax_total",
|
||||||
"credit_line_subtotal",
|
"credit_line_subtotal",
|
||||||
|
"refundable_amount",
|
||||||
]
|
]
|
||||||
|
|
||||||
const includeTotals = (config?.select ?? []).some((field) =>
|
const includeTotals = (config?.select ?? []).some((field) =>
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ export class OrderChangeProcessing {
|
|||||||
return orderSummary
|
return orderSummary
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the order summary from a calculated order including taxes
|
// Returns the order summary from a calculated order including taxes
|
||||||
public getSummaryFromOrder(order: OrderDTO): OrderSummaryDTO {
|
public getSummaryFromOrder(order: OrderDTO): OrderSummaryDTO {
|
||||||
const summary_ = this.summary
|
const summary_ = this.summary
|
||||||
const total = order.total
|
const total = order.total
|
||||||
@@ -241,35 +241,6 @@ export class OrderChangeProcessing {
|
|||||||
|
|
||||||
orderSummary.accounting_total = orderSummary.current_order_total
|
orderSummary.accounting_total = orderSummary.current_order_total
|
||||||
|
|
||||||
orderSummary.pending_difference = MathBN.sub(
|
|
||||||
orderSummary.current_order_total,
|
|
||||||
orderSummary.transaction_total
|
|
||||||
)
|
|
||||||
|
|
||||||
// return total becomes pending difference
|
|
||||||
for (const item of order.items ?? []) {
|
|
||||||
const item_ = item as any
|
|
||||||
|
|
||||||
;[
|
|
||||||
"return_requested_total",
|
|
||||||
"return_received_total",
|
|
||||||
// TODO: revisit this when we settle on which dismissed items need to be refunded
|
|
||||||
// "return_dismissed_total",
|
|
||||||
].forEach((returnTotalKey) => {
|
|
||||||
const returnTotal = item_[returnTotalKey]
|
|
||||||
|
|
||||||
if (MathBN.gt(returnTotal, 0)) {
|
|
||||||
orderSummary.pending_difference = MathBN.sub(
|
|
||||||
orderSummary.pending_difference,
|
|
||||||
returnTotal
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
orderSummary.pending_difference = new BigNumber(
|
|
||||||
orderSummary.pending_difference
|
|
||||||
)
|
|
||||||
|
|
||||||
return orderSummary
|
return orderSummary
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user