chore(inventory, core-flows): big number support (#8204)

This commit is contained in:
Carlos R. L. Rodrigues
2024-07-22 06:32:25 -03:00
committed by GitHub
parent c307972a99
commit fb29b958fa
27 changed files with 363 additions and 218 deletions
@@ -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.
*/
+10 -9
View File
@@ -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>
}
+16 -2
View File
@@ -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
}
+4 -4
View File
@@ -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_
}
}