feat(order): create claim and exchange (#7734)

This commit is contained in:
Carlos R. L. Rodrigues
2024-06-18 08:08:16 -03:00
committed by GitHub
parent e0b14519f1
commit cfa983001b
45 changed files with 2571 additions and 437 deletions

View File

@@ -9,3 +9,4 @@ export * from "./receive-return-item"
export * from "./return-item"
export * from "./ship-item"
export * from "./shipping-add"
export * from "./write-off-item"

View File

@@ -7,7 +7,7 @@ import { setActionReference } from "../set-action-reference"
OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_ADD, {
operation({ action, currentOrder }) {
const existing = currentOrder.items.find(
(item) => item.id === action.reference_id
(item) => item.id === action.details.reference_id
)
if (existing) {
@@ -23,7 +23,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_ADD, {
setActionReference(existing, action)
} else {
currentOrder.items.push({
id: action.reference_id!,
id: action.details.reference_id!,
order_id: currentOrder.id,
return_id: action.details.return_id,
claim_id: action.details.claim_id,
@@ -38,7 +38,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_ADD, {
},
revert({ action, currentOrder }) {
const existingIndex = currentOrder.items.findIndex(
(item) => item.id === action.reference_id
(item) => item.id === action.details.reference_id
)
if (existingIndex > -1) {
@@ -55,13 +55,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_ADD, {
}
},
validate({ action }) {
const refId = action.reference_id
if (!isDefined(action.reference_id)) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"Reference ID is required."
)
}
const refId = action.details?.reference_id
if (!isDefined(action.amount) && !isDefined(action.details?.unit_price)) {
throw new MedusaError(

View File

@@ -8,7 +8,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_REMOVE, {
isDeduction: true,
operation({ action, currentOrder }) {
const existingIndex = currentOrder.items.findIndex(
(item) => item.id === action.reference_id
(item) => item.id === action.details.reference_id
)
const existing = currentOrder.items[existingIndex]
@@ -31,7 +31,7 @@ OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_REMOVE, {
},
revert({ action, currentOrder }) {
const existing = currentOrder.items.find(
(item) => item.id === action.reference_id
(item) => item.id === action.details.reference_id
)
if (existing) {
@@ -42,14 +42,14 @@ OrderChangeProcessing.registerActionType(ChangeActionType.ITEM_REMOVE, {
)
} else {
currentOrder.items.push({
id: action.reference_id!,
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.reference_id
const refId = action.details?.reference_id
if (!isDefined(refId)) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,

View File

@@ -31,24 +31,23 @@ export function applyChangesToOrder(
const version = actionsMap[order.id][0].version ?? 1
for (const item of calculated.order.items) {
const orderItem = item.detail as any
const orderItem = (item.detail as any) ?? item
const itemId = item.detail ? orderItem.item_id : item.id
itemsToUpsert.push({
id: orderItem.version === version ? orderItem.id : undefined,
item_id: item.id,
item_id: itemId,
order_id: order.id,
version,
return_id: item.detail.return_id,
claim_id: item.detail.claim_id,
exchange_id: item.detail.exchange_id,
quantity: item.detail.quantity,
fulfilled_quantity: item.detail.fulfilled_quantity,
shipped_quantity: item.detail.shipped_quantity,
return_requested_quantity: item.detail.return_requested_quantity,
return_received_quantity: item.detail.return_received_quantity,
return_dismissed_quantity: item.detail.return_dismissed_quantity,
written_off_quantity: item.detail.written_off_quantity,
metadata: item.detail.metadata,
} as any)
quantity: orderItem.quantity,
fulfilled_quantity: orderItem.fulfilled_quantity,
shipped_quantity: orderItem.shipped_quantity,
return_requested_quantity: orderItem.return_requested_quantity,
return_received_quantity: orderItem.return_received_quantity,
return_dismissed_quantity: orderItem.return_dismissed_quantity,
written_off_quantity: orderItem.written_off_quantity,
metadata: orderItem.metadata,
} as OrderItem)
}
const orderSummary = order.summary as any
@@ -61,6 +60,10 @@ export function applyChangesToOrder(
if (version > order.version) {
for (const shippingMethod of calculated.order.shipping_methods ?? []) {
if (!shippingMethod) {
continue
}
const sm = {
...((shippingMethod as any).detail ?? shippingMethod),
version,

View File

@@ -29,13 +29,16 @@ export function setFindMethods<T>(klass: Constructor<T>, entity: any) {
}
}
const config = mapRepositoryToOrderModel(findOptions_)
const isRelatedEntity = entity !== Order
const config = mapRepositoryToOrderModel(findOptions_, isRelatedEntity)
let orderAlias = "o0"
if (entity !== Order) {
// first relation is always order if entity is not Order
if (isRelatedEntity) {
// first relation is always order if the entity is not Order
config.options.populate.unshift("order")
orderAlias = "o1"
config.options.populate.unshift("order.items")
}
let defaultVersion = knex.raw(`"${orderAlias}"."version"`)
@@ -44,7 +47,7 @@ export function setFindMethods<T>(klass: Constructor<T>, entity: any) {
const sql = manager
.qb(Order, "_sub0")
.select("version")
.where({ id: knex.raw(`"o0"."order_id"`) })
.where({ id: knex.raw(`"${orderAlias}"."order_id"`) })
.getKnexQuery()
.toString()
@@ -55,23 +58,22 @@ export function setFindMethods<T>(klass: Constructor<T>, entity: any) {
delete config.where?.version
config.options.populateWhere ??= {}
const popWhere = config.options.populateWhere
if (entity !== Order) {
config.options.populateWhere.order ??= {}
config.options.populateWhere.order.version = version
config.options.populateWhere.order.summary ??= {}
config.options.populateWhere.order.summary.version = version
} else {
config.options.populateWhere.summary ??= {}
config.options.populateWhere.summary.version = version
if (isRelatedEntity) {
popWhere.order ??= {}
}
config.options.populateWhere.items ??= {}
config.options.populateWhere.items.version = version
const orderWhere = isRelatedEntity ? popWhere.order : popWhere
config.options.populateWhere.shipping_methods ??= {}
config.options.populateWhere.shipping_methods.version = version
orderWhere.summary ??= {}
orderWhere.summary.version = version
orderWhere.items ??= {}
orderWhere.items.version = version
popWhere.shipping_methods ??= {}
popWhere.shipping_methods.version = version
if (!config.options.orderBy) {
config.options.orderBy = { id: "ASC" }
@@ -98,10 +100,11 @@ export function setFindMethods<T>(klass: Constructor<T>, entity: any) {
})
}
const config = mapRepositoryToOrderModel(findOptions_)
const isRelatedEntity = entity !== Order
const config = mapRepositoryToOrderModel(findOptions_, isRelatedEntity)
let orderAlias = "o0"
if (entity !== Order) {
if (isRelatedEntity) {
// first relation is always order if entity is not Order
config.options.populate.unshift("order")
orderAlias = "o1"
@@ -113,7 +116,7 @@ export function setFindMethods<T>(klass: Constructor<T>, entity: any) {
const sql = manager
.qb(Order, "_sub0")
.select("version")
.where({ id: knex.raw(`"o0"."order_id"`) })
.where({ id: knex.raw(`"${orderAlias}"."order_id"`) })
.getKnexQuery()
.toString()
@@ -124,23 +127,22 @@ export function setFindMethods<T>(klass: Constructor<T>, entity: any) {
delete config.where.version
config.options.populateWhere ??= {}
const popWhere = config.options.populateWhere
if (entity !== Order) {
config.options.populateWhere.order ??= {}
config.options.populateWhere.order.version = version
config.options.populateWhere.order.summary ??= {}
config.options.populateWhere.order.summary.version = version
} else {
config.options.populateWhere.summary ??= {}
config.options.populateWhere.summary.version = version
if (isRelatedEntity) {
popWhere.order ??= {}
}
config.options.populateWhere.items ??= {}
config.options.populateWhere.items.version = version
const orderWhere = isRelatedEntity ? popWhere.order : popWhere
config.options.populateWhere.shipping_methods ??= {}
config.options.populateWhere.shipping_methods.version = version
orderWhere.summary ??= {}
orderWhere.summary.version = version
orderWhere.items ??= {}
orderWhere.items.version = version
popWhere.shipping_methods ??= {}
popWhere.shipping_methods.version = version
if (!config.options.orderBy) {
config.options.orderBy = { id: "ASC" }

View File

@@ -3,6 +3,7 @@ import {
BigNumber,
MathBN,
isDefined,
isPresent,
transformPropertiesToBigNumber,
} from "@medusajs/utils"
import {
@@ -183,9 +184,14 @@ export class OrderChangeProcessing {
action: InternalOrderChangeEvent,
isReplay = false
): BigNumberInput | void {
const definedType = OrderChangeProcessing.typeDefinition[action.action]
if (!isPresent(definedType)) {
throw new Error(`Action type ${action.action} is not defined`)
}
const type = {
...OrderChangeProcessing.defaultConfig,
...OrderChangeProcessing.typeDefinition[action.action],
...definedType,
}
this.actionsProcessed[action.action] ??= []

View File

@@ -5,18 +5,32 @@ import {
deduplicate,
isDefined,
} from "@medusajs/utils"
import { Order, OrderClaim, OrderExchange, Return } from "@models"
export function formatOrder(
order,
options: {
entity: any
includeTotals?: boolean
}
): OrderTypes.OrderDTO | OrderTypes.OrderDTO[] {
): Partial<OrderTypes.OrderDTO> | Partial<OrderTypes.OrderDTO>[] {
const isArray = Array.isArray(order)
const orders = [...(isArray ? order : [order])]
orders.map((order) => {
order.items = order.items?.map((orderItem) => {
let mainOrder = order
const isRelatedEntity = options?.entity !== Order
if (isRelatedEntity) {
if (!order.order) {
return order
}
mainOrder = order.order
}
mainOrder.items = mainOrder.items?.map((orderItem) => {
const detail = { ...orderItem }
delete detail.order
delete detail.item
@@ -29,30 +43,118 @@ export function formatOrder(
}
})
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,
},
if (isRelatedEntity) {
if (order.return) {
formatOrderReturn(order.return, mainOrder)
}
})
order.summary = order.summary?.[0]?.totals
if (options.entity === OrderClaim) {
formatClaim(order)
} else if (options.entity === OrderExchange) {
formatExchange(order)
} else if (options.entity === Return) {
formatReturn(order)
}
}
return options?.includeTotals
? createRawPropertiesFromBigNumber(decorateCartTotals(order))
: order
if (order.shipping_methods) {
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,
},
}
})
}
if (mainOrder.summary) {
mainOrder.summary = mainOrder.summary?.[0]?.totals
}
return createRawPropertiesFromBigNumber(
options?.includeTotals ? decorateCartTotals(order) : order
)
})
return isArray ? orders : orders[0]
}
export function mapRepositoryToOrderModel(config) {
function formatOrderReturn(orderReturn, mainOrder) {
orderReturn.items = orderReturn.items.filter(
(item) => !item.is_additional_item
)
orderReturn.items.forEach((orderItem) => {
const item = mainOrder.items?.find((item) => item.id === orderItem.item_id)
orderItem.detail = item?.detail
})
}
function formatClaim(claim) {
if (claim.additional_items) {
claim.additional_items = claim.additional_items.filter(
(item) => item.is_additional_item
)
claim.additional_items.forEach((orderItem) => {
const item = claim.order.items?.find(
(item) => item.id === orderItem.item_id
)
orderItem.detail = item?.detail
})
}
if (!claim.claim_items) {
return
}
claim.claim_items = claim.claim_items.filter(
(item) => !item.is_additional_item
)
claim.claim_items.forEach((orderItem) => {
const item = claim.order.items?.find(
(item) => item.id === orderItem.item_id
)
orderItem.detail = item?.detail
})
}
function formatExchange(exchange) {
if (!exchange.additional_items) {
return
}
exchange.additional_items.forEach((orderItem) => {
const item = exchange.order.items?.find(
(item) => item.id === orderItem.item_id
)
orderItem.detail = item?.detail
})
}
function formatReturn(returnOrder) {
if (!returnOrder.items) {
return
}
returnOrder.items.forEach((orderItem) => {
const item = returnOrder.order.items?.find(
(item) => item.id === orderItem.item_id
)
orderItem.detail = item?.detail
})
}
export function mapRepositoryToOrderModel(config, isRelatedEntity = false) {
const conf = { ...config }
function replace(obj, type): string[] | undefined {