chore(order): simplify order engine (#8188)

what:
- remove unused features of order changes calculation engine
This commit is contained in:
Carlos R. L. Rodrigues
2024-07-18 15:02:13 -03:00
committed by GitHub
parent e0c0a86264
commit 78b8a3c60f
24 changed files with 26 additions and 548 deletions

View File

@@ -5,10 +5,7 @@ import {
isDefined,
} from "@medusajs/utils"
import { OrderChangeProcessing } from "../calculate-order-change"
import {
setActionReference,
unsetActionReference,
} from "../set-action-reference"
import { setActionReference } from "../set-action-reference"
OrderChangeProcessing.registerActionType(
ChangeActionType.CANCEL_ITEM_FULFILLMENT,
@@ -27,18 +24,6 @@ OrderChangeProcessing.registerActionType(
setActionReference(existing, action, options)
},
revert({ action, currentOrder }) {
const existing = currentOrder.items.find(
(item) => item.id === action.reference_id
)!
existing.detail.fulfilled_quantity = MathBN.add(
existing.detail.fulfilled_quantity,
action.details.quantity
)
unsetActionReference(existing, action)
},
validate({ action, currentOrder }) {
const refId = action.details?.reference_id
if (!isDefined(refId)) {

View File

@@ -5,10 +5,7 @@ import {
isDefined,
} from "@medusajs/utils"
import { OrderChangeProcessing } from "../calculate-order-change"
import {
setActionReference,
unsetActionReference,
} from "../set-action-reference"
import { setActionReference } from "../set-action-reference"
OrderChangeProcessing.registerActionType(ChangeActionType.CANCEL_RETURN_ITEM, {
operation({ action, currentOrder, options }) {
@@ -27,18 +24,6 @@ OrderChangeProcessing.registerActionType(ChangeActionType.CANCEL_RETURN_ITEM, {
return action.details.unit_price * action.details.quantity
},
revert({ action, currentOrder }) {
const existing = currentOrder.items.find(
(item) => item.id === action.details.reference_id
)!
existing.detail.return_requested_quantity = MathBN.add(
existing.detail.return_requested_quantity,
action.details.quantity
)
unsetActionReference(existing, action)
},
validate({ action, currentOrder }) {
const refId = action.details?.reference_id
if (!isDefined(refId)) {

View File

@@ -1,6 +0,0 @@
import { ChangeActionType } from "@medusajs/utils"
import { OrderChangeProcessing } from "../calculate-order-change"
OrderChangeProcessing.registerActionType(ChangeActionType.CANCEL, {
void: true,
})

View File

@@ -5,10 +5,7 @@ import {
isDefined,
} from "@medusajs/utils"
import { OrderChangeProcessing } from "../calculate-order-change"
import {
setActionReference,
unsetActionReference,
} from "../set-action-reference"
import { setActionReference } from "../set-action-reference"
OrderChangeProcessing.registerActionType(ChangeActionType.FULFILL_ITEM, {
operation({ action, currentOrder, options }) {
@@ -25,18 +22,6 @@ OrderChangeProcessing.registerActionType(ChangeActionType.FULFILL_ITEM, {
setActionReference(existing, action, options)
},
revert({ action, currentOrder }) {
const existing = currentOrder.items.find(
(item) => item.id === action.reference_id
)!
existing.detail.fulfilled_quantity = MathBN.sub(
existing.detail.fulfilled_quantity,
action.details.quantity
)
unsetActionReference(existing, action)
},
validate({ action, currentOrder }) {
const refId = action.details?.reference_id
if (!isDefined(refId)) {

View File

@@ -1,4 +1,3 @@
export * from "./cancel"
export * from "./cancel-item-fulfillment"
export * from "./cancel-return"
export * from "./fulfill-item"

View File

@@ -6,10 +6,7 @@ import {
} from "@medusajs/utils"
import { VirtualOrder } from "@types"
import { OrderChangeProcessing } from "../calculate-order-change"
import {
setActionReference,
unsetActionReference,
} from "../set-action-reference"
import { setActionReference } from "../set-action-reference"
OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_ADD, {
operation({ action, currentOrder, options }) {
@@ -45,26 +42,6 @@ OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_ADD, {
return MathBN.mult(action.details.unit_price, action.details.quantity)
},
revert({ action, currentOrder }) {
const existingIndex = currentOrder.items.findIndex(
(item) => item.id === action.details.reference_id
)
if (existingIndex > -1) {
const existing = currentOrder.items[existingIndex]
existing.quantity = MathBN.sub(existing.quantity, action.details.quantity)
existing.detail.quantity = MathBN.sub(
existing.detail.quantity,
action.details.quantity
)
if (MathBN.lte(existing.quantity, 0)) {
currentOrder.items.splice(existingIndex, 1)
}
unsetActionReference(existing, action)
}
},
validate({ action }) {
const refId = action.details?.reference_id

View File

@@ -4,12 +4,8 @@ import {
MedusaError,
isDefined,
} from "@medusajs/utils"
import { VirtualOrder } from "@types"
import { OrderChangeProcessing } from "../calculate-order-change"
import {
setActionReference,
unsetActionReference,
} from "../set-action-reference"
import { setActionReference } from "../set-action-reference"
OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_REMOVE, {
isDeduction: true,
@@ -36,27 +32,6 @@ OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_REMOVE, {
return MathBN.mult(existing.unit_price, action.details.quantity)
},
revert({ action, currentOrder }) {
const existing = currentOrder.items.find(
(item) => item.id === action.details.reference_id
)
if (existing) {
existing.quantity = MathBN.add(existing.quantity, action.details.quantity)
existing.detail.quantity = MathBN.add(
existing.detail.quantity,
action.details.quantity
)
unsetActionReference(existing, action)
} else {
currentOrder.items.push({
id: action.details.reference_id!,
unit_price: action.details.unit_price,
quantity: action.details.quantity,
} as VirtualOrder["items"][0])
}
},
validate({ action, currentOrder }) {
const refId = action.details?.reference_id
if (!isDefined(refId)) {

View File

@@ -4,18 +4,13 @@ import {
MedusaError,
isDefined,
} from "@medusajs/utils"
import { EVENT_STATUS } from "@types"
import { OrderChangeProcessing } from "../calculate-order-change"
import {
setActionReference,
unsetActionReference,
} from "../set-action-reference"
import { setActionReference } from "../set-action-reference"
OrderChangeProcessing.registerActionType(
ChangeActionType.RECEIVE_DAMAGED_RETURN_ITEM,
{
isDeduction: true,
commitsAction: "return_item",
operation({ action, currentOrder, previousEvents, options }) {
const existing = currentOrder.items.find(
(item) => item.id === action.details.reference_id
@@ -43,61 +38,8 @@ OrderChangeProcessing.registerActionType(
setActionReference(existing, action, options)
if (previousEvents) {
for (const previousEvent of previousEvents) {
previousEvent.original_ = JSON.parse(JSON.stringify(previousEvent))
let ret = MathBN.min(toReturn, previousEvent.details.quantity)
toReturn = MathBN.sub(toReturn, ret)
previousEvent.details.quantity = MathBN.sub(
previousEvent.details.quantity,
ret
)
if (MathBN.lte(previousEvent.details.quantity, 0)) {
previousEvent.status = EVENT_STATUS.DONE
}
}
}
return MathBN.mult(existing.unit_price, action.details.quantity)
},
revert({ action, currentOrder, previousEvents }) {
const existing = currentOrder.items.find(
(item) => item.id === action.details.reference_id
)!
existing.detail.return_dismissed_quantity = MathBN.sub(
existing.detail.return_dismissed_quantity,
action.details.quantity
)
existing.detail.return_requested_quantity = MathBN.add(
existing.detail.return_requested_quantity,
action.details.quantity
)
existing.detail.written_off_quantity = MathBN.sub(
existing.detail.written_off_quantity,
action.details.quantity
)
unsetActionReference(existing, action)
if (previousEvents) {
for (const previousEvent of previousEvents) {
if (!previousEvent.original_) {
continue
}
previousEvent.details = JSON.parse(
JSON.stringify(previousEvent.original_.details)
)
delete previousEvent.original_
previousEvent.status = EVENT_STATUS.PENDING
}
}
},
validate({ action, currentOrder }) {
const refId = action.details?.reference_id
if (!isDefined(refId)) {

View File

@@ -3,18 +3,12 @@ import {
MathBN,
MedusaError,
isDefined,
transformPropertiesToBigNumber,
} from "@medusajs/utils"
import { EVENT_STATUS } from "@types"
import { OrderChangeProcessing } from "../calculate-order-change"
import {
setActionReference,
unsetActionReference,
} from "../set-action-reference"
import { setActionReference } from "../set-action-reference"
OrderChangeProcessing.registerActionType(ChangeActionType.RECEIVE_RETURN_ITEM, {
isDeduction: true,
commitsAction: "return_item",
operation({ action, currentOrder, previousEvents, options }) {
const existing = currentOrder.items.find(
(item) => item.id === action.details.reference_id
@@ -36,59 +30,8 @@ OrderChangeProcessing.registerActionType(ChangeActionType.RECEIVE_RETURN_ITEM, {
setActionReference(existing, action, options)
if (previousEvents) {
for (const previousEvent of previousEvents) {
previousEvent.original_ = JSON.parse(JSON.stringify(previousEvent))
let ret = MathBN.min(toReturn, previousEvent.details.quantity)
toReturn = MathBN.sub(toReturn, ret)
previousEvent.details.quantity = MathBN.sub(
previousEvent.details.quantity,
ret
)
if (MathBN.lte(previousEvent.details.quantity, 0)) {
previousEvent.status = EVENT_STATUS.DONE
}
}
}
return MathBN.mult(existing.unit_price, action.details.quantity)
},
revert({ action, currentOrder, previousEvents }) {
const existing = currentOrder.items.find(
(item) => item.id === action.details.reference_id
)!
existing.detail.return_received_quantity = MathBN.sub(
existing.detail.return_received_quantity,
action.details.quantity
)
existing.detail.return_requested_quantity = MathBN.add(
existing.detail.return_requested_quantity,
action.details.quantity
)
unsetActionReference(existing, action)
if (previousEvents) {
for (const previousEvent of previousEvents) {
if (!previousEvent.original_) {
continue
}
previousEvent.details = JSON.parse(
JSON.stringify(previousEvent.original_.details)
)
transformPropertiesToBigNumber(previousEvent.details?.metadata)
delete previousEvent.original_
previousEvent.status = EVENT_STATUS.PENDING
}
}
},
validate({ action, currentOrder }) {
const refId = action.details?.reference_id
if (!isDefined(refId)) {

View File

@@ -5,10 +5,7 @@ import {
isDefined,
} from "@medusajs/utils"
import { OrderChangeProcessing } from "../calculate-order-change"
import {
setActionReference,
unsetActionReference,
} from "../set-action-reference"
import { setActionReference } from "../set-action-reference"
OrderChangeProcessing.registerActionType(ChangeActionType.REINSTATE_ITEM, {
operation({ action, currentOrder, options }) {
@@ -24,18 +21,6 @@ OrderChangeProcessing.registerActionType(ChangeActionType.REINSTATE_ITEM, {
setActionReference(existing, action, options)
},
revert({ action, currentOrder }) {
const existing = currentOrder.items.find(
(item) => item.id === action.details.reference_id
)!
existing.detail.written_off_quantity = MathBN.add(
existing.detail.written_off_quantity,
action.details.quantity
)
unsetActionReference(existing, action)
},
validate({ action, currentOrder }) {
const refId = action.details?.reference_id
if (!isDefined(refId)) {

View File

@@ -5,10 +5,7 @@ import {
isDefined,
} from "@medusajs/utils"
import { OrderChangeProcessing } from "../calculate-order-change"
import {
setActionReference,
unsetActionReference,
} from "../set-action-reference"
import { setActionReference } from "../set-action-reference"
OrderChangeProcessing.registerActionType(ChangeActionType.RETURN_ITEM, {
isDeduction: true,
@@ -28,18 +25,6 @@ OrderChangeProcessing.registerActionType(ChangeActionType.RETURN_ITEM, {
return MathBN.mult(existing.unit_price, action.details.quantity)
},
revert({ action, currentOrder }) {
const existing = currentOrder.items.find(
(item) => item.id === action.details.reference_id
)!
existing.detail.return_requested_quantity = MathBN.sub(
existing.detail.return_requested_quantity,
action.details.quantity
)
unsetActionReference(existing, action)
},
validate({ action, currentOrder }) {
const refId = action.details?.reference_id
if (!isDefined(refId)) {

View File

@@ -5,10 +5,7 @@ import {
isDefined,
} from "@medusajs/utils"
import { OrderChangeProcessing } from "../calculate-order-change"
import {
setActionReference,
unsetActionReference,
} from "../set-action-reference"
import { setActionReference } from "../set-action-reference"
OrderChangeProcessing.registerActionType(ChangeActionType.SHIP_ITEM, {
operation({ action, currentOrder, options }) {
@@ -25,18 +22,6 @@ OrderChangeProcessing.registerActionType(ChangeActionType.SHIP_ITEM, {
setActionReference(existing, action, options)
},
revert({ action, currentOrder }) {
const existing = currentOrder.items.find(
(item) => item.id === action.reference_id
)!
existing.detail.shipped_quantity = MathBN.sub(
existing.detail.shipped_quantity,
action.details.quantity
)
unsetActionReference(existing, action)
},
validate({ action, currentOrder }) {
const refId = action.details?.reference_id
if (!isDefined(refId)) {

View File

@@ -25,19 +25,6 @@ OrderChangeProcessing.registerActionType(ChangeActionType.SHIPPING_ADD, {
setActionReference(existing, action, options)
currentOrder.shipping_methods = shipping
},
revert({ action, currentOrder }) {
const shipping = Array.isArray(currentOrder.shipping_methods)
? currentOrder.shipping_methods
: [currentOrder.shipping_methods]
const existingIndex = shipping.findIndex(
(item) => item.id === action.reference_id
)
if (existingIndex > -1) {
shipping.splice(existingIndex, 1)
}
},
validate({ action }) {
if (!action.reference_id) {
throw new MedusaError(

View File

@@ -17,26 +17,6 @@ OrderChangeProcessing.registerActionType(ChangeActionType.SHIPPING_REMOVE, {
currentOrder.shipping_methods = shipping
},
revert({ action, currentOrder }) {
const shipping = Array.isArray(currentOrder.shipping_methods)
? currentOrder.shipping_methods
: [currentOrder.shipping_methods]
const existingIndex = shipping.findIndex(
(item) => item.id === action.reference_id
)
if (existingIndex > -1) {
shipping.push({
id: action.reference_id!,
order_id: currentOrder.id,
return_id: action.return_id,
claim_id: action.claim_id,
exchange_id: action.exchange_id,
amount: action.amount as number,
})
}
},
validate({ action }) {
if (!action.reference_id) {
throw new MedusaError(

View File

@@ -5,10 +5,7 @@ import {
isDefined,
} from "@medusajs/utils"
import { OrderChangeProcessing } from "../calculate-order-change"
import {
setActionReference,
unsetActionReference,
} from "../set-action-reference"
import { setActionReference } from "../set-action-reference"
OrderChangeProcessing.registerActionType(ChangeActionType.WRITE_OFF_ITEM, {
operation({ action, currentOrder, options }) {
@@ -24,18 +21,6 @@ OrderChangeProcessing.registerActionType(ChangeActionType.WRITE_OFF_ITEM, {
setActionReference(existing, action, options)
},
revert({ action, currentOrder }) {
const existing = currentOrder.items.find(
(item) => item.id === action.details.reference_id
)!
existing.detail.written_off_quantity = MathBN.sub(
existing.detail.written_off_quantity,
action.details.quantity
)
unsetActionReference(existing, action)
},
validate({ action, currentOrder }) {
const refId = action.details?.reference_id
if (!isDefined(refId)) {

View File

@@ -57,7 +57,7 @@ export function applyChangesToOrder(
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,
written_off_quantity: orderItem.written_off_quantity ?? 0,
metadata: orderItem.metadata,
} as OrderItem)
}

View File

@@ -16,9 +16,6 @@ import {
VirtualOrder,
} from "@types"
interface InternalOrderSummary extends OrderSummaryCalculated {
future_temporary_sum: BigNumberInput
}
interface ProcessOptions {
addActionReferenceToObject?: boolean
[key: string]: any
@@ -27,7 +24,6 @@ interface ProcessOptions {
export class OrderChangeProcessing {
private static typeDefinition: { [key: string]: ActionTypeDefinition } = {}
private static defaultConfig = {
awaitRequired: false,
isDeduction: false,
}
@@ -38,7 +34,7 @@ export class OrderChangeProcessing {
private actionsProcessed: { [key: string]: InternalOrderChangeEvent[] } = {}
private groupTotal: Record<string, BigNumberInput> = {}
private summary: InternalOrderSummary
private summary: OrderSummaryCalculated
public static registerActionType(key: string, type: ActionTypeDefinition) {
OrderChangeProcessing.typeDefinition[key] = type
@@ -76,11 +72,8 @@ export class OrderChangeProcessing {
transformPropertiesToBigNumber(this.order.metadata)
this.summary = {
future_difference: 0,
future_temporary_difference: 0,
temporary_difference: 0,
pending_difference: 0,
future_temporary_sum: 0,
difference_sum: 0,
current_order_total: this.order.total ?? 0,
original_order_total: this.order.total ?? 0,
@@ -103,11 +96,6 @@ export class OrderChangeProcessing {
return status === EVENT_STATUS.DONE
}
private isEventPending(action: InternalOrderChangeEvent): boolean {
const status = action.status
return status === undefined || status === EVENT_STATUS.PENDING
}
public processActions() {
for (const action of this.actions) {
this.processAction_(action)
@@ -126,7 +114,7 @@ export class OrderChangeProcessing {
const amount = MathBN.mult(action.amount!, type.isDeduction ? -1 : 1)
if (action.change_id && !action.evaluationOnly) {
if (action.change_id) {
this.groupTotal[action.change_id] ??= 0
this.groupTotal[action.change_id] = MathBN.add(
this.groupTotal[action.change_id],
@@ -134,34 +122,20 @@ export class OrderChangeProcessing {
)
}
if (type.awaitRequired && !this.isEventDone(action)) {
if (action.evaluationOnly) {
summary.future_temporary_sum = MathBN.add(
summary.future_temporary_sum,
amount
)
} else {
summary.temporary_difference = MathBN.add(
summary.temporary_difference,
amount
)
}
if (type.awaitRequired) {
summary.temporary_difference = MathBN.add(
summary.temporary_difference,
amount
)
}
if (action.evaluationOnly) {
summary.future_difference = MathBN.add(
summary.future_difference,
amount
)
} else {
if (!this.isEventDone(action) && !action.change_id) {
summary.difference_sum = MathBN.add(summary.difference_sum, amount)
}
summary.current_order_total = MathBN.add(
summary.current_order_total,
amount
)
if (!this.isEventDone(action) && !action.change_id) {
summary.difference_sum = MathBN.add(summary.difference_sum, amount)
}
summary.current_order_total = MathBN.add(
summary.current_order_total,
amount
)
}
const groupSum = MathBN.add(...Object.values(this.groupTotal))
@@ -172,11 +146,6 @@ export class OrderChangeProcessing {
...this.transactions.map((tr) => tr.amount)
)
summary.future_temporary_difference = MathBN.sub(
summary.future_difference,
summary.future_temporary_sum
)
summary.temporary_difference = MathBN.sub(
summary.difference_sum,
summary.temporary_difference
@@ -208,20 +177,10 @@ export class OrderChangeProcessing {
this.actionsProcessed[action.action].push(action)
}
let previousEvents: InternalOrderChangeEvent[] | undefined
if (type.commitsAction) {
previousEvents = (this.actionsProcessed[type.commitsAction] ?? []).filter(
(ac_) =>
ac_.reference_id === action.reference_id &&
ac_.status !== EVENT_STATUS.VOIDED
)
}
let calculatedAmount = action.amount ?? 0
const params = {
actions: this.actions,
action,
previousEvents,
currentOrder: this.order,
summary: this.summary,
transactions: this.transactions,
@@ -241,138 +200,9 @@ export class OrderChangeProcessing {
}
}
// If an action commits previous ones, replay them with updated values
if (type.commitsAction) {
for (const previousEvent of previousEvents ?? []) {
this.processAction_(previousEvent, true)
}
}
if (action.resolve) {
if (action.resolve.reference_id) {
this.resolveReferences(action)
}
const groupId = action.resolve.change_id ?? "__default"
if (action.resolve.change_id) {
// resolve all actions in the same group
this.resolveGroup(action)
}
if (action.resolve.amount && !action.evaluationOnly) {
this.groupTotal[groupId] ??= 0
this.groupTotal[groupId] = MathBN.sub(
this.groupTotal[groupId],
action.resolve.amount
)
}
}
return calculatedAmount
}
private resolveReferences(self: InternalOrderChangeEvent) {
const resolve = self.resolve
const resolveType = OrderChangeProcessing.typeDefinition[self.action]
Object.keys(this.actionsProcessed).forEach((actionKey) => {
const type = OrderChangeProcessing.typeDefinition[actionKey]
const actions = this.actionsProcessed[actionKey]
for (const action of actions) {
if (
action === self ||
!this.isEventPending(action) ||
action.reference_id !== resolve?.reference_id
) {
continue
}
if (type.revert && (action.evaluationOnly || resolveType.void)) {
let previousEvents: InternalOrderChangeEvent[] | undefined
if (type.commitsAction) {
previousEvents = (
this.actionsProcessed[type.commitsAction] ?? []
).filter(
(ac_) =>
ac_.reference_id === action.reference_id &&
ac_.status !== EVENT_STATUS.VOIDED
)
}
type.revert({
actions: this.actions,
action,
previousEvents,
currentOrder: this.order,
summary: this.summary,
transactions: this.transactions,
type,
})
for (const previousEvent of previousEvents ?? []) {
this.processAction_(previousEvent, true)
}
action.status =
action.evaluationOnly || resolveType.void
? EVENT_STATUS.VOIDED
: EVENT_STATUS.DONE
}
}
})
}
private resolveGroup(self: InternalOrderChangeEvent) {
const resolve = self.resolve
Object.keys(this.actionsProcessed).forEach((actionKey) => {
const type = OrderChangeProcessing.typeDefinition[actionKey]
const actions = this.actionsProcessed[actionKey]
for (const action of actions) {
if (!resolve?.change_id || action?.change_id !== resolve.change_id) {
continue
}
if (
type.revert &&
action.status !== EVENT_STATUS.DONE &&
action.status !== EVENT_STATUS.VOIDED &&
(action.evaluationOnly || type.void)
) {
let previousEvents: InternalOrderChangeEvent[] | undefined
if (type.commitsAction) {
previousEvents = (
this.actionsProcessed[type.commitsAction] ?? []
).filter(
(ac_) =>
ac_.reference_id === action.reference_id &&
ac_.status !== EVENT_STATUS.VOIDED
)
}
type.revert({
actions: this.actions,
action: action,
previousEvents,
currentOrder: this.order,
summary: this.summary,
transactions: this.transactions,
type: OrderChangeProcessing.typeDefinition[action.action],
})
for (const previousEvent of previousEvents ?? []) {
this.processAction_(previousEvent, true)
}
action.status =
action.evaluationOnly || type.void
? EVENT_STATUS.VOIDED
: EVENT_STATUS.DONE
}
}
})
}
public getSummary(): OrderSummaryDTO {
const summary = this.summary
const orderSummary = {
@@ -380,10 +210,6 @@ export class OrderChangeProcessing {
original_order_total: new BigNumber(summary.original_order_total),
current_order_total: new BigNumber(summary.current_order_total),
temporary_difference: new BigNumber(summary.temporary_difference),
future_difference: new BigNumber(summary.future_difference),
future_temporary_difference: new BigNumber(
summary.future_temporary_difference
),
pending_difference: new BigNumber(summary.pending_difference),
difference_sum: new BigNumber(summary.difference_sum),
paid_total: new BigNumber(summary.paid_total),

View File

@@ -4,9 +4,3 @@ export function setActionReference(existing, action, options) {
existing.actions.push(action)
}
}
export function unsetActionReference(existing, action) {
if (Array.isArray(existing?.actions)) {
existing.actions = existing.actions.filter((a) => a.id !== action.id)
}
}