fix(order): undo order change (#9497)

FIXES: CC-573

Co-authored-by: Frane Polić <16856471+fPolic@users.noreply.github.com>
This commit is contained in:
Carlos R. L. RodriguesandFrane Polić authored and GitHub committed 2024-10-09 11:50:50 +00:00
1 parent d71343d6ab
commit 4daf57dc1f
8 files changed
+225 -22

No files matched your search

@@ -15,21 +15,36 @@ export const confirmOrderChanges = createStep(
"confirm-order-changes", "confirm-order-changes",
async (input: ConfirmOrderChangesInput, { container }) => { async (input: ConfirmOrderChangesInput, { container }) => {
const orderModuleService = container.resolve(Modules.ORDER) const orderModuleService = container.resolve(Modules.ORDER)
const currentChanges: Partial<OrderChangeDTO>[] = []
await orderModuleService.confirmOrderChange( await orderModuleService.confirmOrderChange(
input.changes.map((action) => ({ input.changes.map((action) => {
const update = {
id: action.id, id: action.id,
confirmed_by: input.confirmed_by, confirmed_by: input.confirmed_by,
})) }
currentChanges.push({
...update,
order_id: input.orderId,
status: action.status,
})
return update
})
) )
return new StepResponse(null, input.orderId) return new StepResponse(null, currentChanges)
}, },
async (orderId, { container }) => { async (currentChanges, { container }) => {
if (!orderId) { if (!currentChanges?.length) {
return return
} }
const orderModuleService = container.resolve(Modules.ORDER) const orderModuleService = container.resolve(Modules.ORDER)
await orderModuleService.revertLastVersion(orderId) await orderModuleService.undoLastChange(
currentChanges[0].order_id!,
currentChanges[0]
)
} }
) )
@@ -246,6 +246,7 @@ export const confirmClaimRequestWorkflow = createWorkflow(
entry_point: "order_change", entry_point: "order_change",
fields: [ fields: [
"id", "id",
"status",
"actions.id", "actions.id",
"actions.claim_id", "actions.claim_id",
"actions.return_id", "actions.return_id",
@@ -291,7 +292,11 @@ export const confirmClaimRequestWorkflow = createWorkflow(
} }
) )
confirmOrderChanges({ changes: [orderChange], orderId: order.id }) confirmOrderChanges({
changes: [orderChange],
orderId: order.id,
confirmed_by: input.confirmed_by,
})
when({ returnId }, ({ returnId }) => { when({ returnId }, ({ returnId }) => {
return !!returnId return !!returnId
@@ -234,6 +234,7 @@ export const confirmExchangeRequestWorkflow = createWorkflow(
entry_point: "order_change", entry_point: "order_change",
fields: [ fields: [
"id", "id",
"status",
"actions.id", "actions.id",
"actions.exchange_id", "actions.exchange_id",
"actions.return_id", "actions.return_id",
@@ -272,7 +273,11 @@ export const confirmExchangeRequestWorkflow = createWorkflow(
returnItems: createdReturnItems, returnItems: createdReturnItems,
}) })
confirmOrderChanges({ changes: [orderChange], orderId: order.id }) confirmOrderChanges({
changes: [orderChange],
orderId: order.id,
confirmed_by: input.confirmed_by,
})
const returnId = transform( const returnId = transform(
{ createdReturnItems }, { createdReturnItems },
@@ -18,6 +18,7 @@ import {
import { reserveInventoryStep } from "../../../cart/steps/reserve-inventory" import { reserveInventoryStep } from "../../../cart/steps/reserve-inventory"
import { prepareConfirmInventoryInput } from "../../../cart/utils/prepare-confirm-inventory-input" import { prepareConfirmInventoryInput } from "../../../cart/utils/prepare-confirm-inventory-input"
import { useRemoteQueryStep } from "../../../common" import { useRemoteQueryStep } from "../../../common"
import { deleteReservationsByLineItemsStep } from "../../../reservation"
import { previewOrderChangeStep } from "../../steps" import { previewOrderChangeStep } from "../../steps"
import { confirmOrderChanges } from "../../steps/confirm-order-changes" import { confirmOrderChanges } from "../../steps/confirm-order-changes"
import { import {
@@ -25,7 +26,6 @@ import {
throwIfOrderChangeIsNotActive, throwIfOrderChangeIsNotActive,
} from "../../utils/order-validation" } from "../../utils/order-validation"
import { createOrUpdateOrderPaymentCollectionWorkflow } from "../create-or-update-order-payment-collection" import { createOrUpdateOrderPaymentCollectionWorkflow } from "../create-or-update-order-payment-collection"
import { deleteReservationsByLineItemsStep } from "../../../reservation"
export type ConfirmOrderEditRequestWorkflowInput = { export type ConfirmOrderEditRequestWorkflowInput = {
order_id: string order_id: string
@@ -80,6 +80,7 @@ export const confirmOrderEditRequestWorkflow = createWorkflow(
entry_point: "order_change", entry_point: "order_change",
fields: [ fields: [
"id", "id",
"status",
"actions.id", "actions.id",
"actions.order_id", "actions.order_id",
"actions.return_id", "actions.return_id",
@@ -162,7 +163,6 @@ export const confirmOrderEditRequestWorkflow = createWorkflow(
const unitPrice: BigNumberInput = const unitPrice: BigNumberInput =
itemAction.raw_unit_price ?? itemAction.unit_price itemAction.raw_unit_price ?? itemAction.unit_price
const updateAction = itemAction.actions!.find( const updateAction = itemAction.actions!.find(
(a) => a.action === ChangeActionType.ITEM_UPDATE (a) => a.action === ChangeActionType.ITEM_UPDATE
) )
@@ -187,7 +187,7 @@ export const confirmOrderEditRequestWorkflow = createWorkflow(
id: ordItem.id, id: ordItem.id,
variant_id: ordItem.variant_id, variant_id: ordItem.variant_id,
quantity: reservationQuantity, quantity: reservationQuantity,
unit_price: unitPrice unit_price: unitPrice,
}) })
allVariants.push(ordItem.variant) allVariants.push(ordItem.variant)
}) })
@@ -171,6 +171,7 @@ export const confirmReturnReceiveWorkflow = createWorkflow(
entry_point: "order_change", entry_point: "order_change",
fields: [ fields: [
"id", "id",
"status",
"actions.id", "actions.id",
"actions.action", "actions.action",
"actions.details", "actions.details",
@@ -191,6 +191,7 @@ export const confirmReturnRequestWorkflow = createWorkflow(
entry_point: "order_change", entry_point: "order_change",
fields: [ fields: [
"id", "id",
"status",
"actions.id", "actions.id",
"actions.action", "actions.action",
"actions.details", "actions.details",
+18 -1
View File
@@ -3380,7 +3380,7 @@ export interface IOrderModuleService extends IModuleService {
): Promise<Record<TReturnableLinkableKeys, string[]> | void> ): Promise<Record<TReturnableLinkableKeys, string[]> | void>
/** /**
* This method reverts an order to its last version. * This method reverts an order to its last version and cleanup data related to the changes.
* *
* @param {string} orderId - The order's ID. * @param {string} orderId - The order's ID.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module. * @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
@@ -3391,6 +3391,23 @@ export interface IOrderModuleService extends IModuleService {
*/ */
revertLastVersion(orderId: string, sharedContext?: Context): Promise<void> revertLastVersion(orderId: string, sharedContext?: Context): Promise<void>
/**
* This method reverts an order to its last change and keep the order changes and actions not applied.
*
* @param {string} orderId - The order's ID.
* @param {Partial<OrderChangeDTO>} lastOrderChange - The last order change status to revert to.
* @param {Context} sharedContext - A context used to share resources, such as transaction manager, between the application and the module.
* @returns {Promise<void>} Resolves when the order is undone.
*
* @example
* await orderModuleService.revertLastChange("123")
*/
undoLastChange(
orderId: string,
lastOrderChange?: Partial<OrderChangeDTO>,
sharedContext?: Context
): Promise<void>
/** /**
* This method retrieves a paginated list of transactions based on optional filters and configuration. * This method retrieves a paginated list of transactions based on optional filters and configuration.
* *
@@ -8,6 +8,7 @@ import {
IOrderModuleService, IOrderModuleService,
ModuleJoinerConfig, ModuleJoinerConfig,
ModulesSdkTypes, ModulesSdkTypes,
OrderChangeDTO,
OrderDTO, OrderDTO,
OrderReturnReasonDTO, OrderReturnReasonDTO,
OrderShippingMethodDTO, OrderShippingMethodDTO,
@@ -2302,13 +2303,39 @@ export default class OrderModuleService<
return await this.revertLastChange_(order, sharedContext) return await this.revertLastChange_(order, sharedContext)
} }
@InjectManager()
async undoLastChange(
orderId: string,
lastOrderChange?: Partial<OrderChangeDTO>,
@MedusaContext() sharedContext?: Context
) {
const order = await super.retrieveOrder(
orderId,
{
select: ["id", "version"],
},
sharedContext
)
if (order.version < 2) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`Order with id ${orderId} has no previous versions`
)
}
return await this.undoLastChange_(order, lastOrderChange, sharedContext)
}
@InjectTransactionManager() @InjectTransactionManager()
protected async revertLastChange_( protected async undoLastChange_(
order: OrderDTO, order: OrderDTO,
lastOrderChange?: Partial<OrderChangeDTO>,
sharedContext?: Context sharedContext?: Context
): Promise<void> { ): Promise<void> {
const currentVersion = order.version const currentVersion = order.version
const updatePromises: Promise<any>[] = []
// Order Changes // Order Changes
const orderChanges = await this.orderChangeService_.list( const orderChanges = await this.orderChangeService_.list(
{ {
@@ -2318,9 +2345,18 @@ export default class OrderModuleService<
{ select: ["id", "version"] }, { select: ["id", "version"] },
sharedContext sharedContext
) )
const orderChangesIds = orderChanges.map((change) => change.id)
await this.orderChangeService_.softDelete(orderChangesIds, sharedContext) const orderChangesIds = orderChanges.map((change) => {
return {
id: change.id,
status: lastOrderChange?.status ?? OrderChangeStatus.PENDING,
confirmed_at: null,
}
})
updatePromises.push(
this.orderChangeService_.update(orderChangesIds, sharedContext)
)
// Order Changes Actions // Order Changes Actions
const orderChangesActions = await this.orderChangeActionService_.list( const orderChangesActions = await this.orderChangeActionService_.list(
@@ -2331,12 +2367,19 @@ export default class OrderModuleService<
{ select: ["id", "version"] }, { select: ["id", "version"] },
sharedContext sharedContext
) )
const orderChangeActionsIds = orderChangesActions.map((action) => action.id) const orderChangeActionsIds = orderChangesActions.map((action) => {
return {
id: action.id,
applied: false,
}
})
await this.orderChangeActionService_.softDelete( updatePromises.push(
this.orderChangeActionService_.update(
orderChangeActionsIds, orderChangeActionsIds,
sharedContext sharedContext
) )
)
// Order Summary // Order Summary
const orderSummary = await this.orderSummaryService_.list( const orderSummary = await this.orderSummaryService_.list(
@@ -2349,7 +2392,9 @@ export default class OrderModuleService<
) )
const orderSummaryIds = orderSummary.map((summary) => summary.id) const orderSummaryIds = orderSummary.map((summary) => summary.id)
await this.orderSummaryService_.softDelete(orderSummaryIds, sharedContext) updatePromises.push(
this.orderSummaryService_.softDelete(orderSummaryIds, sharedContext)
)
// Order Items // Order Items
const orderItems = await this.orderItemService_.list( const orderItems = await this.orderItemService_.list(
@@ -2362,7 +2407,9 @@ export default class OrderModuleService<
) )
const orderItemIds = orderItems.map((summary) => summary.id) const orderItemIds = orderItems.map((summary) => summary.id)
await this.orderItemService_.softDelete(orderItemIds, sharedContext) updatePromises.push(
this.orderItemService_.softDelete(orderItemIds, sharedContext)
)
// Order Shipping // Order Shipping
const orderShippings = await this.orderShippingService_.list( const orderShippings = await this.orderShippingService_.list(
@@ -2375,10 +2422,13 @@ export default class OrderModuleService<
) )
const orderShippingIds = orderShippings.map((sh) => sh.id) const orderShippingIds = orderShippings.map((sh) => sh.id)
await this.orderShippingService_.softDelete(orderShippingIds, sharedContext) updatePromises.push(
this.orderShippingService_.softDelete(orderShippingIds, sharedContext)
)
// Order // Order
await this.orderService_.update( updatePromises.push(
this.orderService_.update(
{ {
selector: { selector: {
id: order.id, id: order.id,
@@ -2389,15 +2439,124 @@ export default class OrderModuleService<
}, },
sharedContext sharedContext
) )
)
await promiseAll(updatePromises)
}
@InjectTransactionManager()
protected async revertLastChange_(
order: OrderDTO,
sharedContext?: Context
): Promise<void> {
const currentVersion = order.version
const updatePromises: Promise<any>[] = []
// Order Changes
const orderChanges = await this.orderChangeService_.list(
{
order_id: order.id,
version: currentVersion,
},
{ select: ["id", "version"] },
sharedContext
)
const orderChangesIds = orderChanges.map((change) => change.id)
updatePromises.push(
this.orderChangeService_.softDelete(orderChangesIds, sharedContext)
)
// Order Changes Actions
const orderChangesActions = await this.orderChangeActionService_.list(
{
order_id: order.id,
version: currentVersion,
},
{ select: ["id", "version"] },
sharedContext
)
const orderChangeActionsIds = orderChangesActions.map((action) => action.id)
updatePromises.push(
this.orderChangeActionService_.softDelete(
orderChangeActionsIds,
sharedContext
)
)
// Order Summary
const orderSummary = await this.orderSummaryService_.list(
{
order_id: order.id,
version: currentVersion,
},
{ select: ["id", "version"] },
sharedContext
)
const orderSummaryIds = orderSummary.map((summary) => summary.id)
updatePromises.push(
this.orderSummaryService_.softDelete(orderSummaryIds, sharedContext)
)
// Order Items
const orderItems = await this.orderItemService_.list(
{
order_id: order.id,
version: currentVersion,
},
{ select: ["id", "version"] },
sharedContext
)
const orderItemIds = orderItems.map((summary) => summary.id)
updatePromises.push(
this.orderItemService_.softDelete(orderItemIds, sharedContext)
)
// Order Shipping
const orderShippings = await this.orderShippingService_.list(
{
order_id: order.id,
version: currentVersion,
},
{ select: ["id", "version"] },
sharedContext
)
const orderShippingIds = orderShippings.map((sh) => sh.id)
updatePromises.push(
this.orderShippingService_.softDelete(orderShippingIds, sharedContext)
)
// Order
updatePromises.push(
this.orderService_.update(
{
selector: {
id: order.id,
},
data: {
version: order.version - 1,
},
},
sharedContext
)
)
// Returns // Returns
await this.returnService_.delete( updatePromises.push(
this.returnService_.delete(
{ {
order_id: order.id, order_id: order.id,
order_version: currentVersion, order_version: currentVersion,
}, },
sharedContext sharedContext
) )
)
await promiseAll(updatePromises)
} }
private async getActiveOrderChange_( private async getActiveOrderChange_(