feat(medusa, types, utils, core-flows, order) request & accept order transfer (#10106)

**What**
- add request order transfer workflow
- add admin endpoint for transferring an order to a customer
- accept order transfer storefront endpoint
- accept transfer workflow
- changes in the order module to introduce new change and action types

---

**Note**
- we return 400 instead 409 currently if there is already an active order edit, I will revisit this in a followup
- endpoint for requesting order transfer from the storefront will be added in a separate PR

---

RESOLVES CMRC-701
RESOLVES CMRC-703
RESOLVES CMRC-704
RESOLVES CMRC-705
This commit is contained in:
Frane Polić
2024-11-19 09:53:22 +01:00
committed by GitHub
parent b1b7a4abf1
commit 36460a3a07
21 changed files with 660 additions and 4 deletions

View File

@@ -56,6 +56,8 @@ export type VirtualOrder = {
total: BigNumberInput
customer_id?: string
transactions?: OrderTransaction[]
metadata?: Record<string, unknown>
}

View File

@@ -13,3 +13,4 @@ export * from "./ship-item"
export * from "./shipping-add"
export * from "./shipping-remove"
export * from "./write-off-item"
export * from "./transfer-customer"

View File

@@ -0,0 +1,19 @@
import { ChangeActionType, MedusaError } from "@medusajs/framework/utils"
import { OrderChangeProcessing } from "../calculate-order-change"
import { setActionReference } from "../set-action-reference"
OrderChangeProcessing.registerActionType(ChangeActionType.TRANSFER_CUSTOMER, {
operation({ action, currentOrder, options }) {
currentOrder.customer_id = action.reference_id
setActionReference(currentOrder, action, options)
},
validate({ action }) {
if (!action.reference_id) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"Reference to customer ID is required"
)
}
},
})

View File

@@ -27,6 +27,13 @@ export function applyChangesToOrder(
const summariesToUpsert: any[] = []
const orderToUpdate: any[] = []
const orderEditableAttributes = [
"customer_id",
"sales_channel_id",
"email",
"no_notification",
]
const calculatedOrders = {}
for (const order of orders) {
const calculated = calculateOrderChange({
@@ -41,6 +48,17 @@ export function applyChangesToOrder(
calculatedOrders[order.id] = calculated
const version = actionsMap[order.id]?.[0]?.version ?? order.version
const orderAttributes: {
version?: number
customer_id?: string
} = {}
// Editable attributes that have changed
for (const attr of orderEditableAttributes) {
if (order[attr] !== calculated.order[attr]) {
orderAttributes[attr] = calculated.order[attr]
}
}
for (const item of calculated.order.items) {
if (MathBN.lte(item.quantity, 0)) {
@@ -113,12 +131,16 @@ export function applyChangesToOrder(
}
}
orderAttributes.version = version
}
if (Object.keys(orderAttributes).length > 0) {
orderToUpdate.push({
selector: {
id: order.id,
},
data: {
version,
...orderAttributes,
},
})
}