feat(core-flows,medusa,utils,types): adds delivered_quantity to order (#9130)
what: - adds delivered_quantity to order https://github.com/user-attachments/assets/709b1727-08ed-4a88-ae29-38f13540e301
This commit is contained in:
@@ -869,6 +869,25 @@
|
||||
"nullable": false,
|
||||
"mappedType": "json"
|
||||
},
|
||||
"delivered_quantity": {
|
||||
"name": "delivered_quantity",
|
||||
"type": "numeric",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": false,
|
||||
"default": "0",
|
||||
"mappedType": "decimal"
|
||||
},
|
||||
"raw_delivered_quantity": {
|
||||
"name": "raw_delivered_quantity",
|
||||
"type": "jsonb",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": false,
|
||||
"mappedType": "json"
|
||||
},
|
||||
"shipped_quantity": {
|
||||
"name": "shipped_quantity",
|
||||
"type": "numeric",
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Migration } from "@mikro-orm/migrations"
|
||||
|
||||
export class Migration20240913092514 extends Migration {
|
||||
async up(): Promise<void> {
|
||||
this.addSql(
|
||||
'alter table if exists "order_item" add column if not exists "delivered_quantity" numeric not null default 0, add column if not exists "raw_delivered_quantity" jsonb;'
|
||||
)
|
||||
|
||||
this.addSql(
|
||||
`UPDATE "order_item" SET raw_delivered_quantity = '{"value": "0", "precision": 20}'::jsonb;`
|
||||
)
|
||||
|
||||
this.addSql(
|
||||
'ALTER TABLE IF EXISTS "order_item" ALTER COLUMN "raw_delivered_quantity" SET NOT NULL;'
|
||||
)
|
||||
}
|
||||
|
||||
async down(): Promise<void> {
|
||||
this.addSql(
|
||||
'alter table if exists "order_item" drop column if exists "delivered_quantity";'
|
||||
)
|
||||
this.addSql(
|
||||
'alter table if exists "order_item" drop column if exists "raw_delivered_quantity";'
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -96,6 +96,12 @@ export default class OrderItem {
|
||||
@Property({ columnType: "jsonb" })
|
||||
raw_fulfilled_quantity: BigNumberRawValue
|
||||
|
||||
@MikroOrmBigNumberProperty()
|
||||
delivered_quantity: BigNumber | number = 0
|
||||
|
||||
@Property({ columnType: "jsonb" })
|
||||
raw_delivered_quantity: BigNumberRawValue
|
||||
|
||||
@MikroOrmBigNumberProperty()
|
||||
shipped_quantity: BigNumber | number = 0
|
||||
|
||||
|
||||
@@ -6,5 +6,6 @@ export * from "./create-claim"
|
||||
export * from "./create-exchange"
|
||||
export * from "./create-return"
|
||||
export * from "./receive-return"
|
||||
export * from "./register-delivery"
|
||||
export * from "./register-fulfillment"
|
||||
export * from "./register-shipment"
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Context, OrderTypes } from "@medusajs/types"
|
||||
import { ChangeActionType } from "@medusajs/utils"
|
||||
|
||||
export async function registerDelivery(
|
||||
this: any,
|
||||
data: OrderTypes.RegisterOrderDeliveryDTO,
|
||||
sharedContext?: Context
|
||||
): Promise<void> {
|
||||
const items = data.items?.map((item) => {
|
||||
return {
|
||||
action: ChangeActionType.DELIVER_ITEM,
|
||||
internal_note: item.internal_note,
|
||||
reference: data.reference,
|
||||
reference_id: data.reference_id,
|
||||
details: {
|
||||
reference_id: item.id,
|
||||
quantity: item.quantity,
|
||||
metadata: item.metadata,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
const change = await this.createOrderChange_(
|
||||
{
|
||||
order_id: data.order_id,
|
||||
description: data.description,
|
||||
internal_note: data.internal_note,
|
||||
created_by: data.created_by,
|
||||
metadata: data.metadata,
|
||||
actions: items,
|
||||
},
|
||||
sharedContext
|
||||
)
|
||||
|
||||
await this.confirmOrderChange(change[0].id, sharedContext)
|
||||
}
|
||||
@@ -3295,4 +3295,12 @@ export default class OrderModuleService<
|
||||
): Promise<void> {
|
||||
return await BundledActions.registerShipment.bind(this)(data, sharedContext)
|
||||
}
|
||||
|
||||
@InjectTransactionManager("baseRepository_")
|
||||
async registerDelivery(
|
||||
data: OrderTypes.RegisterOrderDeliveryDTO,
|
||||
@MedusaContext() sharedContext?: Context
|
||||
): Promise<void> {
|
||||
return await BundledActions.registerDelivery.bind(this)(data, sharedContext)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ export type VirtualOrder = {
|
||||
quantity: BigNumberInput
|
||||
shipped_quantity: BigNumberInput
|
||||
fulfilled_quantity: BigNumberInput
|
||||
delivered_quantity: BigNumberInput
|
||||
return_requested_quantity: BigNumberInput
|
||||
return_received_quantity: BigNumberInput
|
||||
return_dismissed_quantity: BigNumberInput
|
||||
|
||||
67
packages/modules/order/src/utils/actions/deliver-item.ts
Normal file
67
packages/modules/order/src/utils/actions/deliver-item.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { ChangeActionType, MathBN, MedusaError } from "@medusajs/utils"
|
||||
import { OrderChangeProcessing } from "../calculate-order-change"
|
||||
import { setActionReference } from "../set-action-reference"
|
||||
|
||||
OrderChangeProcessing.registerActionType(ChangeActionType.DELIVER_ITEM, {
|
||||
operation({ action, currentOrder, options }) {
|
||||
const item = currentOrder.items.find(
|
||||
(item) => item.id === action.details.reference_id
|
||||
)!
|
||||
|
||||
item.detail.delivered_quantity ??= 0
|
||||
|
||||
item.detail.delivered_quantity = MathBN.add(
|
||||
item.detail.delivered_quantity,
|
||||
action.details.quantity
|
||||
)
|
||||
|
||||
setActionReference(item, action, options)
|
||||
},
|
||||
validate({ action, currentOrder }) {
|
||||
const refId = action.details?.reference_id
|
||||
|
||||
if (refId == null) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
"Reference ID is required."
|
||||
)
|
||||
}
|
||||
|
||||
const item = currentOrder.items.find((item) => item.id === refId)
|
||||
|
||||
if (!item) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Item ID "${refId}" not found.`
|
||||
)
|
||||
}
|
||||
|
||||
const totalDeliverable = MathBN.convert(item.quantity)
|
||||
const totalDelivered = MathBN.convert(item.detail?.delivered_quantity)
|
||||
const newDelivered = MathBN.convert(action.details?.quantity ?? 0)
|
||||
const newTotalDelivered = MathBN.sum(totalDelivered, newDelivered)
|
||||
|
||||
const totalFulfilled = MathBN.convert(item.detail?.fulfilled_quantity)
|
||||
|
||||
if (MathBN.lte(newDelivered, 0)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Quantity of item ${refId} must be greater than 0.`
|
||||
)
|
||||
}
|
||||
|
||||
if (MathBN.gt(newTotalDelivered, totalFulfilled)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Cannot deliver more items than what was fulfilled for item ${refId}.`
|
||||
)
|
||||
}
|
||||
|
||||
if (MathBN.gt(newTotalDelivered, totalDeliverable)) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Cannot deliver more items than what was ordered for item ${refId}.`
|
||||
)
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -1,5 +1,6 @@
|
||||
export * from "./cancel-item-fulfillment"
|
||||
export * from "./cancel-return"
|
||||
export * from "./deliver-item"
|
||||
export * from "./fulfill-item"
|
||||
export * from "./item-add"
|
||||
export * from "./item-remove"
|
||||
|
||||
@@ -58,6 +58,7 @@ export function applyChangesToOrder(
|
||||
version,
|
||||
quantity: orderItem.quantity,
|
||||
fulfilled_quantity: orderItem.fulfilled_quantity ?? 0,
|
||||
delivered_quantity: orderItem.delivered_quantity ?? 0,
|
||||
shipped_quantity: orderItem.shipped_quantity ?? 0,
|
||||
return_requested_quantity: orderItem.return_requested_quantity ?? 0,
|
||||
return_received_quantity: orderItem.return_received_quantity ?? 0,
|
||||
|
||||
@@ -148,6 +148,7 @@ export class OrderChangeProcessing {
|
||||
isReplay = false
|
||||
): BigNumberInput | void {
|
||||
const definedType = OrderChangeProcessing.typeDefinition[action.action]
|
||||
|
||||
if (!isPresent(definedType)) {
|
||||
throw new Error(`Action type ${action.action} is not defined`)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user