feat: Add exchange return shipping (#8108)

* wip

* finalize tests

* feat: Add exchange return shipping

* add shipping to preview

* test input

* move utils and ignore already inserted shipping method

* use custom price

---------

Co-authored-by: Carlos R. L. Rodrigues <rodrigolr@gmail.com>
This commit is contained in:
Oli Juhl
2024-07-15 22:04:20 +02:00
committed by GitHub
parent b38c0488be
commit ffd4b195ee
25 changed files with 511 additions and 165 deletions
@@ -225,21 +225,11 @@ medusaIntegrationTestRunner({
adminHeaders
)
expect(result.data.return).toEqual(
expect(result.data.order.shipping_methods[1]).toEqual(
expect.objectContaining({
id: expect.any(String),
order_id: order.id,
display_id: 1,
order_version: 2,
status: "requested",
items: [],
shipping_methods: [
expect.objectContaining({
amount: 1000,
name: "Return shipping",
shipping_option_id: returnShippingOption.id,
}),
],
amount: 1000,
name: "Return shipping",
shipping_option_id: returnShippingOption.id,
})
)
@@ -0,0 +1,126 @@
import {
beginExchangeOrderWorkflow,
createExchangeReturnShippingMethodWorkflow,
} from "@medusajs/core-flows"
import { OrderDTO, OrderExchangeDTO } from "@medusajs/types"
import {
ContainerRegistrationKeys,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import { medusaIntegrationTestRunner } from "medusa-test-utils"
import { createOrderFixture, prepareDataFixtures } from "../__fixtures__"
jest.setTimeout(50000)
medusaIntegrationTestRunner({
env: { MEDUSA_FF_MEDUSA_V2: true },
testSuite: ({ getContainer }) => {
let container
beforeAll(() => {
container = getContainer()
})
describe("Order change: Create exchange return shipping", () => {
let order: OrderDTO
let fixtures
let exchangeOrder: OrderExchangeDTO
beforeEach(async () => {
fixtures = await prepareDataFixtures({ container })
order = await createOrderFixture({
container,
product: fixtures.product,
location: fixtures.location,
inventoryItem: fixtures.inventoryItem,
})
await beginExchangeOrderWorkflow(container).run({
input: { order_id: order.id },
throwOnError: true,
})
const remoteQuery = container.resolve(
ContainerRegistrationKeys.REMOTE_QUERY
)
const remoteQueryObject = remoteQueryObjectFromString({
entryPoint: "order_exchange",
variables: { order_id: order.id },
fields: ["order_id", "id", "status", "order_change_id", "return_id"],
})
;[exchangeOrder] = await remoteQuery(remoteQueryObject)
})
describe("createExchangeReturnShippingMethodWorkflow", () => {
it("should successfully add exchange return shipping to order changes", async () => {
const shippingOptionId = fixtures.shippingOption.id
const { result } = await createExchangeReturnShippingMethodWorkflow(
container
).run({
input: {
exchangeId: exchangeOrder.id,
shippingOptionId: shippingOptionId,
},
})
const orderChange = result?.[0]
expect(orderChange).toEqual(
expect.objectContaining({
id: expect.any(String),
reference: "order_shipping_method",
reference_id: expect.any(String),
details: {
exchange_id: exchangeOrder.id,
order_id: exchangeOrder.order_id,
return_id: exchangeOrder.return_id,
},
raw_amount: { value: "10", precision: 20 },
applied: false,
action: "SHIPPING_ADD",
amount: 10,
})
)
})
it("should successfully add return shipping with custom price to order changes", async () => {
const shippingOptionId = fixtures.shippingOption.id
const { result } = await createExchangeReturnShippingMethodWorkflow(
container
).run({
input: {
exchangeId: exchangeOrder.id,
shippingOptionId: shippingOptionId,
customShippingPrice: 20,
},
})
const orderChange = result?.[0]
expect(orderChange).toEqual(
expect.objectContaining({
id: expect.any(String),
reference: "order_shipping_method",
reference_id: expect.any(String),
details: {
exchange_id: exchangeOrder.id,
order_id: exchangeOrder.order_id,
return_id: exchangeOrder.return_id,
},
raw_amount: { value: "20", precision: 20 },
applied: false,
action: "SHIPPING_ADD",
amount: 20,
})
)
})
})
})
},
})
@@ -2,9 +2,10 @@ import {
beginReturnOrderWorkflow,
createReturnShippingMethodWorkflow,
} from "@medusajs/core-flows"
import { OrderDTO, ReturnDTO } from "@medusajs/types"
import { IFulfillmentModuleService, OrderDTO, ReturnDTO } from "@medusajs/types"
import {
ContainerRegistrationKeys,
ModuleRegistrationName,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import { medusaIntegrationTestRunner } from "medusa-test-utils"
@@ -23,6 +24,7 @@ medusaIntegrationTestRunner({
describe("Order change: Create return shipping", () => {
let order: OrderDTO
let service: IFulfillmentModuleService
let fixtures
let returnOrder: ReturnDTO
@@ -52,6 +54,7 @@ medusaIntegrationTestRunner({
fields: ["order_id", "id", "status", "order_change_id"],
})
service = container.resolve(ModuleRegistrationName.FULFILLMENT)
;[returnOrder] = await remoteQuery(remoteQueryObject)
})
@@ -59,62 +62,50 @@ medusaIntegrationTestRunner({
it("should successfully add return shipping to order changes", async () => {
const shippingOptionId = fixtures.shippingOption.id
const { result } = await createReturnShippingMethodWorkflow(
container
).run({
input: {
return_id: returnOrder.id,
shipping_option_id: shippingOptionId,
},
})
const { result: orderChangePreview } =
await createReturnShippingMethodWorkflow(container).run({
input: {
return_id: returnOrder.id,
shipping_option_id: shippingOptionId,
},
})
const orderChange = result?.[0]
expect(orderChange).toEqual(
expect(orderChangePreview.shipping_methods[1].actions).toEqual([
expect.objectContaining({
id: expect.any(String),
reference: "order_shipping_method",
reference_id: expect.any(String),
order_id: returnOrder.order_id,
return_id: returnOrder.id,
details: {},
raw_amount: { value: "10", precision: 20 },
applied: false,
action: "SHIPPING_ADD",
amount: 10,
})
)
}),
])
})
it("should successfully add return shipping with custom price to order changes", async () => {
const shippingOptionId = fixtures.shippingOption.id
const { result } = await createReturnShippingMethodWorkflow(
container
).run({
input: {
return_id: returnOrder.id,
shipping_option_id: shippingOptionId,
custom_price: 20,
},
})
const { result: orderChangePreview } =
await createReturnShippingMethodWorkflow(container).run({
input: {
return_id: returnOrder.id,
shipping_option_id: shippingOptionId,
custom_price: 20,
},
})
const orderChange = result?.[0]
expect(orderChange).toEqual(
expect(orderChangePreview.shipping_methods[1].actions).toEqual([
expect.objectContaining({
id: expect.any(String),
reference: "order_shipping_method",
reference_id: expect.any(String),
order_id: returnOrder.order_id,
return_id: returnOrder.id,
details: {},
raw_amount: { value: "20", precision: 20 },
applied: false,
action: "SHIPPING_ADD",
amount: 20,
})
)
}),
])
})
})
})
@@ -1,13 +1,12 @@
import { OrderChangeDTO, OrderDTO, ReturnDTO } from "@medusajs/types"
import { ChangeActionType } from "@medusajs/utils"
import {
WorkflowData,
createStep,
createWorkflow,
transform,
WorkflowData,
} from "@medusajs/workflows-sdk"
import { useRemoteQueryStep } from "../../common"
import { previewOrderChangeStep } from "../steps"
import { confirmOrderChanges } from "../steps/confirm-order-changes"
import { createReturnItems } from "../steps/create-return-items"
import {
@@ -39,7 +38,7 @@ const validationStep = createStep(
export const confirmReturnRequestWorkflowId = "confirm-return-request"
export const confirmReturnRequestWorkflow = createWorkflow(
confirmReturnRequestWorkflowId,
function (input: WorkflowInput): WorkflowData<OrderDTO> {
function (input: WorkflowInput): WorkflowData<void> {
const orderReturn: ReturnDTO = useRemoteQueryStep({
entry_point: "return",
fields: ["id", "status", "order_id"],
@@ -87,7 +86,5 @@ export const confirmReturnRequestWorkflow = createWorkflow(
createReturnItems({ returnId: orderReturn.id, changes: returnItemActions })
confirmOrderChanges({ changes: [orderChange], orderId: order.id })
return previewOrderChangeStep(order.id)
}
)
@@ -0,0 +1,147 @@
import {
BigNumberInput,
OrderChangeDTO,
OrderDTO,
OrderExchangeDTO,
} from "@medusajs/types"
import { ChangeActionType } from "@medusajs/utils"
import {
createStep,
createWorkflow,
transform,
WorkflowData,
} from "@medusajs/workflows-sdk"
import { useRemoteQueryStep } from "../../common"
import { createOrderChangeActionsStep } from "../steps/create-order-change-actions"
import { createOrderShippingMethods } from "../steps/create-order-shipping-methods"
import {
throwIfOrderChangeIsNotActive,
throwIfOrderIsCancelled,
} from "../utils/order-validation"
const validationStep = createStep(
"validate-create-exchange-return-shipping-method",
async function ({
order,
orderChange,
}: {
order: OrderDTO
orderChange: OrderChangeDTO
}) {
throwIfOrderIsCancelled({ order })
throwIfOrderChangeIsNotActive({ orderChange })
}
)
export const createExchangeReturnShippingMethodWorkflowId =
"create-exchange-return-shipping-method"
export const createExchangeReturnShippingMethodWorkflow = createWorkflow(
createExchangeReturnShippingMethodWorkflowId,
function (input: {
exchangeId: string
shippingOptionId: string
customShippingPrice?: BigNumberInput
}): WorkflowData {
const orderExchange: OrderExchangeDTO = useRemoteQueryStep({
entry_point: "order_exchange",
fields: ["id", "status", "order_id", "return_id"],
variables: { id: input.exchangeId },
list: false,
throw_if_key_not_found: true,
})
const order: OrderDTO = useRemoteQueryStep({
entry_point: "orders",
fields: ["id", "status", "currency_code"],
variables: { id: orderExchange.order_id },
list: false,
throw_if_key_not_found: true,
}).config({ name: "order-query" })
const shippingOptions = useRemoteQueryStep({
entry_point: "shipping_option",
fields: [
"id",
"name",
"calculated_price.calculated_amount",
"calculated_price.is_calculated_price_tax_inclusive",
],
variables: {
id: input.shippingOptionId,
calculated_price: {
context: { currency_code: order.currency_code },
},
},
}).config({ name: "fetch-shipping-option" })
const shippingMethodInput = transform(
{ orderExchange, shippingOptions, input },
(data) => {
const option = data.shippingOptions[0]
return {
shipping_option_id: option.id,
amount:
data.input.customShippingPrice ??
option.calculated_price.calculated_amount,
is_tax_inclusive:
!!option.calculated_price.is_calculated_price_tax_inclusive,
data: option.data ?? {},
name: option.name,
order_id: data.orderExchange.order_id,
return_id: data.orderExchange.return_id,
exchange_id: data.orderExchange.id,
}
}
)
const createdMethods = createOrderShippingMethods({
shipping_methods: [shippingMethodInput],
})
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, orderChange })
const orderChangeActionInput = transform(
{
orderId: order.id,
returnId: orderExchange.return_id,
exchangeId: orderExchange.id,
shippingOption: shippingOptions[0],
methodId: createdMethods[0].id,
customPrice: input.customShippingPrice,
},
({
shippingOption,
exchangeId,
returnId,
orderId,
methodId,
customPrice,
}) => {
const methodPrice =
customPrice ?? shippingOption.calculated_price.calculated_amount
return {
action: ChangeActionType.SHIPPING_ADD,
reference: "order_shipping_method",
reference_id: methodId,
amount: methodPrice,
details: {
order_id: orderId,
return_id: returnId,
exchange_id: exchangeId,
},
}
}
)
return createOrderChangeActionsStep([orderChangeActionInput])
}
)
@@ -4,16 +4,17 @@ import {
OrderDTO,
ReturnDTO,
} from "@medusajs/types"
import { ChangeActionType } from "@medusajs/utils"
import { ChangeActionType, OrderChangeStatus } from "@medusajs/utils"
import {
WorkflowData,
createStep,
createWorkflow,
transform,
WorkflowData,
} from "@medusajs/workflows-sdk"
import { useRemoteQueryStep } from "../../common"
import { createOrderChangeActionsStep } from "../steps/create-order-change-actions"
import { createOrderShippingMethods } from "../steps/create-order-shipping-methods"
import { previewOrderChangeStep } from "../steps/preview-order-change"
import {
throwIfIsCancelled,
throwIfOrderChangeIsNotActive,
@@ -77,10 +78,25 @@ export const createReturnShippingMethodWorkflow = createWorkflow(
},
}).config({ name: "fetch-shipping-option" })
const orderChange: OrderChangeDTO = useRemoteQueryStep({
entry_point: "order_change",
fields: ["id", "status", "version"],
variables: {
filters: {
order_id: orderReturn.order_id,
status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED],
},
},
list: false,
}).config({ name: "order-change-query" })
validationStep({ order, orderReturn, orderChange })
const shippingMethodInput = transform(
{ orderReturn, shippingOptions },
{ orderReturn, shippingOptions, orderChange },
(data) => {
const option = data.shippingOptions[0]
const orderChange = data.orderChange
return {
shipping_option_id: option.id,
@@ -89,6 +105,7 @@ export const createReturnShippingMethodWorkflow = createWorkflow(
!!option.calculated_price.is_calculated_price_tax_inclusive,
data: option.data ?? {},
name: option.name,
version: orderChange.version,
order_id: data.orderReturn.order_id,
return_id: data.orderReturn.id,
}
@@ -99,40 +116,42 @@ export const createReturnShippingMethodWorkflow = createWorkflow(
shipping_methods: [shippingMethodInput],
})
const orderChange: OrderChangeDTO = useRemoteQueryStep({
entry_point: "order_change",
fields: ["id", "status"],
variables: {
filters: { order_id: orderReturn.order_id, return_id: orderReturn.id },
},
list: false,
}).config({ name: "order-change-query" })
validationStep({ order, orderReturn, orderChange })
const orderChangeActionInput = transform(
{
orderId: order.id,
returnId: orderReturn.id,
shippingOption: shippingOptions[0],
methodId: createdMethods[0].id,
order,
orderReturn,
shippingOptions,
createdMethods,
customPrice: input.custom_price,
orderChange,
},
({ shippingOption, returnId, orderId, methodId, customPrice }) => {
({
shippingOptions,
orderReturn,
order,
createdMethods,
customPrice,
orderChange,
}) => {
const shippingOption = shippingOptions[0]
const createdMethod = createdMethods[0]
const methodPrice =
customPrice ?? shippingOption.calculated_price.calculated_amount
return {
action: ChangeActionType.SHIPPING_ADD,
reference: "order_shipping_method",
reference_id: methodId,
reference_id: createdMethod.id,
order_change_id: orderChange.id,
amount: methodPrice,
order_id: orderId,
return_id: returnId,
order_id: order.id,
return_id: orderReturn.id,
}
}
)
return createOrderChangeActionsStep([orderChangeActionInput])
createOrderChangeActionsStep([orderChangeActionInput])
return previewOrderChangeStep(order.id)
}
)
@@ -11,6 +11,7 @@ export * from "./claim-request-item-return"
export * from "./complete-orders"
export * from "./confirm-return-request"
export * from "./create-complete-return"
export * from "./create-exchange-return-shipping-method"
export * from "./create-fulfillment"
export * from "./create-order-change"
export * from "./create-order-change-actions"
+2
View File
@@ -1161,6 +1161,8 @@ export interface OrderExchangeDTO
no_notification?: boolean
difference_due?: BigNumberValue
return?: ReturnDTO
return_id?: string
order_id: string
}
export type PaymentStatus =
+1
View File
@@ -1,3 +1,4 @@
export * from "./events"
export * from "./order-change"
export * from "./order-change-action"
export * from "./status"
@@ -0,0 +1,29 @@
export enum OrderChangeStatus {
/**
* The order change is confirmed.
*/
CONFIRMED = "confirmed",
/**
* The order change is declined.
*/
DECLINED = "declined",
/**
* The order change is requested.
*/
REQUESTED = "requested",
/**
* The order change is pending.
*/
PENDING = "pending",
/**
* The order change is canceled.
*/
CANCELED = "canceled",
}
export enum OrderChangeType {
RETURN = "return",
EXCHANGE = "exchange",
CLAIM = "claim",
EDIT = "edit",
}
@@ -1,8 +1,4 @@
import { createReturnShippingMethodWorkflow } from "@medusajs/core-flows"
import {
ContainerRegistrationKeys,
remoteQueryObjectFromString,
} from "@medusajs/utils"
import {
AuthenticatedMedusaRequest,
MedusaResponse,
@@ -15,26 +11,13 @@ export const POST = async (
) => {
const { id } = req.params
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
await createReturnShippingMethodWorkflow(req.scope).run({
const { result: orderPreview } = await createReturnShippingMethodWorkflow(
req.scope
).run({
input: { ...req.validatedBody, return_id: id },
})
const queryObject = remoteQueryObjectFromString({
entryPoint: "return",
variables: {
id,
filters: {
...req.filterableFields,
},
},
fields: req.remoteQueryConfig.fields,
})
const [orderReturn] = await remoteQuery(queryObject)
res.json({
return: orderReturn,
order: orderPreview,
})
}
@@ -0,0 +1,12 @@
import { Migration } from "@mikro-orm/migrations"
export class Migration20240715102100 extends Migration {
async up(): Promise<void> {
const sql = `
ALTER TABLE "return"
ADD COLUMN if NOT exists "location_id" TEXT NULL;
`
this.addSql(sql)
}
}
@@ -2,6 +2,8 @@ import { DAL } from "@medusajs/types"
import {
createPsqlIndexStatementHelper,
generateEntityId,
OrderChangeStatus,
OrderChangeType,
} from "@medusajs/utils"
import {
BeforeCreate,
@@ -10,14 +12,14 @@ import {
Entity,
Enum,
ManyToOne,
OnInit,
OneToMany,
OnInit,
OptionalProps,
PrimaryKey,
Property,
Rel,
} from "@mikro-orm/core"
import { OrderChangeStatus, OrderChangeType } from "@types"
import {} from "@types"
import OrderClaim from "./claim"
import OrderExchange from "./exchange"
import Order from "./order"
@@ -116,6 +116,9 @@ export default class Return {
@Enum({ items: () => ReturnStatus, default: ReturnStatus.REQUESTED })
status: ReturnStatus = ReturnStatus.REQUESTED
@Property({ columnType: "text", nullable: true })
location_id: string | null = null
@Property({ columnType: "boolean", nullable: true })
no_notification: boolean | null = null
@@ -54,7 +54,7 @@ describe("Order Exchange - Actions", function () {
shipping_methods: [
{
id: "ship_123",
price: 0,
amount: 0,
},
],
total: 270,
@@ -188,11 +188,11 @@ describe("Order Exchange - Actions", function () {
expect(changes.order.shipping_methods).toEqual([
{
id: "ship_123",
price: 0,
amount: 0,
},
{
id: "shipping_345",
price: 5,
amount: 5,
actions: [
{
action: "SHIPPING_ADD",
@@ -203,7 +203,7 @@ describe("Order Exchange - Actions", function () {
},
{
id: "return_shipping_345",
price: 7.5,
amount: 7.5,
actions: [
{
action: "SHIPPING_ADD",
@@ -6,13 +6,13 @@ import {
import {
ChangeActionType,
ClaimType,
OrderChangeType,
ReturnStatus,
getShippingMethodsTotals,
isString,
promiseAll,
} from "@medusajs/utils"
import { ClaimItem, OrderClaim, Return, ReturnItem } from "@models"
import { OrderChangeType } from "@types"
function createClaimAndReturnEntities(em, data, order) {
const claimReference = em.create(OrderClaim, {
@@ -5,13 +5,13 @@ import {
} from "@medusajs/types"
import {
ChangeActionType,
OrderChangeType,
ReturnStatus,
getShippingMethodsTotals,
isString,
promiseAll,
} from "@medusajs/utils"
import { ExchangeItem, OrderExchange, Return, ReturnItem } from "@models"
import { OrderChangeType } from "@types"
function createExchangeAndReturnEntities(em, data, order) {
const exchangeReference = em.create(OrderExchange, {
@@ -5,6 +5,7 @@ import {
} from "@medusajs/types"
import {
ChangeActionType,
OrderChangeType,
ReturnStatus,
getShippingMethodsTotals,
isDefined,
@@ -12,7 +13,6 @@ import {
promiseAll,
} from "@medusajs/utils"
import { Return, ReturnItem } from "@models"
import { OrderChangeType } from "@types"
function createReturnReference(em, data, order) {
return em.create(Return, {
@@ -2,10 +2,10 @@ import { Context, OrderTypes } from "@medusajs/types"
import {
ChangeActionType,
MathBN,
OrderChangeType,
ReturnStatus,
promiseAll,
} from "@medusajs/utils"
import { OrderChangeType } from "@types"
function createReturnItems(data) {
return data.items.map((item) => ({
@@ -21,12 +21,14 @@ import {
deduplicate,
InjectManager,
InjectTransactionManager,
isDefined,
isObject,
isString,
MathBN,
MedusaContext,
MedusaError,
ModulesSdkUtils,
OrderChangeStatus,
OrderStatus,
promiseAll,
transformPropertiesToBigNumber,
@@ -59,7 +61,6 @@ import {
CreateOrderLineItemTaxLineDTO,
CreateOrderShippingMethodDTO,
CreateOrderShippingMethodTaxLineDTO,
OrderChangeStatus,
UpdateOrderItemDTO,
UpdateOrderLineItemDTO,
UpdateOrderLineItemTaxLineDTO,
@@ -1193,7 +1194,7 @@ export default class OrderModuleService<
return_id: dt.return_id,
claim_id: dt.claim_id,
exchange_id: dt.exchange_id,
version: mapOrderVersion[dt.order_id],
version: dt.version ?? mapOrderVersion[dt.order_id],
}
})
@@ -1979,13 +1980,20 @@ export default class OrderModuleService<
const calculated = calculatedOrders[order.id]
const addedItems = {}
const addedShippingMethods = {}
for (const item of calculated.order.items) {
const isExistingItem = item.id === item.detail?.item_id
if (!isExistingItem) {
addedItems[item.id] = item
}
}
for (const sm of calculated.order.shipping_methods) {
if (!isDefined(sm.shipping_option_id)) {
addedShippingMethods[sm.id] = sm
}
}
if (Object.keys(addedItems).length > 0) {
const addedItemDetails = await this.listLineItems(
{ id: Object.keys(addedItems) },
@@ -1996,22 +2004,61 @@ export default class OrderModuleService<
)
calculated.order.items.forEach((item, idx) => {
if (addedItems[item.id]) {
const lineItem = addedItemDetails.find((d) => d.id === item.id) as any
if (!addedItems[item.id]) {
return
}
const actions = item.actions
delete item.actions
const lineItem = addedItemDetails.find((d) => d.id === item.id) as any
const newItem = itemsToUpsert.find((d) => d.item_id === item.id)!
calculated.order.items[idx] = {
...lineItem,
actions,
quantity: newItem.quantity,
detail: {
...newItem,
...item,
},
}
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,
},
}
})
}
if (Object.keys(addedShippingMethods).length > 0) {
const addedShippingDetails = await this.listShippingMethods(
{ id: Object.keys(addedShippingMethods) },
{
relations: ["adjustments", "tax_lines"],
},
sharedContext
)
calculated.order.shipping_methods.forEach((sm, idx) => {
if (!addedShippingMethods[sm.id]) {
return
}
const shippingMethod = addedShippingDetails.find(
(d) => d.id === sm.id
) as any
const actions = sm.actions
delete sm.actions
const newItem = shippingMethodsToUpsert.find((d) => d.id === sm.id)!
sm.shipping_method_id = sm.id
delete sm.id
calculated.order.shipping_methods[idx] = {
...shippingMethod,
actions,
detail: {
...sm,
...newItem,
},
}
})
}
@@ -2579,7 +2626,9 @@ export default class OrderModuleService<
shippingMethodsToUpsert,
summariesToUpsert,
orderToUpdate,
} = applyChangesToOrder(orders, actionsMap)
} = applyChangesToOrder(orders, actionsMap, {
addActionReferenceToObject: true,
})
await promiseAll([
orderToUpdate.length
@@ -1,34 +1,5 @@
import { OrderTypes } from "@medusajs/types"
export enum OrderChangeStatus {
/**
* The order change is confirmed.
*/
CONFIRMED = "confirmed",
/**
* The order change is declined.
*/
DECLINED = "declined",
/**
* The order change is requested.
*/
REQUESTED = "requested",
/**
* The order change is pending.
*/
PENDING = "pending",
/**
* The order change is canceled.
*/
CANCELED = "canceled",
}
export enum OrderChangeType {
RETURN = "return",
EXCHANGE = "exchange",
CLAIM = "claim",
EDIT = "edit",
}
import { OrderChangeType } from "@medusajs/utils"
export interface CreateOrderChangeDTO extends OrderTypes.CreateOrderChangeDTO {
change_type?: OrderChangeType
@@ -47,7 +47,7 @@ export type VirtualOrder = {
exchange_id?: string
}
price: BigNumberInput
amount: BigNumberInput
}[]
total: BigNumberInput
@@ -17,7 +17,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.SHIPPING_ADD, {
return_id: action.return_id,
claim_id: action.claim_id,
exchange_id: action.exchange_id,
price: action.amount as number,
amount: action.amount as number,
}
shipping.push(existing)
}
@@ -33,7 +33,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.SHIPPING_REMOVE, {
return_id: action.return_id,
claim_id: action.claim_id,
exchange_id: action.exchange_id,
price: action.amount as number,
amount: action.amount as number,
})
}
},
@@ -1,5 +1,9 @@
import { OrderChangeActionDTO } from "@medusajs/types"
import { createRawPropertiesFromBigNumber } from "@medusajs/utils"
import {
ChangeActionType,
createRawPropertiesFromBigNumber,
isDefined,
} from "@medusajs/utils"
import { OrderItem, OrderShippingMethod } from "@models"
import { calculateOrderChange } from "./calculate-order-change"
@@ -35,7 +39,7 @@ export function applyChangesToOrder(
calculatedOrders[order.id] = calculated
const version = actionsMap[order.id][0].version ?? 1
const version = actionsMap[order.id]?.[0]?.version ?? order.version
for (const item of calculated.order.items) {
const isExistingItem = item.id === item.detail?.item_id
@@ -68,17 +72,36 @@ export function applyChangesToOrder(
if (version > order.version) {
for (const shippingMethod of calculated.order.shipping_methods ?? []) {
if (!shippingMethod) {
const shippingMethod_ = shippingMethod as any
const isNewShippingMethod = !isDefined(shippingMethod_?.detail)
if (!shippingMethod_) {
continue
}
const sm = {
...((shippingMethod as any).detail ?? shippingMethod),
version,
let associatedMethodId
let hasShippingMethod = false
if (isNewShippingMethod) {
associatedMethodId = shippingMethod_.actions?.find((sm) => {
return (
sm.action === ChangeActionType.SHIPPING_ADD && sm.reference_id
)
})
hasShippingMethod = !!associatedMethodId
} else {
associatedMethodId = shippingMethod_?.detail?.shipping_method_id
}
const sm = {
...(isNewShippingMethod ? shippingMethod_ : shippingMethod_.detail),
version,
shipping_method_id: associatedMethodId,
} as any
delete sm.id
shippingMethodsToUpsert.push(sm)
if (!hasShippingMethod) {
shippingMethodsToUpsert.push(sm)
}
}
orderToUpdate.push({