From 2b2e2fbb3d564bf42c52782f2abef1580522e0fd Mon Sep 17 00:00:00 2001 From: "Carlos R. L. Rodrigues" <37986729+carlos-r-l-rodrigues@users.noreply.github.com> Date: Tue, 9 Jul 2024 11:45:55 -0300 Subject: [PATCH] chore(order): preview order change (#8025) What: - new method `previewOrderChange` - Calculate all the actions related to an order change. - Return the preview of the final Order, with all the calculated values. - Associate actions with items and shipping_methods they modified. FIXES: CORE-2509 --- packages/core/types/src/order/common.ts | 42 +++++++ packages/core/types/src/order/service.ts | 5 + .../create-raw-properties-from-bignumber.ts | 25 +++-- .../__tests__/order-exchange.ts | 2 +- .../__tests__/util/actions/exchanges.ts | 57 ++++++++++ .../src/services/actions/create-claim.ts | 1 + .../src/services/actions/create-exchange.ts | 3 + .../src/services/order-module-service.ts | 105 ++++++++++++++++++ .../modules/order/src/types/utils/index.ts | 5 + .../utils/actions/cancel-item-fulfillment.ts | 11 +- .../order/src/utils/actions/cancel-return.ts | 11 +- .../order/src/utils/actions/fulfill-item.ts | 11 +- .../order/src/utils/actions/item-add.ts | 21 ++-- .../order/src/utils/actions/item-remove.ts | 11 +- .../actions/receive-damaged-return-item.ts | 11 +- .../src/utils/actions/receive-return-item.ts | 11 +- .../order/src/utils/actions/reinstate-item.ts | 11 +- .../order/src/utils/actions/return-item.ts | 11 +- .../order/src/utils/actions/ship-item.ts | 11 +- .../order/src/utils/actions/shipping-add.ts | 14 +-- .../src/utils/actions/shipping-remove.ts | 2 +- .../order/src/utils/actions/write-off-item.ts | 11 +- .../order/src/utils/apply-order-changes.ts | 5 +- .../order/src/utils/calculate-order-change.ts | 18 ++- .../order/src/utils/set-action-reference.ts | 15 ++- 25 files changed, 373 insertions(+), 57 deletions(-) diff --git a/packages/core/types/src/order/common.ts b/packages/core/types/src/order/common.ts index 19fbe57bf1..6337c6547d 100644 --- a/packages/core/types/src/order/common.ts +++ b/packages/core/types/src/order/common.ts @@ -835,6 +835,10 @@ export interface OrderDTO { * The version of the order. */ version: number + /** + * The active order change, if any. + */ + order_change?: OrderChangeDTO /** * The status of the order. */ @@ -1191,16 +1195,54 @@ export interface OrderChangeDTO { * The ID of the order change */ id: string + /** + * The version of the order change + */ + version: string + /** + * The type of the order change + */ + change_type?: "return" | "exchange" | "claim" | "edit" /** * The ID of the associated order */ order_id: string + /** + * The ID of the associated return order + */ + return_id: string + /** + * The ID of the associated exchange order + */ + exchange_id: string + /** + * The ID of the associated claim order + */ + claim_id: string /** * The associated order * * @expandable */ order: OrderDTO + /** + * The associated return order + * + * @expandable + */ + return_order: ReturnDTO + /** + * The associated exchange order + * + * @expandable + */ + exchange: OrderExchangeDTO + /** + * The associated claim order + * + * @expandable + */ + claim: OrderClaimDTO /** * The actions of the order change diff --git a/packages/core/types/src/order/service.ts b/packages/core/types/src/order/service.ts index f2e904ff6e..939c6aa309 100644 --- a/packages/core/types/src/order/service.ts +++ b/packages/core/types/src/order/service.ts @@ -1304,6 +1304,11 @@ export interface IOrderModuleService extends IModuleService { */ cancelOrderChange(orderId: string[], sharedContext?: Context): Promise + previewOrderChange( + orderId: string, + sharedContext?: Context + ): Promise + /** * This method Represents the completion of an asynchronous operation * diff --git a/packages/core/utils/src/totals/create-raw-properties-from-bignumber.ts b/packages/core/utils/src/totals/create-raw-properties-from-bignumber.ts index fc0407f755..1cc49e1449 100644 --- a/packages/core/utils/src/totals/create-raw-properties-from-bignumber.ts +++ b/packages/core/utils/src/totals/create-raw-properties-from-bignumber.ts @@ -1,3 +1,4 @@ +import { BigNumber as BigNumberJS } from "bignumber.js" import { isDefined, trimZeros } from "../common" import { BigNumber } from "./big-number" @@ -11,6 +12,14 @@ export function createRawPropertiesFromBigNumber( exclude?: string[] } = {} ) { + const isBigNumber = (value) => { + return ( + typeof value === "object" && + isDefined(value.raw_) && + isDefined(value.numeric_) + ) + } + const stack = [{ current: obj, path: "" }] while (stack.length > 0) { @@ -19,7 +28,8 @@ export function createRawPropertiesFromBigNumber( if ( current == null || typeof current !== "object" || - current instanceof BigNumber + isBigNumber(current) || + path.includes("." + prefix) ) { continue } @@ -30,16 +40,17 @@ export function createRawPropertiesFromBigNumber( ) } else { for (const key of Object.keys(current)) { - const value = current[key] + let value = current[key] const currentPath = path ? `${path}.${key}` : key if (value != null && !exclude.includes(currentPath)) { - const isBigNumber = - typeof value === "object" && - isDefined(value.raw_) && - isDefined(value.numeric_) + const isBigNumberJS = BigNumberJS.isBigNumber(value) + if (isBigNumberJS) { + current[key] = new BigNumber(current[key]) + value = current[key] + } - if (isBigNumber) { + if (isBigNumber(value)) { const newKey = prefix + key const newPath = path ? `${path}.${newKey}` : newKey if (!exclude.includes(newPath)) { diff --git a/packages/modules/order/integration-tests/__tests__/order-exchange.ts b/packages/modules/order/integration-tests/__tests__/order-exchange.ts index bd7b4086bf..8a3a07b753 100644 --- a/packages/modules/order/integration-tests/__tests__/order-exchange.ts +++ b/packages/modules/order/integration-tests/__tests__/order-exchange.ts @@ -1,6 +1,6 @@ import { CreateOrderDTO, IOrderModuleService } from "@medusajs/types" -import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils" import { Modules } from "@medusajs/utils" +import { SuiteOptions, moduleIntegrationTestRunner } from "medusa-test-utils" jest.setTimeout(100000) diff --git a/packages/modules/order/src/services/__tests__/util/actions/exchanges.ts b/packages/modules/order/src/services/__tests__/util/actions/exchanges.ts index 2d7dc17507..4143e78ed2 100644 --- a/packages/modules/order/src/services/__tests__/util/actions/exchanges.ts +++ b/packages/modules/order/src/services/__tests__/util/actions/exchanges.ts @@ -92,6 +92,9 @@ describe("Order Exchange - Actions", function () { const changes = calculateOrderChange({ order: originalOrder, actions: actions, + options: { + addActionReferenceToObject: true, + }, }) const sumToJSON = JSON.parse(JSON.stringify(changes.summary)) @@ -151,11 +154,65 @@ describe("Order Exchange - Actions", function () { return_dismissed_quantity: 0, written_off_quantity: 0, }, + actions: [ + { + action: "RETURN_ITEM", + reference_id: "return_123", + details: { + reference_id: "3", + quantity: 1, + }, + amount: "20", + }, + ], }, { id: "item_555", unit_price: 50, quantity: 1, + detail: {}, + actions: [ + { + action: "ITEM_ADD", + details: { + reference_id: "item_555", + unit_price: 50, + quantity: 1, + }, + amount: "50", + }, + ], + }, + ]) + + expect(changes.order.shipping_methods).toEqual([ + { + id: "ship_123", + price: 0, + }, + { + id: "shipping_345", + price: 5, + detail: {}, + actions: [ + { + action: "SHIPPING_ADD", + reference_id: "shipping_345", + amount: 5, + }, + ], + }, + { + id: "return_shipping_345", + price: 7.5, + detail: {}, + actions: [ + { + action: "SHIPPING_ADD", + reference_id: "return_shipping_345", + amount: 7.5, + }, + ], }, ]) }) diff --git a/packages/modules/order/src/services/actions/create-claim.ts b/packages/modules/order/src/services/actions/create-claim.ts index fb818bc2c7..dbb146a9d6 100644 --- a/packages/modules/order/src/services/actions/create-claim.ts +++ b/packages/modules/order/src/services/actions/create-claim.ts @@ -174,6 +174,7 @@ async function processAdditionalItems( reference_id: item.id, claim_id: claimReference.id, quantity: addedItem.quantity, + unit_price: item.unit_price, metadata: addedItem.metadata, }, }) diff --git a/packages/modules/order/src/services/actions/create-exchange.ts b/packages/modules/order/src/services/actions/create-exchange.ts index cd169adb40..190fd055ab 100644 --- a/packages/modules/order/src/services/actions/create-exchange.ts +++ b/packages/modules/order/src/services/actions/create-exchange.ts @@ -129,7 +129,9 @@ async function processAdditionalItems( createItems.forEach((item, index) => { const addedItem = itemsToAdd[index] + additionalNewItems[index].item_id = item.id + actions.push({ action: ChangeActionType.ITEM_ADD, exchange_id: exchangeReference.id, @@ -140,6 +142,7 @@ async function processAdditionalItems( reference_id: item.id, exchange_id: exchangeReference.id, quantity: addedItem.quantity, + unit_price: item.unit_price, metadata: addedItem.metadata, }, }) diff --git a/packages/modules/order/src/services/order-module-service.ts b/packages/modules/order/src/services/order-module-service.ts index e6703687d7..f0265ba6b1 100644 --- a/packages/modules/order/src/services/order-module-service.ts +++ b/packages/modules/order/src/services/order-module-service.ts @@ -16,6 +16,7 @@ import { import { BigNumber, createRawPropertiesFromBigNumber, + DecorateCartLikeInputDTO, decorateCartTotals, deduplicate, InjectManager, @@ -307,6 +308,14 @@ export default class OrderModuleService< const order = await super.retrieveOrder(id, config, sharedContext) + const orderChange = await this.getActiveOrderChange_( + order.id, + false, + sharedContext + ) + + order.order_change = orderChange + return formatOrder(order, { entity: Order, includeTotals, @@ -1795,6 +1804,58 @@ export default class OrderModuleService< return await this.orderChangeService_.create(input, sharedContext) } + async previewOrderChange(orderChangeId: string, sharedContext?: Context) { + const orderChange = await super.retrieveOrderChange( + orderChangeId, + { relations: ["actions"] }, + sharedContext + ) + + orderChange.actions = orderChange.actions.map((action) => { + return { + ...action, + version: orderChange.version, + order_id: orderChange.order_id, + return_id: orderChange.return_id, + claim_id: orderChange.claim_id, + exchange_id: orderChange.exchange_id, + } + }) + + const order = await this.retrieveOrder( + orderChange.order_id, + { + select: ["id", "version", "items.detail", "summary", "total"], + relations: [ + "transactions", + "items", + "items.detail", + "shipping_methods", + ], + }, + sharedContext + ) + + const calculated = calculateOrderChange({ + order: order as any, + actions: orderChange.actions, + transactions: order.transactions ?? [], + options: { + addActionReferenceToObject: true, + }, + }) + + createRawPropertiesFromBigNumber(calculated) + + const calcOrder = calculated.order as any + decorateCartTotals(calcOrder as DecorateCartLikeInputDTO) + calcOrder.summary = calculated.summary + + createRawPropertiesFromBigNumber(calcOrder) + + return calcOrder + } + async cancelOrderChange( orderId: string, sharedContext?: Context @@ -2123,6 +2184,50 @@ export default class OrderModuleService< ) } + private async getActiveOrderChange_( + orderId: string, + includeActions: boolean, + sharedContext?: Context + ): Promise { + const options = { + select: [ + "id", + "change_type", + "order_id", + "return_id", + "claim_id", + "exchange_id", + "version", + "requested_at", + "requested_by", + "status", + ], + relations: [] as string[], + order: {}, + } + + if (includeActions) { + options.select.push("actions") + options.relations.push("actions") + options.order = { + actions: { + ordering: "ASC", + }, + } + } + + const [orderChange] = await this.listOrderChanges( + { + order_id: orderId, + status: [OrderChangeStatus.PENDING, OrderChangeStatus.REQUESTED], + }, + options, + sharedContext + ) + + return orderChange + } + private async getAndValidateOrderChange_( orderChangeIds: string[], includeActions: boolean, diff --git a/packages/modules/order/src/types/utils/index.ts b/packages/modules/order/src/types/utils/index.ts index d87be466d0..377815aefc 100644 --- a/packages/modules/order/src/types/utils/index.ts +++ b/packages/modules/order/src/types/utils/index.ts @@ -20,6 +20,7 @@ export type VirtualOrder = { claim_id?: string exchange_id?: string + item_id?: string quantity: BigNumberInput shipped_quantity: BigNumberInput fulfilled_quantity: BigNumberInput @@ -115,6 +116,10 @@ export type OrderReferences = { transactions: OrderTransaction[] type: ActionTypeDefinition actions: InternalOrderChangeEvent[] + options?: { + addActionReferenceToObject?: boolean + [key: string]: unknown + } } export interface ActionTypeDefinition { diff --git a/packages/modules/order/src/utils/actions/cancel-item-fulfillment.ts b/packages/modules/order/src/utils/actions/cancel-item-fulfillment.ts index 2ff091e067..e76b78bad4 100644 --- a/packages/modules/order/src/utils/actions/cancel-item-fulfillment.ts +++ b/packages/modules/order/src/utils/actions/cancel-item-fulfillment.ts @@ -1,12 +1,15 @@ import { MathBN, MedusaError, isDefined } from "@medusajs/utils" import { ChangeActionType } from "../action-key" import { OrderChangeProcessing } from "../calculate-order-change" -import { setActionReference } from "../set-action-reference" +import { + setActionReference, + unsetActionReference, +} from "../set-action-reference" OrderChangeProcessing.registerActionType( ChangeActionType.CANCEL_ITEM_FULFILLMENT, { - operation({ action, currentOrder }) { + operation({ action, currentOrder, options }) { const existing = currentOrder.items.find( (item) => item.id === action.details.reference_id )! @@ -18,7 +21,7 @@ OrderChangeProcessing.registerActionType( action.details.quantity ) - setActionReference(existing, action) + setActionReference(existing, action, options) }, revert({ action, currentOrder }) { const existing = currentOrder.items.find( @@ -29,6 +32,8 @@ OrderChangeProcessing.registerActionType( existing.detail.fulfilled_quantity, action.details.quantity ) + + unsetActionReference(existing, action) }, validate({ action, currentOrder }) { const refId = action.details?.reference_id diff --git a/packages/modules/order/src/utils/actions/cancel-return.ts b/packages/modules/order/src/utils/actions/cancel-return.ts index cf79982656..6bfe317f95 100644 --- a/packages/modules/order/src/utils/actions/cancel-return.ts +++ b/packages/modules/order/src/utils/actions/cancel-return.ts @@ -1,10 +1,13 @@ import { MathBN, MedusaError, isDefined } from "@medusajs/utils" import { ChangeActionType } from "../action-key" import { OrderChangeProcessing } from "../calculate-order-change" -import { setActionReference } from "../set-action-reference" +import { + setActionReference, + unsetActionReference, +} from "../set-action-reference" OrderChangeProcessing.registerActionType(ChangeActionType.CANCEL_RETURN_ITEM, { - operation({ action, currentOrder }) { + operation({ action, currentOrder, options }) { const existing = currentOrder.items.find( (item) => item.id === action.details.reference_id )! @@ -16,7 +19,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.CANCEL_RETURN_ITEM, { action.details.quantity ) - setActionReference(existing, action) + setActionReference(existing, action, options) return action.details.unit_price * action.details.quantity }, @@ -29,6 +32,8 @@ OrderChangeProcessing.registerActionType(ChangeActionType.CANCEL_RETURN_ITEM, { existing.detail.return_requested_quantity, action.details.quantity ) + + unsetActionReference(existing, action) }, validate({ action, currentOrder }) { const refId = action.details?.reference_id diff --git a/packages/modules/order/src/utils/actions/fulfill-item.ts b/packages/modules/order/src/utils/actions/fulfill-item.ts index d0dcbf04f0..24aaa6d74f 100644 --- a/packages/modules/order/src/utils/actions/fulfill-item.ts +++ b/packages/modules/order/src/utils/actions/fulfill-item.ts @@ -1,10 +1,13 @@ import { MathBN, MedusaError, isDefined } from "@medusajs/utils" import { ChangeActionType } from "../action-key" import { OrderChangeProcessing } from "../calculate-order-change" -import { setActionReference } from "../set-action-reference" +import { + setActionReference, + unsetActionReference, +} from "../set-action-reference" OrderChangeProcessing.registerActionType(ChangeActionType.FULFILL_ITEM, { - operation({ action, currentOrder }) { + operation({ action, currentOrder, options }) { const existing = currentOrder.items.find( (item) => item.id === action.details.reference_id )! @@ -16,7 +19,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.FULFILL_ITEM, { action.details.quantity ) - setActionReference(existing, action) + setActionReference(existing, action, options) }, revert({ action, currentOrder }) { const existing = currentOrder.items.find( @@ -27,6 +30,8 @@ OrderChangeProcessing.registerActionType(ChangeActionType.FULFILL_ITEM, { existing.detail.fulfilled_quantity, action.details.quantity ) + + unsetActionReference(existing, action) }, validate({ action, currentOrder }) { const refId = action.details?.reference_id diff --git a/packages/modules/order/src/utils/actions/item-add.ts b/packages/modules/order/src/utils/actions/item-add.ts index 17ee886bba..4fcf2c1adc 100644 --- a/packages/modules/order/src/utils/actions/item-add.ts +++ b/packages/modules/order/src/utils/actions/item-add.ts @@ -2,11 +2,14 @@ import { MathBN, MedusaError, isDefined } from "@medusajs/utils" import { VirtualOrder } from "@types" import { ChangeActionType } from "../action-key" import { OrderChangeProcessing } from "../calculate-order-change" -import { setActionReference } from "../set-action-reference" +import { + setActionReference, + unsetActionReference, +} from "../set-action-reference" OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_ADD, { - operation({ action, currentOrder }) { - const existing = currentOrder.items.find( + operation({ action, currentOrder, options }) { + let existing = currentOrder.items.find( (item) => item.id === action.details.reference_id ) @@ -19,10 +22,8 @@ OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_ADD, { existing.detail.quantity, action.details.quantity ) - - setActionReference(existing, action) } else { - currentOrder.items.push({ + existing = { id: action.details.reference_id!, order_id: currentOrder.id, return_id: action.details.return_id, @@ -31,9 +32,13 @@ OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_ADD, { unit_price: action.details.unit_price, quantity: action.details.quantity, - } as VirtualOrder["items"][0]) + } as VirtualOrder["items"][0] + + currentOrder.items.push(existing) } + setActionReference(existing, action, options) + return MathBN.mult(action.details.unit_price, action.details.quantity) }, revert({ action, currentOrder }) { @@ -52,6 +57,8 @@ OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_ADD, { if (MathBN.lte(existing.quantity, 0)) { currentOrder.items.splice(existingIndex, 1) } + + unsetActionReference(existing, action) } }, validate({ action }) { diff --git a/packages/modules/order/src/utils/actions/item-remove.ts b/packages/modules/order/src/utils/actions/item-remove.ts index ef59731c22..97dd87ef1f 100644 --- a/packages/modules/order/src/utils/actions/item-remove.ts +++ b/packages/modules/order/src/utils/actions/item-remove.ts @@ -2,11 +2,14 @@ import { MathBN, MedusaError, isDefined } from "@medusajs/utils" import { VirtualOrder } from "@types" import { ChangeActionType } from "../action-key" import { OrderChangeProcessing } from "../calculate-order-change" -import { setActionReference } from "../set-action-reference" +import { + setActionReference, + unsetActionReference, +} from "../set-action-reference" OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_REMOVE, { isDeduction: true, - operation({ action, currentOrder }) { + operation({ action, currentOrder, options }) { const existingIndex = currentOrder.items.findIndex( (item) => item.id === action.details.reference_id ) @@ -21,7 +24,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_REMOVE, { action.details.quantity ) - setActionReference(existing, action) + setActionReference(existing, action, options) if (MathBN.lte(existing.quantity, 0)) { currentOrder.items.splice(existingIndex, 1) @@ -40,6 +43,8 @@ OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_REMOVE, { existing.detail.quantity, action.details.quantity ) + + unsetActionReference(existing, action) } else { currentOrder.items.push({ id: action.details.reference_id!, diff --git a/packages/modules/order/src/utils/actions/receive-damaged-return-item.ts b/packages/modules/order/src/utils/actions/receive-damaged-return-item.ts index 383d12232b..a335db8c4c 100644 --- a/packages/modules/order/src/utils/actions/receive-damaged-return-item.ts +++ b/packages/modules/order/src/utils/actions/receive-damaged-return-item.ts @@ -2,14 +2,17 @@ import { MathBN, MedusaError, isDefined } from "@medusajs/utils" import { EVENT_STATUS } from "@types" import { ChangeActionType } from "../action-key" import { OrderChangeProcessing } from "../calculate-order-change" -import { setActionReference } from "../set-action-reference" +import { + setActionReference, + unsetActionReference, +} from "../set-action-reference" OrderChangeProcessing.registerActionType( ChangeActionType.RECEIVE_DAMAGED_RETURN_ITEM, { isDeduction: true, commitsAction: "return_item", - operation({ action, currentOrder, previousEvents }) { + operation({ action, currentOrder, previousEvents, options }) { const existing = currentOrder.items.find( (item) => item.id === action.details.reference_id )! @@ -28,7 +31,7 @@ OrderChangeProcessing.registerActionType( toReturn ) - setActionReference(existing, action) + setActionReference(existing, action, options) if (previousEvents) { for (const previousEvent of previousEvents) { @@ -63,6 +66,8 @@ OrderChangeProcessing.registerActionType( action.details.quantity ) + unsetActionReference(existing, action) + if (previousEvents) { for (const previousEvent of previousEvents) { if (!previousEvent.original_) { diff --git a/packages/modules/order/src/utils/actions/receive-return-item.ts b/packages/modules/order/src/utils/actions/receive-return-item.ts index d4faa96486..fe78d0a8ae 100644 --- a/packages/modules/order/src/utils/actions/receive-return-item.ts +++ b/packages/modules/order/src/utils/actions/receive-return-item.ts @@ -7,12 +7,15 @@ import { import { EVENT_STATUS } from "@types" import { ChangeActionType } from "../action-key" import { OrderChangeProcessing } from "../calculate-order-change" -import { setActionReference } from "../set-action-reference" +import { + setActionReference, + unsetActionReference, +} from "../set-action-reference" OrderChangeProcessing.registerActionType(ChangeActionType.RECEIVE_RETURN_ITEM, { isDeduction: true, commitsAction: "return_item", - operation({ action, currentOrder, previousEvents }) { + operation({ action, currentOrder, previousEvents, options }) { const existing = currentOrder.items.find( (item) => item.id === action.details.reference_id )! @@ -31,7 +34,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.RECEIVE_RETURN_ITEM, { toReturn ) - setActionReference(existing, action) + setActionReference(existing, action, options) if (previousEvents) { for (const previousEvent of previousEvents) { @@ -67,6 +70,8 @@ OrderChangeProcessing.registerActionType(ChangeActionType.RECEIVE_RETURN_ITEM, { action.details.quantity ) + unsetActionReference(existing, action) + if (previousEvents) { for (const previousEvent of previousEvents) { if (!previousEvent.original_) { diff --git a/packages/modules/order/src/utils/actions/reinstate-item.ts b/packages/modules/order/src/utils/actions/reinstate-item.ts index 11fea56a5c..624d81d521 100644 --- a/packages/modules/order/src/utils/actions/reinstate-item.ts +++ b/packages/modules/order/src/utils/actions/reinstate-item.ts @@ -1,10 +1,13 @@ import { MathBN, MedusaError, isDefined } from "@medusajs/utils" import { ChangeActionType } from "../action-key" import { OrderChangeProcessing } from "../calculate-order-change" -import { setActionReference } from "../set-action-reference" +import { + setActionReference, + unsetActionReference, +} from "../set-action-reference" OrderChangeProcessing.registerActionType(ChangeActionType.REINSTATE_ITEM, { - operation({ action, currentOrder }) { + operation({ action, currentOrder, options }) { const existing = currentOrder.items.find( (item) => item.id === action.details.reference_id )! @@ -15,7 +18,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.REINSTATE_ITEM, { action.details.quantity ) - setActionReference(existing, action) + setActionReference(existing, action, options) }, revert({ action, currentOrder }) { const existing = currentOrder.items.find( @@ -26,6 +29,8 @@ OrderChangeProcessing.registerActionType(ChangeActionType.REINSTATE_ITEM, { existing.detail.written_off_quantity, action.details.quantity ) + + unsetActionReference(existing, action) }, validate({ action, currentOrder }) { const refId = action.details?.reference_id diff --git a/packages/modules/order/src/utils/actions/return-item.ts b/packages/modules/order/src/utils/actions/return-item.ts index 9bd24ec3ab..cf67d72309 100644 --- a/packages/modules/order/src/utils/actions/return-item.ts +++ b/packages/modules/order/src/utils/actions/return-item.ts @@ -1,12 +1,15 @@ import { MathBN, MedusaError, isDefined } from "@medusajs/utils" import { ChangeActionType } from "../action-key" import { OrderChangeProcessing } from "../calculate-order-change" -import { setActionReference } from "../set-action-reference" +import { + setActionReference, + unsetActionReference, +} from "../set-action-reference" OrderChangeProcessing.registerActionType(ChangeActionType.RETURN_ITEM, { isDeduction: true, awaitRequired: true, - operation({ action, currentOrder }) { + operation({ action, currentOrder, options }) { const existing = currentOrder.items.find( (item) => item.id === action.details.reference_id )! @@ -17,7 +20,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.RETURN_ITEM, { action.details.quantity ) - setActionReference(existing, action) + setActionReference(existing, action, options) return MathBN.mult(existing.unit_price, action.details.quantity) }, @@ -30,6 +33,8 @@ OrderChangeProcessing.registerActionType(ChangeActionType.RETURN_ITEM, { existing.detail.return_requested_quantity, action.details.quantity ) + + unsetActionReference(existing, action) }, validate({ action, currentOrder }) { const refId = action.details?.reference_id diff --git a/packages/modules/order/src/utils/actions/ship-item.ts b/packages/modules/order/src/utils/actions/ship-item.ts index 8a3769ee0f..f45bc080ae 100644 --- a/packages/modules/order/src/utils/actions/ship-item.ts +++ b/packages/modules/order/src/utils/actions/ship-item.ts @@ -1,10 +1,13 @@ import { MathBN, MedusaError, isDefined } from "@medusajs/utils" import { ChangeActionType } from "../action-key" import { OrderChangeProcessing } from "../calculate-order-change" -import { setActionReference } from "../set-action-reference" +import { + setActionReference, + unsetActionReference, +} from "../set-action-reference" OrderChangeProcessing.registerActionType(ChangeActionType.SHIP_ITEM, { - operation({ action, currentOrder }) { + operation({ action, currentOrder, options }) { const existing = currentOrder.items.find( (item) => item.id === action.details.reference_id )! @@ -16,7 +19,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.SHIP_ITEM, { action.details.quantity ) - setActionReference(existing, action) + setActionReference(existing, action, options) }, revert({ action, currentOrder }) { const existing = currentOrder.items.find( @@ -27,6 +30,8 @@ OrderChangeProcessing.registerActionType(ChangeActionType.SHIP_ITEM, { existing.detail.shipped_quantity, action.details.quantity ) + + unsetActionReference(existing, action) }, validate({ action, currentOrder }) { const refId = action.details?.reference_id diff --git a/packages/modules/order/src/utils/actions/shipping-add.ts b/packages/modules/order/src/utils/actions/shipping-add.ts index 4f9db4207d..64e7446d56 100644 --- a/packages/modules/order/src/utils/actions/shipping-add.ts +++ b/packages/modules/order/src/utils/actions/shipping-add.ts @@ -4,26 +4,26 @@ import { OrderChangeProcessing } from "../calculate-order-change" import { setActionReference } from "../set-action-reference" OrderChangeProcessing.registerActionType(ChangeActionType.SHIPPING_ADD, { - operation({ action, currentOrder }) { + operation({ action, currentOrder, options }) { const shipping = Array.isArray(currentOrder.shipping_methods) ? currentOrder.shipping_methods : [currentOrder.shipping_methods] - const existing = shipping.find((sh) => sh.id === action.reference_id) + let existing = shipping.find((sh) => sh.id === action.reference_id) - if (existing) { - setActionReference(existing, action) - } else { - shipping.push({ + if (!existing) { + existing = { id: action.reference_id!, order_id: currentOrder.id, return_id: action.return_id, claim_id: action.claim_id, exchange_id: action.exchange_id, price: action.amount as number, - }) + } + shipping.push(existing) } + setActionReference(existing, action, options) currentOrder.shipping_methods = shipping }, revert({ action, currentOrder }) { diff --git a/packages/modules/order/src/utils/actions/shipping-remove.ts b/packages/modules/order/src/utils/actions/shipping-remove.ts index a4e2e9fdb6..ba5ad00903 100644 --- a/packages/modules/order/src/utils/actions/shipping-remove.ts +++ b/packages/modules/order/src/utils/actions/shipping-remove.ts @@ -3,7 +3,7 @@ import { ChangeActionType } from "../action-key" import { OrderChangeProcessing } from "../calculate-order-change" OrderChangeProcessing.registerActionType(ChangeActionType.SHIPPING_REMOVE, { - operation({ action, currentOrder }) { + operation({ action, currentOrder, options }) { const shipping = Array.isArray(currentOrder.shipping_methods) ? currentOrder.shipping_methods : [currentOrder.shipping_methods] diff --git a/packages/modules/order/src/utils/actions/write-off-item.ts b/packages/modules/order/src/utils/actions/write-off-item.ts index 5b56b72d7f..521463ed03 100644 --- a/packages/modules/order/src/utils/actions/write-off-item.ts +++ b/packages/modules/order/src/utils/actions/write-off-item.ts @@ -1,10 +1,13 @@ import { MathBN, MedusaError, isDefined } from "@medusajs/utils" import { ChangeActionType } from "../action-key" import { OrderChangeProcessing } from "../calculate-order-change" -import { setActionReference } from "../set-action-reference" +import { + setActionReference, + unsetActionReference, +} from "../set-action-reference" OrderChangeProcessing.registerActionType(ChangeActionType.WRITE_OFF_ITEM, { - operation({ action, currentOrder }) { + operation({ action, currentOrder, options }) { const existing = currentOrder.items.find( (item) => item.id === action.details.reference_id )! @@ -15,7 +18,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.WRITE_OFF_ITEM, { action.details.quantity ) - setActionReference(existing, action) + setActionReference(existing, action, options) }, revert({ action, currentOrder }) { const existing = currentOrder.items.find( @@ -26,6 +29,8 @@ OrderChangeProcessing.registerActionType(ChangeActionType.WRITE_OFF_ITEM, { existing.detail.written_off_quantity, action.details.quantity ) + + unsetActionReference(existing, action) }, validate({ action, currentOrder }) { const refId = action.details?.reference_id diff --git a/packages/modules/order/src/utils/apply-order-changes.ts b/packages/modules/order/src/utils/apply-order-changes.ts index 92a7b0c037..a5b1e9f792 100644 --- a/packages/modules/order/src/utils/apply-order-changes.ts +++ b/packages/modules/order/src/utils/apply-order-changes.ts @@ -31,8 +31,9 @@ export function applyChangesToOrder( const version = actionsMap[order.id][0].version ?? 1 for (const item of calculated.order.items) { - const orderItem = (item.detail as any) ?? item - const itemId = item.detail ? orderItem.item_id : item.id + const isExistingItem = item.id === item.detail?.item_id + const orderItem = isExistingItem ? (item.detail as any) : item + const itemId = isExistingItem ? orderItem.item_id : item.id itemsToUpsert.push({ id: orderItem.version === version ? orderItem.id : undefined, diff --git a/packages/modules/order/src/utils/calculate-order-change.ts b/packages/modules/order/src/utils/calculate-order-change.ts index f2c46d78da..d8609da388 100644 --- a/packages/modules/order/src/utils/calculate-order-change.ts +++ b/packages/modules/order/src/utils/calculate-order-change.ts @@ -19,6 +19,10 @@ import { interface InternalOrderSummary extends OrderSummaryCalculated { future_temporary_sum: BigNumberInput } +interface ProcessOptions { + addActionReferenceToObject?: boolean + [key: string]: any +} export class OrderChangeProcessing { private static typeDefinition: { [key: string]: ActionTypeDefinition } = {} @@ -30,6 +34,7 @@ export class OrderChangeProcessing { private order: VirtualOrder private transactions: OrderTransaction[] private actions: InternalOrderChangeEvent[] + private options: ProcessOptions = {} private actionsProcessed: { [key: string]: InternalOrderChangeEvent[] } = {} private groupTotal: Record = {} @@ -43,14 +48,17 @@ export class OrderChangeProcessing { order, transactions, actions, + options, }: { order: VirtualOrder transactions: OrderTransaction[] actions: InternalOrderChangeEvent[] + options: ProcessOptions }) { this.order = JSON.parse(JSON.stringify(order)) this.transactions = JSON.parse(JSON.stringify(transactions ?? [])) this.actions = JSON.parse(JSON.stringify(actions ?? [])) + this.options = options let paid = MathBN.convert(0) let refunded = MathBN.convert(0) @@ -218,6 +226,7 @@ export class OrderChangeProcessing { summary: this.summary, transactions: this.transactions, type, + options: this.options, } if (typeof type.validate === "function") { type.validate(params) @@ -393,12 +402,19 @@ export function calculateOrderChange({ order, transactions = [], actions = [], + options = {}, }: { order: VirtualOrder transactions?: OrderTransaction[] actions?: OrderChangeEvent[] + options?: ProcessOptions }) { - const calc = new OrderChangeProcessing({ order, transactions, actions }) + const calc = new OrderChangeProcessing({ + order, + transactions, + actions, + options, + }) calc.processActions() return { diff --git a/packages/modules/order/src/utils/set-action-reference.ts b/packages/modules/order/src/utils/set-action-reference.ts index 345d2b065e..be8c8cdeed 100644 --- a/packages/modules/order/src/utils/set-action-reference.ts +++ b/packages/modules/order/src/utils/set-action-reference.ts @@ -1,6 +1,19 @@ -export function setActionReference(existing, action) { +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) + } +} + +export function unsetActionReference(existing, action) { + if (Array.isArray(existing?.actions)) { + existing.actions = existing.actions.filter((a) => a.id !== action.id) + } }