chore(): Reorganize modules (#7210)
**What** Move all modules to the modules directory
This commit is contained in:
committed by
GitHub
parent
7a351eef09
commit
4eae25e1ef
13
packages/modules/order/src/utils/action-key.ts
Normal file
13
packages/modules/order/src/utils/action-key.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export enum ChangeActionType {
|
||||
CANCEL = "CANCEL",
|
||||
CANCEL_RETURN = "CANCEL_RETURN",
|
||||
FULFILL_ITEM = "FULFILL_ITEM",
|
||||
ITEM_ADD = "ITEM_ADD",
|
||||
ITEM_REMOVE = "ITEM_REMOVE",
|
||||
RECEIVE_DAMAGED_RETURN_ITEM = "RECEIVE_DAMAGED_RETURN_ITEM",
|
||||
RECEIVE_RETURN_ITEM = "RECEIVE_RETURN_ITEM",
|
||||
RETURN_ITEM = "RETURN_ITEM",
|
||||
SHIPPING_ADD = "SHIPPING_ADD",
|
||||
SHIP_ITEM = "SHIP_ITEM",
|
||||
WRITE_OFF_ITEM = "WRITE_OFF_ITEM",
|
||||
}
|
||||
73
packages/modules/order/src/utils/actions/cancel-return.ts
Normal file
73
packages/modules/order/src/utils/actions/cancel-return.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { MathBN, MedusaError, isDefined } from "@medusajs/utils"
|
||||
import { ChangeActionType } from "../action-key"
|
||||
import { OrderChangeProcessing } from "../calculate-order-change"
|
||||
|
||||
OrderChangeProcessing.registerActionType(ChangeActionType.CANCEL_RETURN, {
|
||||
operation({ action, currentOrder }) {
|
||||
const existing = currentOrder.items.find(
|
||||
(item) => item.id === action.details.reference_id
|
||||
)!
|
||||
|
||||
existing.detail.return_requested_quantity ??= 0
|
||||
|
||||
existing.detail.return_requested_quantity = MathBN.sub(
|
||||
existing.detail.return_requested_quantity,
|
||||
action.details.quantity
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
},
|
||||
validate({ action, currentOrder }) {
|
||||
const refId = action.details?.reference_id
|
||||
if (!isDefined(refId)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Details reference ID is required."
|
||||
)
|
||||
}
|
||||
|
||||
if (!isDefined(action.amount) && !isDefined(action.details?.unit_price)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Unit price of item ${action.reference_id} is required if no action.amount is provided.`
|
||||
)
|
||||
}
|
||||
|
||||
const existing = currentOrder.items.find((item) => item.id === refId)
|
||||
|
||||
if (!existing) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Reference ID "${refId}" not found.`
|
||||
)
|
||||
}
|
||||
|
||||
if (!action.details?.quantity) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Quantity to cancel return of item ${refId} is required.`
|
||||
)
|
||||
}
|
||||
|
||||
const greater = MathBN.gt(
|
||||
action.details?.quantity,
|
||||
existing.detail?.return_requested_quantity
|
||||
)
|
||||
if (greater) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Cannot cancel more items than what was requested to return for item ${refId}.`
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
6
packages/modules/order/src/utils/actions/cancel.ts
Normal file
6
packages/modules/order/src/utils/actions/cancel.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { ChangeActionType } from "../action-key"
|
||||
import { OrderChangeProcessing } from "../calculate-order-change"
|
||||
|
||||
OrderChangeProcessing.registerActionType(ChangeActionType.CANCEL, {
|
||||
void: true,
|
||||
})
|
||||
71
packages/modules/order/src/utils/actions/fulfill-item.ts
Normal file
71
packages/modules/order/src/utils/actions/fulfill-item.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import { MathBN, MedusaError, isDefined } from "@medusajs/utils"
|
||||
import { ChangeActionType } from "../action-key"
|
||||
import { OrderChangeProcessing } from "../calculate-order-change"
|
||||
|
||||
OrderChangeProcessing.registerActionType(ChangeActionType.FULFILL_ITEM, {
|
||||
operation({ action, currentOrder }) {
|
||||
const existing = currentOrder.items.find(
|
||||
(item) => item.id === action.details.reference_id
|
||||
)!
|
||||
|
||||
existing.detail.fulfilled_quantity ??= 0
|
||||
|
||||
existing.detail.fulfilled_quantity = MathBN.add(
|
||||
existing.detail.fulfilled_quantity,
|
||||
action.details.quantity
|
||||
)
|
||||
},
|
||||
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
|
||||
)
|
||||
},
|
||||
validate({ action, currentOrder }) {
|
||||
const refId = action.details?.reference_id
|
||||
if (!isDefined(refId)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Reference ID is required."
|
||||
)
|
||||
}
|
||||
|
||||
const existing = currentOrder.items.find((item) => item.id === refId)
|
||||
if (!existing) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Reference ID "${refId}" not found.`
|
||||
)
|
||||
}
|
||||
|
||||
if (!action.details?.quantity) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Quantity to fulfill of item ${refId} is required.`
|
||||
)
|
||||
}
|
||||
|
||||
if (action.details?.quantity < 1) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Quantity of item ${refId} must be greater than 0.`
|
||||
)
|
||||
}
|
||||
|
||||
const notFulfilled = MathBN.sub(
|
||||
existing.quantity,
|
||||
existing.detail?.fulfilled_quantity
|
||||
)
|
||||
const greater = MathBN.gt(action.details?.quantity, notFulfilled)
|
||||
if (greater) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Cannot fulfill more items than what was ordered for item ${refId}.`
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
10
packages/modules/order/src/utils/actions/index.ts
Normal file
10
packages/modules/order/src/utils/actions/index.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
export * from "./cancel"
|
||||
export * from "./cancel-return"
|
||||
export * from "./fulfill-item"
|
||||
export * from "./item-add"
|
||||
export * from "./item-remove"
|
||||
export * from "./receive-damaged-return-item"
|
||||
export * from "./receive-return-item"
|
||||
export * from "./return-item"
|
||||
export * from "./ship-item"
|
||||
export * from "./shipping-add"
|
||||
79
packages/modules/order/src/utils/actions/item-add.ts
Normal file
79
packages/modules/order/src/utils/actions/item-add.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { MathBN, MedusaError, isDefined } from "@medusajs/utils"
|
||||
import { VirtualOrder } from "@types"
|
||||
import { ChangeActionType } from "../action-key"
|
||||
import { OrderChangeProcessing } from "../calculate-order-change"
|
||||
|
||||
OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_ADD, {
|
||||
operation({ action, currentOrder }) {
|
||||
const existing = currentOrder.items.find(
|
||||
(item) => item.id === action.reference_id
|
||||
)
|
||||
|
||||
if (existing) {
|
||||
existing.detail.quantity ??= 0
|
||||
|
||||
existing.quantity = MathBN.add(existing.quantity, action.details.quantity)
|
||||
|
||||
existing.detail.quantity = MathBN.add(
|
||||
existing.detail.quantity,
|
||||
action.details.quantity
|
||||
)
|
||||
} else {
|
||||
currentOrder.items.push({
|
||||
id: action.reference_id!,
|
||||
unit_price: action.details.unit_price,
|
||||
quantity: action.details.quantity,
|
||||
} as VirtualOrder["items"][0])
|
||||
}
|
||||
|
||||
return MathBN.mult(action.details.unit_price, action.details.quantity)
|
||||
},
|
||||
revert({ action, currentOrder }) {
|
||||
const existingIndex = currentOrder.items.findIndex(
|
||||
(item) => item.id === action.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)
|
||||
}
|
||||
}
|
||||
},
|
||||
validate({ action }) {
|
||||
const refId = action.reference_id
|
||||
if (!isDefined(action.reference_id)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Reference ID is required."
|
||||
)
|
||||
}
|
||||
|
||||
if (!isDefined(action.amount) && !isDefined(action.details?.unit_price)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Unit price of item ${refId} is required if no action.amount is provided.`
|
||||
)
|
||||
}
|
||||
|
||||
if (!action.details?.quantity) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Quantity of item ${refId} is required.`
|
||||
)
|
||||
}
|
||||
|
||||
if (MathBN.lt(action.details?.quantity, 1)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Quantity of item ${refId} must be greater than 0.`
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
99
packages/modules/order/src/utils/actions/item-remove.ts
Normal file
99
packages/modules/order/src/utils/actions/item-remove.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import { MathBN, MedusaError, isDefined } from "@medusajs/utils"
|
||||
import { VirtualOrder } from "@types"
|
||||
import { ChangeActionType } from "../action-key"
|
||||
import { OrderChangeProcessing } from "../calculate-order-change"
|
||||
|
||||
OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_REMOVE, {
|
||||
isDeduction: true,
|
||||
operation({ action, currentOrder }) {
|
||||
const existingIndex = currentOrder.items.findIndex(
|
||||
(item) => item.id === action.reference_id
|
||||
)
|
||||
|
||||
const existing = currentOrder.items[existingIndex]
|
||||
|
||||
existing.detail.quantity ??= 0
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
return MathBN.mult(existing.unit_price, action.details.quantity)
|
||||
},
|
||||
revert({ action, currentOrder }) {
|
||||
const existing = currentOrder.items.find(
|
||||
(item) => item.id === action.reference_id
|
||||
)
|
||||
|
||||
if (existing) {
|
||||
existing.quantity = MathBN.add(existing.quantity, action.details.quantity)
|
||||
existing.detail.quantity = MathBN.add(
|
||||
existing.detail.quantity,
|
||||
action.details.quantity
|
||||
)
|
||||
} else {
|
||||
currentOrder.items.push({
|
||||
id: action.reference_id!,
|
||||
unit_price: action.details.unit_price,
|
||||
quantity: action.details.quantity,
|
||||
} as VirtualOrder["items"][0])
|
||||
}
|
||||
},
|
||||
validate({ action, currentOrder }) {
|
||||
const refId = action.reference_id
|
||||
if (!isDefined(refId)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Reference ID is required."
|
||||
)
|
||||
}
|
||||
|
||||
const existing = currentOrder.items.find((item) => item.id === refId)
|
||||
if (!existing) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Reference ID "${refId}" not found.`
|
||||
)
|
||||
}
|
||||
|
||||
if (!isDefined(action.amount) && !isDefined(action.details?.unit_price)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Unit price of item ${refId} is required if no action.amount is provided.`
|
||||
)
|
||||
}
|
||||
|
||||
if (!action.details?.quantity) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Quantity of item ${refId} is required.`
|
||||
)
|
||||
}
|
||||
|
||||
if (MathBN.lt(action.details?.quantity, 1)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Quantity of item ${refId} must be greater than 0.`
|
||||
)
|
||||
}
|
||||
|
||||
const notFulfilled = MathBN.sub(
|
||||
existing.quantity,
|
||||
existing.detail?.fulfilled_quantity
|
||||
)
|
||||
|
||||
const greater = MathBN.gt(action.details?.quantity, notFulfilled)
|
||||
if (greater) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Cannot remove fulfilled item: Item ${refId}.`
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,112 @@
|
||||
import { MathBN, MedusaError, isDefined } from "@medusajs/utils"
|
||||
import { EVENT_STATUS } from "@types"
|
||||
import { ChangeActionType } from "../action-key"
|
||||
import { OrderChangeProcessing } from "../calculate-order-change"
|
||||
|
||||
OrderChangeProcessing.registerActionType(
|
||||
ChangeActionType.RECEIVE_DAMAGED_RETURN_ITEM,
|
||||
{
|
||||
isDeduction: true,
|
||||
commitsAction: "return_item",
|
||||
operation({ action, currentOrder, previousEvents }) {
|
||||
const existing = currentOrder.items.find(
|
||||
(item) => item.id === action.details.reference_id
|
||||
)!
|
||||
|
||||
let toReturn = action.details.quantity
|
||||
|
||||
existing.detail.return_dismissed_quantity ??= 0
|
||||
existing.detail.return_requested_quantity ??= 0
|
||||
|
||||
existing.detail.return_dismissed_quantity = MathBN.add(
|
||||
existing.detail.return_dismissed_quantity,
|
||||
toReturn
|
||||
)
|
||||
existing.detail.return_requested_quantity = MathBN.sub(
|
||||
existing.detail.return_requested_quantity,
|
||||
toReturn
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
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)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Details reference ID is required."
|
||||
)
|
||||
}
|
||||
|
||||
const existing = currentOrder.items.find((item) => item.id === refId)
|
||||
|
||||
if (!existing) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Reference ID "${refId}" not found.`
|
||||
)
|
||||
}
|
||||
|
||||
if (!action.details?.quantity) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Quantity to return of item ${refId} is required.`
|
||||
)
|
||||
}
|
||||
|
||||
const quantityRequested = existing?.detail.return_requested_quantity || 0
|
||||
if (action.details?.quantity > quantityRequested) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Cannot receive more items than what was requested to be returned for item ${refId}.`
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
119
packages/modules/order/src/utils/actions/receive-return-item.ts
Normal file
119
packages/modules/order/src/utils/actions/receive-return-item.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import {
|
||||
MathBN,
|
||||
MedusaError,
|
||||
isDefined,
|
||||
transformPropertiesToBigNumber,
|
||||
} from "@medusajs/utils"
|
||||
import { EVENT_STATUS } from "@types"
|
||||
import { ChangeActionType } from "../action-key"
|
||||
import { OrderChangeProcessing } from "../calculate-order-change"
|
||||
|
||||
OrderChangeProcessing.registerActionType(ChangeActionType.RECEIVE_RETURN_ITEM, {
|
||||
isDeduction: true,
|
||||
commitsAction: "return_item",
|
||||
operation({ action, currentOrder, previousEvents }) {
|
||||
const existing = currentOrder.items.find(
|
||||
(item) => item.id === action.details.reference_id
|
||||
)!
|
||||
|
||||
let toReturn = action.details.quantity
|
||||
|
||||
existing.detail.return_received_quantity ??= 0
|
||||
existing.detail.return_requested_quantity ??= 0
|
||||
|
||||
existing.detail.return_received_quantity = MathBN.add(
|
||||
existing.detail.return_received_quantity,
|
||||
toReturn
|
||||
)
|
||||
existing.detail.return_requested_quantity = MathBN.sub(
|
||||
existing.detail.return_requested_quantity,
|
||||
toReturn
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
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)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Details reference ID is required."
|
||||
)
|
||||
}
|
||||
|
||||
const existing = currentOrder.items.find((item) => item.id === refId)
|
||||
|
||||
if (!existing) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Reference ID "${refId}" not found.`
|
||||
)
|
||||
}
|
||||
|
||||
if (!action.details?.quantity) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Quantity to receive return of item ${refId} is required.`
|
||||
)
|
||||
}
|
||||
|
||||
const quantityRequested = existing?.detail?.return_requested_quantity || 0
|
||||
|
||||
const greater = MathBN.gt(action.details?.quantity, quantityRequested)
|
||||
if (greater) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Cannot receive more items than what was requested to be returned for item ${refId}.`
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
69
packages/modules/order/src/utils/actions/return-item.ts
Normal file
69
packages/modules/order/src/utils/actions/return-item.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { MathBN, MedusaError, isDefined } from "@medusajs/utils"
|
||||
import { ChangeActionType } from "../action-key"
|
||||
import { OrderChangeProcessing } from "../calculate-order-change"
|
||||
|
||||
OrderChangeProcessing.registerActionType(ChangeActionType.RETURN_ITEM, {
|
||||
isDeduction: true,
|
||||
awaitRequired: true,
|
||||
operation({ action, currentOrder }) {
|
||||
const existing = currentOrder.items.find(
|
||||
(item) => item.id === action.details.reference_id
|
||||
)!
|
||||
|
||||
existing.detail.return_requested_quantity ??= 0
|
||||
existing.detail.return_requested_quantity = MathBN.add(
|
||||
existing.detail.return_requested_quantity,
|
||||
action.details.quantity
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
},
|
||||
validate({ action, currentOrder }) {
|
||||
const refId = action.details?.reference_id
|
||||
if (!isDefined(refId)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Details reference ID is required."
|
||||
)
|
||||
}
|
||||
|
||||
const existing = currentOrder.items.find((item) => item.id === refId)
|
||||
|
||||
if (!existing) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Reference ID "${refId}" not found.`
|
||||
)
|
||||
}
|
||||
|
||||
if (!action.details?.quantity) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Quantity to return of item ${refId} is required.`
|
||||
)
|
||||
}
|
||||
|
||||
const quantityAvailable = MathBN.sub(
|
||||
existing!.detail?.shipped_quantity ?? 0,
|
||||
existing!.detail?.return_requested_quantity ?? 0
|
||||
)
|
||||
|
||||
const greater = MathBN.gt(action.details?.quantity, quantityAvailable)
|
||||
if (greater) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Cannot request to return more items than what was shipped for item ${refId}.`
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
72
packages/modules/order/src/utils/actions/ship-item.ts
Normal file
72
packages/modules/order/src/utils/actions/ship-item.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { MathBN, MedusaError, isDefined } from "@medusajs/utils"
|
||||
import { ChangeActionType } from "../action-key"
|
||||
import { OrderChangeProcessing } from "../calculate-order-change"
|
||||
|
||||
OrderChangeProcessing.registerActionType(ChangeActionType.SHIP_ITEM, {
|
||||
operation({ action, currentOrder }) {
|
||||
const existing = currentOrder.items.find(
|
||||
(item) => item.id === action.details.reference_id
|
||||
)!
|
||||
|
||||
existing.detail.shipped_quantity ??= 0
|
||||
|
||||
existing.detail.shipped_quantity = MathBN.add(
|
||||
existing.detail.shipped_quantity,
|
||||
action.details.quantity
|
||||
)
|
||||
},
|
||||
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
|
||||
)
|
||||
},
|
||||
validate({ action, currentOrder }) {
|
||||
const refId = action.details?.reference_id
|
||||
if (!isDefined(refId)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Reference ID is required."
|
||||
)
|
||||
}
|
||||
|
||||
const existing = currentOrder.items.find((item) => item.id === refId)
|
||||
if (!existing) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Reference ID "${refId}" not found.`
|
||||
)
|
||||
}
|
||||
|
||||
if (!action.details?.quantity) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Quantity to ship of item ${refId} is required.`
|
||||
)
|
||||
}
|
||||
|
||||
if (MathBN.lt(action.details?.quantity, 1)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Quantity of item ${refId} must be greater than 0.`
|
||||
)
|
||||
}
|
||||
|
||||
const notShipped = MathBN.sub(
|
||||
existing.detail?.fulfilled_quantity,
|
||||
existing.detail?.shipped_quantity
|
||||
)
|
||||
|
||||
const greater = MathBN.gt(action.details?.quantity, notShipped)
|
||||
if (greater) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Cannot ship more items than what was fulfilled for item ${refId}.`
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
46
packages/modules/order/src/utils/actions/shipping-add.ts
Normal file
46
packages/modules/order/src/utils/actions/shipping-add.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { MedusaError, isDefined } from "@medusajs/utils"
|
||||
import { ChangeActionType } from "../action-key"
|
||||
import { OrderChangeProcessing } from "../calculate-order-change"
|
||||
|
||||
OrderChangeProcessing.registerActionType(ChangeActionType.SHIPPING_ADD, {
|
||||
operation({ action, currentOrder }) {
|
||||
const shipping = Array.isArray(currentOrder.shipping_methods)
|
||||
? currentOrder.shipping_methods
|
||||
: [currentOrder.shipping_methods]
|
||||
|
||||
shipping.push({
|
||||
id: action.reference_id!,
|
||||
price: action.amount as number,
|
||||
})
|
||||
|
||||
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(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Reference ID is required."
|
||||
)
|
||||
}
|
||||
|
||||
if (!isDefined(action.amount)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Amount is required."
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
61
packages/modules/order/src/utils/actions/write-off-item.ts
Normal file
61
packages/modules/order/src/utils/actions/write-off-item.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { MathBN, MedusaError, isDefined } from "@medusajs/utils"
|
||||
import { ChangeActionType } from "../action-key"
|
||||
import { OrderChangeProcessing } from "../calculate-order-change"
|
||||
|
||||
OrderChangeProcessing.registerActionType(ChangeActionType.WRITE_OFF_ITEM, {
|
||||
operation({ action, currentOrder }) {
|
||||
const existing = currentOrder.items.find(
|
||||
(item) => item.id === action.details.reference_id
|
||||
)!
|
||||
|
||||
existing.detail.written_off_quantity ??= 0
|
||||
existing.detail.written_off_quantity = MathBN.add(
|
||||
existing.detail.written_off_quantity,
|
||||
action.details.quantity
|
||||
)
|
||||
},
|
||||
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
|
||||
)
|
||||
},
|
||||
validate({ action, currentOrder }) {
|
||||
const refId = action.details?.reference_id
|
||||
if (!isDefined(refId)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Details reference ID is required."
|
||||
)
|
||||
}
|
||||
|
||||
const existing = currentOrder.items.find((item) => item.id === refId)
|
||||
|
||||
if (!existing) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Reference ID "${refId}" not found.`
|
||||
)
|
||||
}
|
||||
|
||||
if (!action.details?.quantity) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Quantity to write-off item ${refId} is required.`
|
||||
)
|
||||
}
|
||||
|
||||
const quantityAvailable = existing!.quantity ?? 0
|
||||
const greater = MathBN.gt(action.details?.quantity, quantityAvailable)
|
||||
if (greater) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Cannot claim more items than what was ordered."
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
412
packages/modules/order/src/utils/calculate-order-change.ts
Normal file
412
packages/modules/order/src/utils/calculate-order-change.ts
Normal file
@@ -0,0 +1,412 @@
|
||||
import { BigNumberInput, OrderSummaryDTO } from "@medusajs/types"
|
||||
import {
|
||||
BigNumber,
|
||||
MathBN,
|
||||
isDefined,
|
||||
transformPropertiesToBigNumber,
|
||||
} from "@medusajs/utils"
|
||||
import {
|
||||
ActionTypeDefinition,
|
||||
EVENT_STATUS,
|
||||
InternalOrderChangeEvent,
|
||||
OrderChangeEvent,
|
||||
OrderSummaryCalculated,
|
||||
OrderTransaction,
|
||||
VirtualOrder,
|
||||
} from "@types"
|
||||
|
||||
type InternalOrderSummary = OrderSummaryCalculated & {
|
||||
futureTemporarySum: BigNumberInput
|
||||
}
|
||||
|
||||
export class OrderChangeProcessing {
|
||||
private static typeDefinition: { [key: string]: ActionTypeDefinition } = {}
|
||||
private static defaultConfig = {
|
||||
awaitRequired: false,
|
||||
isDeduction: false,
|
||||
}
|
||||
|
||||
private order: VirtualOrder
|
||||
private transactions: OrderTransaction[]
|
||||
private actions: InternalOrderChangeEvent[]
|
||||
|
||||
private actionsProcessed: { [key: string]: InternalOrderChangeEvent[] } = {}
|
||||
private groupTotal: Record<string, BigNumberInput> = {}
|
||||
private summary: InternalOrderSummary
|
||||
|
||||
public static registerActionType(key: string, type: ActionTypeDefinition) {
|
||||
OrderChangeProcessing.typeDefinition[key] = type
|
||||
}
|
||||
|
||||
constructor({
|
||||
order,
|
||||
transactions,
|
||||
actions,
|
||||
}: {
|
||||
order: VirtualOrder
|
||||
transactions: OrderTransaction[]
|
||||
actions: InternalOrderChangeEvent[]
|
||||
}) {
|
||||
this.order = JSON.parse(JSON.stringify(order))
|
||||
this.transactions = JSON.parse(JSON.stringify(transactions ?? []))
|
||||
this.actions = JSON.parse(JSON.stringify(actions ?? []))
|
||||
|
||||
const transactionTotal = MathBN.add(...transactions.map((tr) => tr.amount))
|
||||
|
||||
transformPropertiesToBigNumber(this.order.metadata)
|
||||
|
||||
this.summary = {
|
||||
futureDifference: 0,
|
||||
futureTemporaryDifference: 0,
|
||||
temporaryDifference: 0,
|
||||
pendingDifference: 0,
|
||||
futureTemporarySum: 0,
|
||||
differenceSum: 0,
|
||||
currentOrderTotal: this.order.total ?? 0,
|
||||
originalOrderTotal: this.order.total ?? 0,
|
||||
transactionTotal,
|
||||
}
|
||||
}
|
||||
|
||||
private isEventActive(action: InternalOrderChangeEvent): boolean {
|
||||
const status = action.status
|
||||
return (
|
||||
status === undefined ||
|
||||
status === EVENT_STATUS.PENDING ||
|
||||
status === EVENT_STATUS.DONE
|
||||
)
|
||||
}
|
||||
private isEventDone(action: InternalOrderChangeEvent): boolean {
|
||||
const status = action.status
|
||||
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)
|
||||
}
|
||||
|
||||
const summary = this.summary
|
||||
for (const action of this.actions) {
|
||||
if (!this.isEventActive(action)) {
|
||||
continue
|
||||
}
|
||||
|
||||
const type = {
|
||||
...OrderChangeProcessing.defaultConfig,
|
||||
...OrderChangeProcessing.typeDefinition[action.action],
|
||||
}
|
||||
|
||||
const amount = MathBN.mult(action.amount!, type.isDeduction ? -1 : 1)
|
||||
|
||||
if (action.group_id && !action.evaluationOnly) {
|
||||
this.groupTotal[action.group_id] ??= 0
|
||||
this.groupTotal[action.group_id] = MathBN.add(
|
||||
this.groupTotal[action.group_id],
|
||||
amount
|
||||
)
|
||||
}
|
||||
|
||||
if (type.awaitRequired && !this.isEventDone(action)) {
|
||||
if (action.evaluationOnly) {
|
||||
summary.futureTemporarySum = MathBN.add(
|
||||
summary.futureTemporarySum,
|
||||
amount
|
||||
)
|
||||
} else {
|
||||
summary.temporaryDifference = MathBN.add(
|
||||
summary.temporaryDifference,
|
||||
amount
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (action.evaluationOnly) {
|
||||
summary.futureDifference = MathBN.add(summary.futureDifference, amount)
|
||||
} else {
|
||||
if (!this.isEventDone(action) && !action.group_id) {
|
||||
summary.differenceSum = MathBN.add(summary.differenceSum, amount)
|
||||
}
|
||||
summary.currentOrderTotal = MathBN.add(
|
||||
summary.currentOrderTotal,
|
||||
amount
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const groupSum = MathBN.add(...Object.values(this.groupTotal))
|
||||
|
||||
summary.differenceSum = MathBN.add(summary.differenceSum, groupSum)
|
||||
|
||||
summary.transactionTotal = MathBN.sum(
|
||||
...this.transactions.map((tr) => tr.amount)
|
||||
)
|
||||
|
||||
summary.futureTemporaryDifference = MathBN.sub(
|
||||
summary.futureDifference,
|
||||
summary.futureTemporarySum
|
||||
)
|
||||
|
||||
summary.temporaryDifference = MathBN.sub(
|
||||
summary.differenceSum,
|
||||
summary.temporaryDifference
|
||||
)
|
||||
|
||||
summary.pendingDifference = MathBN.sub(
|
||||
summary.currentOrderTotal,
|
||||
summary.transactionTotal
|
||||
)
|
||||
}
|
||||
|
||||
private processAction_(
|
||||
action: InternalOrderChangeEvent,
|
||||
isReplay = false
|
||||
): BigNumberInput | void {
|
||||
const type = {
|
||||
...OrderChangeProcessing.defaultConfig,
|
||||
...OrderChangeProcessing.typeDefinition[action.action],
|
||||
}
|
||||
|
||||
this.actionsProcessed[action.action] ??= []
|
||||
|
||||
if (!isReplay) {
|
||||
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,
|
||||
type,
|
||||
}
|
||||
if (typeof type.validate === "function") {
|
||||
type.validate(params)
|
||||
}
|
||||
|
||||
if (typeof type.operation === "function") {
|
||||
calculatedAmount = type.operation(params) as BigNumberInput
|
||||
|
||||
// the action.amount has priority over the calculated amount
|
||||
if (!isDefined(action.amount)) {
|
||||
action.amount = calculatedAmount ?? 0
|
||||
}
|
||||
}
|
||||
|
||||
// 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.group_id ?? "__default"
|
||||
if (action.resolve.group_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?.group_id || action?.group_id !== resolve.group_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 = {
|
||||
transactionTotal: new BigNumber(summary.transactionTotal),
|
||||
originalOrderTotal: new BigNumber(summary.originalOrderTotal),
|
||||
currentOrderTotal: new BigNumber(summary.currentOrderTotal),
|
||||
temporaryDifference: new BigNumber(summary.temporaryDifference),
|
||||
futureDifference: new BigNumber(summary.futureDifference),
|
||||
futureTemporaryDifference: new BigNumber(
|
||||
summary.futureTemporaryDifference
|
||||
),
|
||||
pendingDifference: new BigNumber(summary.pendingDifference),
|
||||
differenceSum: new BigNumber(summary.differenceSum),
|
||||
} as unknown as OrderSummaryDTO
|
||||
|
||||
/*
|
||||
{
|
||||
total: summary.currentOrderTotal
|
||||
|
||||
subtotal: number
|
||||
total_tax: number
|
||||
|
||||
ordered_total: summary.originalOrderTotal
|
||||
fulfilled_total: number
|
||||
returned_total: number
|
||||
return_request_total: number
|
||||
write_off_total: number
|
||||
projected_total: number
|
||||
|
||||
net_total: number
|
||||
net_subtotal: number
|
||||
net_total_tax: number
|
||||
|
||||
future_total: number
|
||||
future_subtotal: number
|
||||
future_total_tax: number
|
||||
future_projected_total: number
|
||||
|
||||
balance: summary.pendingDifference
|
||||
future_balance: number
|
||||
}
|
||||
*/
|
||||
|
||||
return orderSummary
|
||||
}
|
||||
|
||||
public getCurrentOrder(): VirtualOrder {
|
||||
return this.order
|
||||
}
|
||||
}
|
||||
|
||||
export function calculateOrderChange({
|
||||
order,
|
||||
transactions = [],
|
||||
actions = [],
|
||||
}: {
|
||||
order: VirtualOrder
|
||||
transactions?: OrderTransaction[]
|
||||
actions?: OrderChangeEvent[]
|
||||
}) {
|
||||
const calc = new OrderChangeProcessing({ order, transactions, actions })
|
||||
calc.processActions()
|
||||
|
||||
return {
|
||||
summary: calc.getSummary(),
|
||||
order: calc.getCurrentOrder(),
|
||||
}
|
||||
}
|
||||
3
packages/modules/order/src/utils/index.ts
Normal file
3
packages/modules/order/src/utils/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from "./action-key"
|
||||
export * from "./actions"
|
||||
export * from "./calculate-order-change"
|
||||
123
packages/modules/order/src/utils/transform-order.ts
Normal file
123
packages/modules/order/src/utils/transform-order.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
import { OrderTypes } from "@medusajs/types"
|
||||
import {
|
||||
createRawPropertiesFromBigNumber,
|
||||
decorateCartTotals,
|
||||
deduplicate,
|
||||
isDefined,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
export function formatOrder(
|
||||
order,
|
||||
options: {
|
||||
includeTotals?: boolean
|
||||
}
|
||||
): OrderTypes.OrderDTO | OrderTypes.OrderDTO[] {
|
||||
const isArray = Array.isArray(order)
|
||||
const orders = [...(isArray ? order : [order])]
|
||||
|
||||
orders.map((order) => {
|
||||
order.items = order.items?.map((orderItem) => {
|
||||
const detail = { ...orderItem }
|
||||
delete detail.order
|
||||
delete detail.item
|
||||
|
||||
return {
|
||||
...orderItem.item,
|
||||
quantity: detail.quantity,
|
||||
raw_quantity: detail.raw_quantity,
|
||||
detail,
|
||||
}
|
||||
})
|
||||
|
||||
order.shipping_methods = order.shipping_methods?.map((shippingMethod) => {
|
||||
const sm = { ...shippingMethod.shipping_method }
|
||||
|
||||
delete shippingMethod.shipping_method
|
||||
return {
|
||||
...sm,
|
||||
order_id: shippingMethod.order_id,
|
||||
detail: {
|
||||
...shippingMethod,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
order.summary = order.summary?.[0]?.totals
|
||||
|
||||
return options?.includeTotals
|
||||
? createRawPropertiesFromBigNumber(decorateCartTotals(order))
|
||||
: order
|
||||
})
|
||||
|
||||
return isArray ? orders : orders[0]
|
||||
}
|
||||
|
||||
export function mapRepositoryToOrderModel(config) {
|
||||
const conf = { ...config }
|
||||
|
||||
function replace(obj, type): string[] | undefined {
|
||||
if (!isDefined(obj[type])) {
|
||||
return
|
||||
}
|
||||
|
||||
return deduplicate(
|
||||
obj[type].sort().map((rel) => {
|
||||
if (rel == "items.quantity") {
|
||||
if (type === "fields") {
|
||||
obj.populate.push("items.item")
|
||||
}
|
||||
return "items.item.quantity"
|
||||
}
|
||||
if (rel == "summary" && type === "fields") {
|
||||
obj.populate.push("summary")
|
||||
return "summary.totals"
|
||||
} else if (
|
||||
rel.includes("shipping_methods") &&
|
||||
!rel.includes("shipping_methods.shipping_method")
|
||||
) {
|
||||
obj.populate.push("shipping_methods.shipping_method")
|
||||
|
||||
return rel.replace(
|
||||
"shipping_methods",
|
||||
"shipping_methods.shipping_method"
|
||||
)
|
||||
} else if (rel.includes("items.detail")) {
|
||||
return rel.replace("items.detail", "items")
|
||||
} else if (rel == "items") {
|
||||
return "items.item"
|
||||
} else if (rel.includes("items.") && !rel.includes("items.item")) {
|
||||
return rel.replace("items.", "items.item.")
|
||||
}
|
||||
return rel
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
conf.options.fields = replace(config.options, "fields")
|
||||
conf.options.populate = replace(config.options, "populate")
|
||||
|
||||
if (conf.where?.items) {
|
||||
const original = { ...conf.where.items }
|
||||
if (original.detail) {
|
||||
delete conf.where.items.detail
|
||||
}
|
||||
|
||||
conf.where.items = {
|
||||
item: conf.where?.items,
|
||||
}
|
||||
|
||||
if (original.quantity) {
|
||||
conf.where.items.quantity = original.quantity
|
||||
delete conf.where.items.item.quantity
|
||||
}
|
||||
|
||||
if (original.detail) {
|
||||
conf.where.items = {
|
||||
...original.detail,
|
||||
...conf.where.items,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return conf
|
||||
}
|
||||
Reference in New Issue
Block a user