chore(inventory, core-flows): big number support (#8204)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { IInventoryService, InventoryTypes } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
import { ModuleRegistrationName } from "@medusajs/utils"
|
||||
import { MathBN, ModuleRegistrationName } from "@medusajs/utils"
|
||||
|
||||
export const adjustInventoryLevelsStepId = "adjust-inventory-levels-step"
|
||||
export const adjustInventoryLevelsStep = createStep(
|
||||
@@ -30,7 +30,7 @@ export const adjustInventoryLevelsStep = createStep(
|
||||
input.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
adjustment: item.adjustment * -1,
|
||||
adjustment: MathBN.mult(item.adjustment, -1),
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import { FulfillmentDTO, OrderDTO, OrderWorkflow } from "@medusajs/types"
|
||||
import {
|
||||
BigNumberInput,
|
||||
FulfillmentDTO,
|
||||
OrderDTO,
|
||||
OrderWorkflow,
|
||||
} from "@medusajs/types"
|
||||
import { MedusaError, Modules } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
createStep,
|
||||
createWorkflow,
|
||||
parallelize,
|
||||
transform,
|
||||
WorkflowData,
|
||||
} from "@medusajs/workflows-sdk"
|
||||
import { useRemoteQueryStep } from "../../common"
|
||||
import { cancelFulfillmentWorkflow } from "../../fulfillment"
|
||||
@@ -82,7 +87,7 @@ function prepareInventoryUpdate({
|
||||
const inventoryAdjustment: {
|
||||
inventory_item_id: string
|
||||
location_id: string
|
||||
adjustment: number // TODO: BigNumberInput
|
||||
adjustment: BigNumberInput
|
||||
}[] = []
|
||||
|
||||
for (const item of fulfillment.items) {
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import {
|
||||
BigNumberInput,
|
||||
FulfillmentDTO,
|
||||
FulfillmentWorkflow,
|
||||
OrderDTO,
|
||||
OrderWorkflow,
|
||||
ReservationItemDTO,
|
||||
} from "@medusajs/types"
|
||||
import { MedusaError, Modules } from "@medusajs/utils"
|
||||
import { MathBN, MedusaError, Modules } from "@medusajs/utils"
|
||||
import {
|
||||
WorkflowData,
|
||||
createStep,
|
||||
@@ -68,6 +69,7 @@ function prepareFulfillmentData({
|
||||
order,
|
||||
input,
|
||||
shippingOption,
|
||||
shippingMethod,
|
||||
reservations,
|
||||
}: {
|
||||
order: OrderDTO
|
||||
@@ -77,6 +79,7 @@ function prepareFulfillmentData({
|
||||
provider_id: string
|
||||
service_zone: { fulfillment_set: { location?: { id: string } } }
|
||||
}
|
||||
shippingMethod: { data?: Record<string, unknown> | null }
|
||||
reservations: ReservationItemDTO[]
|
||||
}) {
|
||||
const inputItems = input.items
|
||||
@@ -120,8 +123,9 @@ function prepareFulfillmentData({
|
||||
location_id: locationId,
|
||||
provider_id: shippingOption.provider_id,
|
||||
shipping_option_id: shippingOption.id,
|
||||
data: shippingMethod.data,
|
||||
items: fulfillmentItems,
|
||||
labels: [] as FulfillmentWorkflow.CreateFulfillmentLabelWorkflowDTO[], // TODO: shipping labels
|
||||
labels: input.labels ?? [],
|
||||
delivery_address: shippingAddress as any,
|
||||
},
|
||||
}
|
||||
@@ -136,13 +140,13 @@ function prepareInventoryUpdate({ reservations, order, input, inputItemsMap }) {
|
||||
const toDelete: string[] = []
|
||||
const toUpdate: {
|
||||
id: string
|
||||
quantity: number // TODO: BigNumberInput
|
||||
quantity: BigNumberInput
|
||||
location_id: string
|
||||
}[] = []
|
||||
const inventoryAdjustment: {
|
||||
inventory_item_id: string
|
||||
location_id: string
|
||||
adjustment: number // TODO: BigNumberInput
|
||||
adjustment: BigNumberInput
|
||||
}[] = []
|
||||
|
||||
for (const item of order.items) {
|
||||
@@ -163,7 +167,7 @@ function prepareInventoryUpdate({ reservations, order, input, inputItemsMap }) {
|
||||
inventoryAdjustment.push({
|
||||
inventory_item_id: reservation.inventory_item_id,
|
||||
location_id: input.location_id ?? reservation.location_id,
|
||||
adjustment: -item.quantity, // TODO: MathBN.mul(-1, item.quantity)
|
||||
adjustment: MathBN.mult(item.quantity, -1),
|
||||
})
|
||||
|
||||
if (quantity === 0) {
|
||||
@@ -201,6 +205,7 @@ export const createOrderFulfillmentWorkflow = createWorkflow(
|
||||
"items.variant.manage_inventory",
|
||||
"shipping_address.*",
|
||||
"shipping_methods.shipping_option_id", // TODO: which shipping method to use when multiple?
|
||||
"shipping_methods.data",
|
||||
],
|
||||
variables: { id: input.order_id },
|
||||
list: false,
|
||||
@@ -216,6 +221,10 @@ export const createOrderFulfillmentWorkflow = createWorkflow(
|
||||
}, {})
|
||||
})
|
||||
|
||||
const shippingMethod = transform(order, (data) => {
|
||||
return { data: data.shipping_methods?.[0].data }
|
||||
})
|
||||
|
||||
const shippingOptionId = transform(order, (data) => {
|
||||
return data.shipping_methods?.[0]?.shipping_option_id
|
||||
})
|
||||
@@ -250,7 +259,7 @@ export const createOrderFulfillmentWorkflow = createWorkflow(
|
||||
}).config({ name: "get-reservations" })
|
||||
|
||||
const fulfillmentData = transform(
|
||||
{ order, input, shippingOption, reservations },
|
||||
{ order, input, shippingOption, shippingMethod, reservations },
|
||||
prepareFulfillmentData
|
||||
)
|
||||
|
||||
@@ -278,12 +287,12 @@ export const createOrderFulfillmentWorkflow = createWorkflow(
|
||||
prepareInventoryUpdate
|
||||
)
|
||||
|
||||
adjustInventoryLevelsStep(inventoryAdjustment)
|
||||
parallelize(
|
||||
registerOrderFulfillmentStep(registerOrderFulfillmentData),
|
||||
createRemoteLinkStep(link),
|
||||
updateReservationsStep(toUpdate),
|
||||
deleteReservationsStep(toDelete),
|
||||
adjustInventoryLevelsStep(inventoryAdjustment)
|
||||
deleteReservationsStep(toDelete)
|
||||
)
|
||||
|
||||
// trigger event OrderModuleService.Events.FULFILLMENT_CREATED
|
||||
|
||||
@@ -92,7 +92,7 @@ export const createOrderShipmentWorkflow = createWorkflow(
|
||||
const fulfillmentData = transform({ input }, ({ input }) => {
|
||||
return {
|
||||
id: input.fulfillment_id,
|
||||
labels: input.labels,
|
||||
labels: input.labels ?? [],
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ function prepareFulfillmentData({
|
||||
provider_id: returnShippingOption.provider_id,
|
||||
shipping_option_id: input.return_shipping?.option_id,
|
||||
items: fulfillmentItems,
|
||||
labels: [] as FulfillmentWorkflow.CreateFulfillmentLabelWorkflowDTO[],
|
||||
labels: input.return_shipping?.labels ?? [],
|
||||
delivery_address: order.shipping_address ?? ({} as any), // TODO: should it be the stock location address?
|
||||
order: order,
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
NumericalComparisonOperator,
|
||||
StringComparisonOperator,
|
||||
} from "../../common"
|
||||
import { BigNumberInput } from "../../totals/big-number"
|
||||
|
||||
/**
|
||||
* The reservation item details.
|
||||
@@ -25,7 +26,7 @@ export interface ReservationItemDTO {
|
||||
/**
|
||||
* The quantity of the reservation item.
|
||||
*/
|
||||
quantity: number
|
||||
quantity: BigNumberInput
|
||||
|
||||
/**
|
||||
* The associated line item's ID.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { BigNumberInput } from "../../totals/big-number"
|
||||
|
||||
export interface CreateInventoryLevelInput {
|
||||
/**
|
||||
* The ID of the associated inventory item.
|
||||
@@ -66,5 +68,5 @@ export type BulkAdjustInventoryLevelInput = {
|
||||
/**
|
||||
* The quantity to adjust the inventory level by.
|
||||
*/
|
||||
adjustment: number // TODO: BigNumberInput
|
||||
adjustment: BigNumberInput
|
||||
} & UpdateInventoryLevelInput
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { BigNumberInput } from "../../totals"
|
||||
|
||||
/**
|
||||
* @interface
|
||||
*
|
||||
@@ -8,7 +10,7 @@ export interface UpdateReservationItemInput {
|
||||
/**
|
||||
* The reserved quantity.
|
||||
*/
|
||||
quantity?: number
|
||||
quantity?: BigNumberInput
|
||||
/**
|
||||
* The ID of the associated location.
|
||||
*/
|
||||
@@ -48,7 +50,7 @@ export interface CreateReservationItemInput {
|
||||
/**
|
||||
* The reserved quantity.
|
||||
*/
|
||||
quantity: number
|
||||
quantity: BigNumberInput
|
||||
/**
|
||||
* Allow backorder of the item. If true, it won't check inventory levels before reserving it.
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,7 @@ import { RestoreReturn, SoftDeleteReturn } from "../dal"
|
||||
import { FindConfig } from "../common"
|
||||
import { IModuleService } from "../modules-sdk"
|
||||
import { Context } from "../shared-context"
|
||||
import { BigNumberInput, IBigNumber } from "../totals"
|
||||
import {
|
||||
FilterableInventoryItemProps,
|
||||
FilterableInventoryLevelProps,
|
||||
@@ -1044,7 +1045,7 @@ export interface IInventoryService extends IModuleService {
|
||||
data: {
|
||||
inventoryItemId: string
|
||||
locationId: string
|
||||
adjustment: number
|
||||
adjustment: BigNumberInput
|
||||
}[],
|
||||
context?: Context
|
||||
): Promise<InventoryLevelDTO[]>
|
||||
@@ -1052,7 +1053,7 @@ export interface IInventoryService extends IModuleService {
|
||||
adjustInventory(
|
||||
inventoryItemId: string,
|
||||
locationId: string,
|
||||
adjustment: number,
|
||||
adjustment: BigNumberInput,
|
||||
context?: Context
|
||||
): Promise<InventoryLevelDTO>
|
||||
|
||||
@@ -1076,7 +1077,7 @@ export interface IInventoryService extends IModuleService {
|
||||
confirmInventory(
|
||||
inventoryItemId: string,
|
||||
locationIds: string[],
|
||||
quantity: number,
|
||||
quantity: BigNumberInput,
|
||||
context?: Context
|
||||
): Promise<boolean>
|
||||
|
||||
@@ -1086,7 +1087,7 @@ export interface IInventoryService extends IModuleService {
|
||||
* @param {string} inventoryItemId - The inventory item's ID.
|
||||
* @param {string[]} locationIds - The locations' IDs.
|
||||
* @param {Context} context - A context used to share resources, such as transaction manager, between the application and the module.
|
||||
* @returns {Promise<number>} The available quantity of the item.
|
||||
* @returns {Promise<BigNumber>} The available quantity of the item.
|
||||
*
|
||||
* @example
|
||||
* const availableQuantity =
|
||||
@@ -1099,7 +1100,7 @@ export interface IInventoryService extends IModuleService {
|
||||
inventoryItemId: string,
|
||||
locationIds: string[],
|
||||
context?: Context
|
||||
): Promise<number>
|
||||
): Promise<IBigNumber>
|
||||
|
||||
/**
|
||||
* This method retrieves the stocked quantity of an inventory item in the specified location.
|
||||
@@ -1107,7 +1108,7 @@ export interface IInventoryService extends IModuleService {
|
||||
* @param {string} inventoryItemId - The inventory item's ID.
|
||||
* @param {string[]} locationIds - The locations' IDs.
|
||||
* @param {Context} context - A context used to share resources, such as transaction manager, between the application and the module.
|
||||
* @returns {Promise<number>} The stocked quantity of the item.
|
||||
* @returns {Promise<BigNumber>} The stocked quantity of the item.
|
||||
*
|
||||
* @example
|
||||
* const stockedQuantity =
|
||||
@@ -1120,7 +1121,7 @@ export interface IInventoryService extends IModuleService {
|
||||
inventoryItemId: string,
|
||||
locationIds: string[],
|
||||
context?: Context
|
||||
): Promise<number>
|
||||
): Promise<IBigNumber>
|
||||
|
||||
/**
|
||||
* This method retrieves the reserved quantity of an inventory item in the specified location.
|
||||
@@ -1128,7 +1129,7 @@ export interface IInventoryService extends IModuleService {
|
||||
* @param {string} inventoryItemId - The inventory item's ID.
|
||||
* @param {string[]} locationIds - The locations' IDs.
|
||||
* @param {Context} context - A context used to share resources, such as transaction manager, between the application and the module.
|
||||
* @returns {Promise<number>} The reserved quantity of the item.
|
||||
* @returns {Promise<BigNumber>} The reserved quantity of the item.
|
||||
*
|
||||
* @example
|
||||
* const reservedQuantity =
|
||||
@@ -1141,5 +1142,5 @@ export interface IInventoryService extends IModuleService {
|
||||
inventoryItemId: string,
|
||||
locationIds: string[],
|
||||
context?: Context
|
||||
): Promise<number>
|
||||
): Promise<IBigNumber>
|
||||
}
|
||||
|
||||
@@ -1,10 +1,24 @@
|
||||
import BigNumberJS from "bignumber.js"
|
||||
|
||||
export interface IBigNumber {
|
||||
numeric: number
|
||||
raw?: BigNumberRawValue
|
||||
bigNumber?: BigNumberJS
|
||||
|
||||
toJSON(): number
|
||||
valueOf(): number
|
||||
}
|
||||
|
||||
export type BigNumberRawValue = {
|
||||
value: string | number
|
||||
[key: string]: unknown
|
||||
}
|
||||
|
||||
export type BigNumberInput = BigNumberRawValue | number | string | BigNumberJS
|
||||
export type BigNumberInput =
|
||||
| BigNumberRawValue
|
||||
| number
|
||||
| string
|
||||
| BigNumberJS
|
||||
| IBigNumber
|
||||
|
||||
export type BigNumberValue = BigNumberJS | number | string
|
||||
export type BigNumberValue = BigNumberJS | number | string | IBigNumber
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { BigNumberInput } from "../../totals"
|
||||
import { CreateFulfillmentLabelWorkflowDTO } from "../fulfillment/create-fulfillment"
|
||||
|
||||
interface CreateOrderFulfillmentItem {
|
||||
id: string
|
||||
@@ -9,6 +10,7 @@ export interface CreateOrderFulfillmentWorkflowInput {
|
||||
order_id: string
|
||||
created_by?: string // The id of the authenticated user
|
||||
items: CreateOrderFulfillmentItem[]
|
||||
labels?: CreateFulfillmentLabelWorkflowDTO[]
|
||||
no_notification?: boolean
|
||||
location_id?: string | null
|
||||
metadata?: Record<string, any> | null
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { BigNumberInput } from "../../totals"
|
||||
import { CreateFulfillmentLabelWorkflowDTO } from "../fulfillment/create-fulfillment"
|
||||
|
||||
export interface CreateReturnItem {
|
||||
id: string
|
||||
@@ -16,6 +17,7 @@ export interface CreateOrderReturnWorkflowInput {
|
||||
return_shipping?: {
|
||||
option_id: string
|
||||
price?: number
|
||||
labels?: CreateFulfillmentLabelWorkflowDTO[]
|
||||
}
|
||||
note?: string | null
|
||||
receive_now?: boolean
|
||||
|
||||
@@ -12,7 +12,7 @@ export interface CreateOrderShipmentWorkflowInput {
|
||||
fulfillment_id: string
|
||||
created_by?: string // The id of the authenticated user
|
||||
items: CreateOrderShipmentItem[]
|
||||
labels: CreateFulfillmentLabelWorkflowDTO[]
|
||||
labels?: CreateFulfillmentLabelWorkflowDTO[]
|
||||
no_notification?: boolean
|
||||
metadata?: MetadataType
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { BigNumberInput, BigNumberRawValue } from "@medusajs/types"
|
||||
import { BigNumberInput, BigNumberRawValue, IBigNumber } from "@medusajs/types"
|
||||
import { BigNumber as BigNumberJS } from "bignumber.js"
|
||||
import { isBigNumber, isString } from "../common"
|
||||
|
||||
export class BigNumber {
|
||||
export class BigNumber implements IBigNumber {
|
||||
static DEFAULT_PRECISION = 20
|
||||
|
||||
private numeric_: number
|
||||
@@ -110,7 +110,7 @@ export class BigNumber {
|
||||
this.bignumber_ = newValue.bignumber_
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
toJSON(): number {
|
||||
return this.bignumber_
|
||||
? this.bignumber_?.toNumber()
|
||||
: this.raw_
|
||||
@@ -118,7 +118,7 @@ export class BigNumber {
|
||||
: this.numeric_
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
valueOf(): number {
|
||||
return this.numeric_
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user