Chore(core-flows,order): exchange/claim add item (#8126)

This commit is contained in:
Carlos R. L. Rodrigues
2024-07-15 08:08:43 -03:00
committed by GitHub
parent 5bb870948a
commit 8d530aa7f2
27 changed files with 636 additions and 70 deletions

View File

@@ -361,7 +361,7 @@ medusaIntegrationTestRunner({
it("should begin a claim order", async () => {
const order = await createOrderFixture({ container, product })
const createClaimOrderData: OrderWorkflow.beginOrderClaimWorkflowInput =
const createClaimOrderData: OrderWorkflow.BeginOrderClaimWorkflowInput =
{
type: ClaimType.REFUND,
order_id: order.id,
@@ -425,8 +425,6 @@ medusaIntegrationTestRunner({
action: "RETURN_ITEM",
details: expect.objectContaining({
quantity: 1,
return_id: expect.stringContaining("return_"),
claim_id: claimOrder.id,
reference_id: order.items![0].id,
}),
}),

View File

@@ -1,6 +1,7 @@
import {
beginExchangeOrderWorkflow,
createShippingOptionsWorkflow,
orderExchangeAddNewItemWorkflow,
orderExchangeRequestItemReturnWorkflow,
} from "@medusajs/core-flows"
import {
@@ -9,7 +10,10 @@ import {
IStockLocationService,
OrderWorkflow,
ProductDTO,
RegionDTO,
SalesChannelDTO,
StockLocationDTO,
UserDTO,
} from "@medusajs/types"
import {
ContainerRegistrationKeys,
@@ -38,6 +42,12 @@ async function prepareDataFixtures({ container }) {
const productModule = container.resolve(ModuleRegistrationName.PRODUCT)
const pricingModule = container.resolve(ModuleRegistrationName.PRICING)
const inventoryModule = container.resolve(ModuleRegistrationName.INVENTORY)
const customerService = container.resolve(ModuleRegistrationName.CUSTOMER)
const customer = await customerService.createCustomers({
first_name: "joe",
email: "joe@gmail.com",
})
const shippingProfile = await fulfillmentService.createShippingProfiles({
name: "test",
@@ -96,17 +106,44 @@ async function prepareDataFixtures({ container }) {
title: "Test variant",
sku: "test-variant",
},
{
title: "another product variant",
sku: "another-variant",
},
],
},
])
const inventoryItem = await inventoryModule.createInventoryItems({
sku: "inv-1234",
})
const priceSets = await pricingModule.createPriceSets([
{
prices: [
{
amount: 45.987,
region_id: region.id,
currency_code: "eur",
},
],
},
])
const inventoryItems = await inventoryModule.createInventoryItems([
{
sku: "inv-1234",
},
{
sku: "another-inv-987",
},
])
await inventoryModule.createInventoryLevels([
{
inventory_item_id: inventoryItem.id,
inventory_item_id: inventoryItems[0].id,
location_id: location.id,
stocked_quantity: 2,
reserved_quantity: 0,
},
{
inventory_item_id: inventoryItems[1].id,
location_id: location.id,
stocked_quantity: 2,
reserved_quantity: 0,
@@ -137,17 +174,28 @@ async function prepareDataFixtures({ container }) {
variant_id: product.variants[0].id,
},
[Modules.INVENTORY]: {
inventory_item_id: inventoryItem.id,
inventory_item_id: inventoryItems[0].id,
},
},
{
[Modules.PRODUCT]: {
variant_id: product.variants[1].id,
},
[Modules.INVENTORY]: {
inventory_item_id: inventoryItems[1].id,
},
},
{
[Modules.PRODUCT]: {
variant_id: product.variants[1].id,
},
[Modules.PRICING]: {
price_set_id: priceSets[0].id,
},
},
])
await pricingModule.createPricePreferences([
{
attribute: "currency_code",
value: "usd",
is_tax_inclusive: true,
},
{
attribute: "region_id",
value: region.id,
@@ -223,13 +271,20 @@ async function prepareDataFixtures({ container }) {
location,
product,
fulfillmentSet,
customer,
}
}
async function createOrderFixture({ container, product }) {
async function createOrderFixture({
container,
product,
salesChannel,
customer,
region,
}) {
const orderService = container.resolve(ModuleRegistrationName.ORDER)
let order = await orderService.createOrders({
region_id: "test_region_id",
region_id: region.id,
email: "foo@bar.com",
items: [
{
@@ -249,7 +304,7 @@ async function createOrderFixture({ container, product }) {
],
} as any,
],
sales_channel_id: "test",
sales_channel_id: salesChannel.id,
shipping_address: {
first_name: "Test",
last_name: "Test",
@@ -290,8 +345,8 @@ async function createOrderFixture({ container, product }) {
],
},
],
currency_code: "usd",
customer_id: "joe",
currency_code: "eur",
customer_id: customer.id,
})
await orderService.addOrderAction([
@@ -339,6 +394,9 @@ medusaIntegrationTestRunner({
describe("Begin exchange order workflow", () => {
let product: ProductDTO
let salesChannel: SalesChannelDTO
let customer: UserDTO
let region: RegionDTO
beforeEach(async () => {
const fixtures = await prepareDataFixtures({
@@ -346,12 +404,21 @@ medusaIntegrationTestRunner({
})
product = fixtures.product
salesChannel = fixtures.salesChannel
customer = fixtures.customer
region = fixtures.region
})
it("should begin an exchange order, request item return", async () => {
const order = await createOrderFixture({ container, product })
const order = await createOrderFixture({
container,
product,
salesChannel,
customer,
region,
})
const createExchangeOrderData: OrderWorkflow.beginOrderExchangeWorkflowInput =
const createExchangeOrderData: OrderWorkflow.BeginOrderExchangeWorkflowInput =
{
order_id: order.id,
metadata: {
@@ -423,8 +490,6 @@ medusaIntegrationTestRunner({
action: "RETURN_ITEM",
details: expect.objectContaining({
quantity: 1,
return_id: expect.stringContaining("return_"),
exchange_id: exchangeOrder.id,
reference_id: order.items![0].id,
}),
}),
@@ -490,6 +555,34 @@ medusaIntegrationTestRunner({
],
})
)
const { result: addItemPreview } =
await orderExchangeAddNewItemWorkflow.run({
container,
input: {
exchange_id: exchangeOrder.id,
items: [
{
variant_id: product.variants[1].id,
quantity: 2,
unit_price: 14.786,
},
],
},
})
expect(addItemPreview.items).toHaveLength(2)
expect(addItemPreview.items[1].actions).toEqual([
expect.objectContaining({
action: "ITEM_ADD",
reference: "order_exchange",
reference_id: exchangeOrder.id,
details: expect.objectContaining({
quantity: 2,
unit_price: 14.786,
}),
}),
])
})
})
},

View File

@@ -359,7 +359,7 @@ medusaIntegrationTestRunner({
it("should begin a return order", async () => {
const order = await createOrderFixture({ container, product })
const createReturnOrderData: OrderWorkflow.beginOrderReturnWorkflowInput =
const createReturnOrderData: OrderWorkflow.BeginOrderReturnWorkflowInput =
{
order_id: order.id,
}

View File

@@ -0,0 +1,33 @@
import { CreateOrderLineItemDTO } from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/utils"
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
interface StepInput {
items: CreateOrderLineItemDTO[]
}
export const createOrderLineItemsStepId = "create-line-items-step"
export const createOrderLineItemsStep = createStep(
createOrderLineItemsStepId,
async (input: StepInput, { container }) => {
const orderModule = container.resolve(ModuleRegistrationName.ORDER)
const createdItems = input.items.length
? await orderModule.createLineItems(input.items)
: []
return new StepResponse(
createdItems,
createdItems.map((c) => c.id)
)
},
async (itemIds, { container }) => {
if (!itemIds?.length) {
return
}
const orderModule = container.resolve(ModuleRegistrationName.ORDER)
await orderModule.deleteLineItems(itemIds)
}
)

View File

@@ -8,6 +8,7 @@ export * from "./complete-orders"
export * from "./create-claims"
export * from "./create-complete-return"
export * from "./create-exchanges"
export * from "./create-line-items"
export * from "./create-order-change"
export * from "./create-order-change-actions"
export * from "./create-orders"

View File

@@ -0,0 +1,148 @@
import { OrderLineItemDTO, OrderWorkflow } from "@medusajs/types"
import { MathBN, MedusaError } from "@medusajs/utils"
import {
WorkflowData,
createWorkflow,
parallelize,
transform,
} from "@medusajs/workflows-sdk"
import { useRemoteQueryStep } from "../../common"
import { findOneOrAnyRegionStep } from "../../definition/cart/steps/find-one-or-any-region"
import { findOrCreateCustomerStep } from "../../definition/cart/steps/find-or-create-customer"
import { findSalesChannelStep } from "../../definition/cart/steps/find-sales-channel"
import { getVariantPriceSetsStep } from "../../definition/cart/steps/get-variant-price-sets"
import { validateVariantPricesStep } from "../../definition/cart/steps/validate-variant-prices"
import { prepareLineItemData } from "../../definition/cart/utils/prepare-line-item-data"
import { confirmVariantInventoryWorkflow } from "../../definition/cart/workflows/confirm-variant-inventory"
import { createOrderLineItemsStep } from "../steps"
import { productVariantsFields } from "../utils/fields"
import { prepareCustomLineItemData } from "../utils/prepare-custom-line-item-data"
function prepareLineItems(data) {
const items = (data.input.items ?? []).map((item) => {
const variant = data.variants.find((v) => v.id === item.variant_id)!
if (!variant) {
return prepareCustomLineItemData({
variant: {
...item,
},
unitPrice: MathBN.max(0, item.unit_price),
isTaxInclusive: item.is_tax_inclusive,
quantity: item.quantity as number,
metadata: item?.metadata ?? {},
})
}
return prepareLineItemData({
variant: variant,
unitPrice: MathBN.max(
0,
item.unit_price ??
data.priceSets[item.variant_id!]?.raw_calculated_amount
),
isTaxInclusive:
item.is_tax_inclusive ??
data.priceSets[item.variant_id!]?.is_calculated_price_tax_inclusive,
quantity: item.quantity as number,
metadata: item?.metadata ?? {},
taxLines: item.tax_lines || [],
adjustments: item.adjustments || [],
})
})
return items
}
export const addOrderLineItemsWorkflowId = "order-add-line-items"
export const addOrderLineItemsWorkflow = createWorkflow(
addOrderLineItemsWorkflowId,
(
input: WorkflowData<OrderWorkflow.OrderAddLineItemWorkflowInput>
): WorkflowData<OrderLineItemDTO[]> => {
const order = useRemoteQueryStep({
entry_point: "orders",
fields: [
"id",
"sales_channel_id",
"region_id",
"customer_id",
"email",
"currency_code",
],
variables: { id: input.order_id },
list: false,
throw_if_key_not_found: true,
}).config({ name: "order-query" })
const variantIds = transform({ input }, (data) => {
return (data.input.items ?? [])
.map((item) => item.variant_id)
.filter(Boolean) as string[]
})
const [salesChannel, region, customerData] = parallelize(
findSalesChannelStep({
salesChannelId: order.sales_channel_id,
}),
findOneOrAnyRegionStep({
regionId: order.region_id,
}),
findOrCreateCustomerStep({
customerId: order.customer_id,
email: order.email,
})
)
const pricingContext = transform(
{ input, region, customerData, order },
(data) => {
if (!data.region) {
throw new MedusaError(MedusaError.Types.NOT_FOUND, "Region not found")
}
return {
currency_code: data.order.currency_code ?? data.region.currency_code,
region_id: data.region.id,
customer_id: data.customerData.customer?.id,
}
}
)
const variants = useRemoteQueryStep({
entry_point: "variants",
fields: productVariantsFields,
variables: {
id: variantIds,
calculated_price: {
context: pricingContext,
},
},
throw_if_key_not_found: true,
}).config({ name: "variants-query" })
validateVariantPricesStep({ variants })
confirmVariantInventoryWorkflow.runAsStep({
input: {
sales_channel_id: salesChannel.id,
variants,
items: input.items!,
},
})
const priceSets = getVariantPriceSetsStep({
variantIds,
context: pricingContext,
})
const lineItems = transform(
{ priceSets, input, variants },
prepareLineItems
)
return createOrderLineItemsStep({
items: lineItems,
})
}
)

View File

@@ -21,7 +21,7 @@ export const beginClaimOrderWorkflowId = "begin-claim-order"
export const beginClaimOrderWorkflow = createWorkflow(
beginClaimOrderWorkflowId,
function (
input: WorkflowData<OrderWorkflow.beginOrderClaimWorkflowInput>
input: WorkflowData<OrderWorkflow.BeginOrderClaimWorkflowInput>
): WorkflowData<OrderChangeDTO> {
const order: OrderDTO = useRemoteQueryStep({
entry_point: "orders",

View File

@@ -21,7 +21,7 @@ export const beginExchangeOrderWorkflowId = "begin-exchange-order"
export const beginExchangeOrderWorkflow = createWorkflow(
beginExchangeOrderWorkflowId,
function (
input: WorkflowData<OrderWorkflow.beginOrderExchangeWorkflowInput>
input: WorkflowData<OrderWorkflow.BeginOrderExchangeWorkflowInput>
): WorkflowData<OrderChangeDTO> {
const order: OrderDTO = useRemoteQueryStep({
entry_point: "orders",

View File

@@ -21,7 +21,7 @@ export const beginReturnOrderWorkflowId = "begin-return-order"
export const beginReturnOrderWorkflow = createWorkflow(
beginReturnOrderWorkflowId,
function (
input: WorkflowData<OrderWorkflow.beginOrderReturnWorkflowInput>
input: WorkflowData<OrderWorkflow.BeginOrderReturnWorkflowInput>
): WorkflowData<OrderChangeDTO> {
const order: OrderDTO = useRemoteQueryStep({
entry_point: "orders",

View File

@@ -0,0 +1,109 @@
import {
OrderChangeDTO,
OrderClaimDTO,
OrderDTO,
OrderWorkflow,
} from "@medusajs/types"
import { ChangeActionType } from "@medusajs/utils"
import {
WorkflowData,
createStep,
createWorkflow,
transform,
} from "@medusajs/workflows-sdk"
import { useRemoteQueryStep } from "../../common"
import { createOrderChangeActionsStep } from "../steps/create-order-change-actions"
import { previewOrderChangeStep } from "../steps/preview-order-change"
import {
throwIfIsCancelled,
throwIfOrderChangeIsNotActive,
throwIfOrderIsCancelled,
} from "../utils/order-validation"
import { addOrderLineItemsWorkflow } from "./add-line-items"
const validationStep = createStep(
"claim-add-new-item-validation",
async function ({
order,
orderChange,
orderClaim,
}: {
order: OrderDTO
orderClaim: OrderClaimDTO
orderChange: OrderChangeDTO
}) {
throwIfOrderIsCancelled({ order })
throwIfIsCancelled(orderClaim, "Claim")
throwIfOrderChangeIsNotActive({ orderChange })
}
)
export const orderClaimAddNewItemWorkflowId = "claim-add-new-item"
export const orderClaimAddNewItemWorkflow = createWorkflow(
orderClaimAddNewItemWorkflowId,
function (
input: WorkflowData<OrderWorkflow.OrderClaimAddNewItemWorkflowInput>
): WorkflowData<OrderDTO> {
const orderClaim = useRemoteQueryStep({
entry_point: "order_claim",
fields: ["id", "order_id"],
variables: { id: input.claim_id },
list: false,
throw_if_key_not_found: true,
}).config({ name: "claim-query" })
const order: OrderDTO = useRemoteQueryStep({
entry_point: "orders",
fields: ["id", "status", "items.*"],
variables: { id: orderClaim.order_id },
list: false,
throw_if_key_not_found: true,
}).config({ name: "order-query" })
const orderChange: OrderChangeDTO = useRemoteQueryStep({
entry_point: "order_change",
fields: ["id", "status"],
variables: { order_id: orderClaim.order_id },
list: false,
}).config({ name: "order-change-query" })
validationStep({
order,
orderClaim,
orderChange,
})
const lineItems = addOrderLineItemsWorkflow.runAsStep({
input: {
order_id: order.id,
items: input.items,
},
})
const orderChangeActionInput = transform(
{ order, orderChange, orderClaim, items: input.items, lineItems },
({ order, orderChange, orderClaim, items, lineItems }) => {
return items.map((item, index) => ({
order_change_id: orderChange.id,
order_id: order.id,
claim_id: orderClaim.id,
version: orderChange.version,
action: ChangeActionType.ITEM_ADD,
internal_note: item.internal_note,
reference: "order_claim",
reference_id: orderClaim.id,
details: {
reference_id: lineItems[index].id,
quantity: item.quantity,
unit_price: item.unit_price,
metadata: item.metadata,
},
}))
}
)
createOrderChangeActionsStep(orderChangeActionInput)
return previewOrderChangeStep(orderClaim.order_id)
}
)

View File

@@ -147,8 +147,6 @@ export const orderClaimRequestItemReturnWorkflow = createWorkflow(
reference_id: orderReturn.id,
details: {
reference_id: item.id,
claim_id: orderClaim.id,
return_id: orderReturn.id,
quantity: item.quantity,
metadata: item.metadata,
},

View File

@@ -38,7 +38,8 @@ function prepareLineItems(data) {
variant: variant,
unitPrice: MathBN.max(
0,
item.unit_price ?? data.priceSets[item.variant_id!]?.calculated_amount
item.unit_price ??
data.priceSets[item.variant_id!]?.raw_calculated_amount
),
isTaxInclusive:
item.is_tax_inclusive ??

View File

@@ -0,0 +1,109 @@
import {
OrderChangeDTO,
OrderDTO,
OrderExchangeDTO,
OrderWorkflow,
} from "@medusajs/types"
import { ChangeActionType } from "@medusajs/utils"
import {
WorkflowData,
createStep,
createWorkflow,
transform,
} from "@medusajs/workflows-sdk"
import { useRemoteQueryStep } from "../../common"
import { createOrderChangeActionsStep } from "../steps/create-order-change-actions"
import { previewOrderChangeStep } from "../steps/preview-order-change"
import {
throwIfIsCancelled,
throwIfOrderChangeIsNotActive,
throwIfOrderIsCancelled,
} from "../utils/order-validation"
import { addOrderLineItemsWorkflow } from "./add-line-items"
const validationStep = createStep(
"exchange-add-new-item-validation",
async function ({
order,
orderChange,
orderExchange,
}: {
order: OrderDTO
orderExchange: OrderExchangeDTO
orderChange: OrderChangeDTO
}) {
throwIfOrderIsCancelled({ order })
throwIfIsCancelled(orderExchange, "Exchange")
throwIfOrderChangeIsNotActive({ orderChange })
}
)
export const orderExchangeAddNewItemWorkflowId = "exchange-add-new-item"
export const orderExchangeAddNewItemWorkflow = createWorkflow(
orderExchangeAddNewItemWorkflowId,
function (
input: WorkflowData<OrderWorkflow.OrderExchangeAddNewItemWorkflowInput>
): WorkflowData<OrderDTO> {
const orderExchange = useRemoteQueryStep({
entry_point: "order_exchange",
fields: ["id", "order_id"],
variables: { id: input.exchange_id },
list: false,
throw_if_key_not_found: true,
}).config({ name: "exchange-query" })
const order: OrderDTO = useRemoteQueryStep({
entry_point: "orders",
fields: ["id", "status", "items.*"],
variables: { id: orderExchange.order_id },
list: false,
throw_if_key_not_found: true,
}).config({ name: "order-query" })
const orderChange: OrderChangeDTO = useRemoteQueryStep({
entry_point: "order_change",
fields: ["id", "status"],
variables: { order_id: orderExchange.order_id },
list: false,
}).config({ name: "order-change-query" })
validationStep({
order,
orderExchange,
orderChange,
})
const lineItems = addOrderLineItemsWorkflow.runAsStep({
input: {
order_id: order.id,
items: input.items,
},
})
const orderChangeActionInput = transform(
{ order, orderChange, orderExchange, items: input.items, lineItems },
({ order, orderChange, orderExchange, items, lineItems }) => {
return items.map((item, index) => ({
order_change_id: orderChange.id,
order_id: order.id,
exchange_id: orderExchange.id,
version: orderChange.version,
action: ChangeActionType.ITEM_ADD,
internal_note: item.internal_note,
reference: "order_exchange",
reference_id: orderExchange.id,
details: {
reference_id: lineItems[index].id,
quantity: item.quantity,
unit_price: item.unit_price,
metadata: item.metadata,
},
}))
}
)
createOrderChangeActionsStep(orderChangeActionInput)
return previewOrderChangeStep(orderExchange.order_id)
}
)

View File

@@ -148,8 +148,6 @@ export const orderExchangeRequestItemReturnWorkflow = createWorkflow(
reference_id: orderReturn.id,
details: {
reference_id: item.id,
exchange_id: orderExchange.id,
return_id: orderReturn.id,
quantity: item.quantity,
metadata: item.metadata,
},

View File

@@ -1,3 +1,4 @@
export * from "./add-line-items"
export * from "./archive-orders"
export * from "./begin-order-claim"
export * from "./begin-order-exchange"
@@ -18,6 +19,7 @@ export * from "./create-shipment"
export * from "./decline-order-change"
export * from "./delete-order-change"
export * from "./delete-order-change-actions"
export * from "./exchange-add-new-item"
export * from "./exchange-request-item-return"
export * from "./get-order-detail"
export * from "./get-orders-list"

View File

@@ -50,7 +50,6 @@ import {
CreateOrderDTO,
CreateOrderExchangeDTO,
CreateOrderLineItemDTO,
CreateOrderLineItemForOrderDTO,
CreateOrderLineItemTaxLineDTO,
CreateOrderReturnDTO,
CreateOrderReturnReasonDTO,
@@ -559,12 +558,8 @@ export interface IOrderModuleService extends IModuleService {
sharedContext?: Context
): Promise<OrderLineItemDTO[]>
createLineItems(
data: CreateOrderLineItemForOrderDTO
): Promise<OrderLineItemDTO[]>
createLineItems(
data: CreateOrderLineItemForOrderDTO[]
): Promise<OrderLineItemDTO[]>
createLineItems(data: CreateOrderLineItemDTO): Promise<OrderLineItemDTO[]>
createLineItems(data: CreateOrderLineItemDTO[]): Promise<OrderLineItemDTO[]>
createLineItems(
orderId: string,
items: CreateOrderLineItemDTO[],

View File

@@ -0,0 +1,34 @@
import { BigNumberInput } from "../../totals"
export interface OrderExchangeAddNewItemWorkflowInput {
exchange_id: string
items: {
variant_id: string
quantity: BigNumberInput
unit_price?: BigNumberInput
internal_note?: string
metadata?: Record<string, any> | null
}[]
}
export interface OrderClaimAddNewItemWorkflowInput {
claim_id: string
items: {
variant_id: string
quantity: BigNumberInput
unit_price?: BigNumberInput
internal_note?: string
metadata?: Record<string, any> | null
}[]
}
export interface OrderAddLineItemWorkflowInput {
order_id: string
items: {
variant_id: string
quantity: BigNumberInput
unit_price?: BigNumberInput
internal_note?: string
metadata?: Record<string, any> | null
}[]
}

View File

@@ -1,6 +1,6 @@
import { OrderClaimType } from "../../order/mutations"
export interface beginOrderClaimWorkflowInput {
export interface BeginOrderClaimWorkflowInput {
type: OrderClaimType
order_id: string
created_by?: string

View File

@@ -1,4 +1,4 @@
export interface beginOrderExchangeWorkflowInput {
export interface BeginOrderExchangeWorkflowInput {
order_id: string
created_by?: string
internal_note?: string

View File

@@ -1,4 +1,4 @@
export interface beginOrderReturnWorkflowInput {
export interface BeginOrderReturnWorkflowInput {
order_id: string
created_by?: string
internal_note?: string

View File

@@ -1,3 +1,4 @@
export * from "./add-new-item"
export * from "./begin-claim-order"
export * from "./begin-exchange-order"
export * from "./begin-return-order"

View File

@@ -171,7 +171,6 @@ describe("Order Exchange - Actions", function () {
id: "item_555",
unit_price: 50,
quantity: 1,
detail: {},
actions: [
{
action: "ITEM_ADD",
@@ -194,7 +193,6 @@ describe("Order Exchange - Actions", function () {
{
id: "shipping_345",
price: 5,
detail: {},
actions: [
{
action: "SHIPPING_ADD",
@@ -206,7 +204,6 @@ describe("Order Exchange - Actions", function () {
{
id: "return_shipping_345",
price: 7.5,
detail: {},
actions: [
{
action: "SHIPPING_ADD",

View File

@@ -1969,18 +1969,57 @@ export default class OrderModuleService<
}
})
const calculated = calculateOrderChange({
order: order as any,
actions: orderChange.actions,
transactions: order.transactions ?? [],
options: {
addActionReferenceToObject: true,
},
})
const { itemsToUpsert, shippingMethodsToUpsert, calculatedOrders } =
applyChangesToOrder(
[order],
{ [order.id]: orderChange.actions },
{ addActionReferenceToObject: true }
)
createRawPropertiesFromBigNumber(calculated)
const calculated = calculatedOrders[order.id]
const addedItems = {}
for (const item of calculated.order.items) {
const isExistingItem = item.id === item.detail?.item_id
if (!isExistingItem) {
addedItems[item.id] = item
}
}
if (Object.keys(addedItems).length > 0) {
const addedItemDetails = await this.listLineItems(
{ id: Object.keys(addedItems) },
{
relations: ["adjustments", "tax_lines"],
},
sharedContext
)
calculated.order.items.forEach((item, idx) => {
if (addedItems[item.id]) {
const lineItem = addedItemDetails.find((d) => d.id === item.id) as any
const actions = item.actions
delete item.actions
const newItem = itemsToUpsert.find((d) => d.item_id === item.id)!
calculated.order.items[idx] = {
...lineItem,
actions,
quantity: newItem.quantity,
detail: {
...newItem,
...item,
},
}
}
})
}
// TODO - add new shipping methods
const calcOrder = calculated.order
const calcOrder = calculated.order as any
decorateCartTotals(calcOrder as DecorateCartLikeInputDTO)
calcOrder.summary = calculated.summary

View File

@@ -30,9 +30,9 @@ OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_ADD, {
existing = {
id: action.details.reference_id!,
order_id: currentOrder.id,
return_id: action.details.return_id,
claim_id: action.details.claim_id,
exchange_id: action.details.exchange_id,
return_id: action.return_id,
claim_id: action.claim_id,
exchange_id: action.exchange_id,
unit_price: action.details.unit_price,
quantity: action.details.quantity,

View File

@@ -12,22 +12,29 @@ export interface ApplyOrderChangeDTO extends OrderChangeActionDTO {
export function applyChangesToOrder(
orders: any[],
actionsMap: Record<string, any[]>
actionsMap: Record<string, any[]>,
options?: {
addActionReferenceToObject?: boolean
}
) {
const itemsToUpsert: OrderItem[] = []
const shippingMethodsToUpsert: OrderShippingMethod[] = []
const summariesToUpsert: any[] = []
const orderToUpdate: any[] = []
const calculatedOrders = {}
for (const order of orders) {
const calculated = calculateOrderChange({
order: order as any,
actions: actionsMap[order.id],
transactions: order.transactions ?? [],
options,
})
createRawPropertiesFromBigNumber(calculated)
calculatedOrders[order.id] = calculated
const version = actionsMap[order.id][0].version ?? 1
for (const item of calculated.order.items) {
@@ -41,11 +48,11 @@ export function applyChangesToOrder(
order_id: order.id,
version,
quantity: orderItem.quantity,
fulfilled_quantity: orderItem.fulfilled_quantity,
shipped_quantity: orderItem.shipped_quantity,
return_requested_quantity: orderItem.return_requested_quantity,
return_received_quantity: orderItem.return_received_quantity,
return_dismissed_quantity: orderItem.return_dismissed_quantity,
fulfilled_quantity: orderItem.fulfilled_quantity ?? 0,
shipped_quantity: orderItem.shipped_quantity ?? 0,
return_requested_quantity: orderItem.return_requested_quantity ?? 0,
return_received_quantity: orderItem.return_received_quantity ?? 0,
return_dismissed_quantity: orderItem.return_dismissed_quantity ?? 0,
written_off_quantity: orderItem.written_off_quantity,
metadata: orderItem.metadata,
} as OrderItem)
@@ -90,5 +97,6 @@ export function applyChangesToOrder(
shippingMethodsToUpsert,
summariesToUpsert,
orderToUpdate,
calculatedOrders,
}
}

View File

@@ -1,11 +1,4 @@
export function setActionReference(existing, action, options) {
existing.detail ??= {}
existing.detail.order_id ??= action.order_id
existing.detail.return_id ??= action.return_id
existing.detail.claim_id ??= action.claim_id
existing.detail.exchange_id ??= action.exchange_id
if (options?.addActionReferenceToObject) {
existing.actions ??= []
existing.actions.push(action)

View File

@@ -33,6 +33,11 @@ export function formatOrder(
}
mainOrder.items = mainOrder.items?.map((orderItem) => {
const isFormatted = isDefined(orderItem.detail?.fulfilled_quantity)
if (isFormatted) {
return orderItem
}
const detail = { ...orderItem }
delete detail.order
delete detail.item
@@ -62,6 +67,10 @@ export function formatOrder(
if (order.shipping_methods) {
order.shipping_methods = order.shipping_methods?.map((shippingMethod) => {
if (shippingMethod.detail) {
return shippingMethod
}
const sm = { ...shippingMethod.shipping_method }
delete shippingMethod.shipping_method