feat(medusa, medusa-plugin-brightpearl): Inventory management for Brightpearl (#3192)
This commit is contained in:
1 parent
8b6464180a
commit
4a85627435
20 files changed
+855
-227
No files matched your search
@@ -1,6 +1,7 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||
import SalesChannelFeatureFlag from "../loaders/feature-flags/sales-channels"
|
||||
|
||||
export const featureFlag = "sales_channels"
|
||||
export const featureFlag = SalesChannelFeatureFlag.key
|
||||
|
||||
export class salesChannel1656949291839 implements MigrationInterface {
|
||||
name = "salesChannel1656949291839"
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||
import SalesChannelFeatureFlag from "../loaders/feature-flags/sales-channels"
|
||||
|
||||
export const featureFlag = SalesChannelFeatureFlag.key
|
||||
|
||||
export class addSalesChannelMetadata1680714052628
|
||||
implements MigrationInterface
|
||||
{
|
||||
name = "addSalesChannelMetadata1680714052628"
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "sales_channel" ADD COLUMN "metadata" jsonb NULL;`
|
||||
)
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "sales_channel" DROP COLUMN "metadata"`
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import { BeforeInsert, Column, OneToMany } from "typeorm"
|
||||
|
||||
import { FeatureFlagEntity } from "../utils/feature-flag-decorators"
|
||||
import { SoftDeletableEntity } from "../interfaces"
|
||||
import { generateEntityId } from "../utils"
|
||||
import { DbAwareColumn, generateEntityId } from "../utils"
|
||||
import { SalesChannelLocation } from "./sales-channel-location"
|
||||
|
||||
@FeatureFlagEntity("sales_channels")
|
||||
@@ -16,6 +16,9 @@ export class SalesChannel extends SoftDeletableEntity {
|
||||
@Column({ default: false })
|
||||
is_disabled: boolean
|
||||
|
||||
@DbAwareColumn({ type: "jsonb", nullable: true })
|
||||
metadata: Record<string, unknown> | null
|
||||
|
||||
@OneToMany(
|
||||
() => SalesChannelLocation,
|
||||
(scLocation) => scLocation.sales_channel,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { EntityManager, In } from "typeorm"
|
||||
import {
|
||||
ICacheService,
|
||||
IEventBusService,
|
||||
IInventoryService,
|
||||
IStockLocationService,
|
||||
InventoryItemDTO,
|
||||
@@ -23,14 +24,19 @@ type InjectedDependencies = {
|
||||
productVariantService: ProductVariantService
|
||||
stockLocationService: IStockLocationService
|
||||
inventoryService: IInventoryService
|
||||
eventBusService: IEventBusService
|
||||
}
|
||||
|
||||
class ProductVariantInventoryService extends TransactionBaseService {
|
||||
protected manager_: EntityManager
|
||||
protected transactionManager_: EntityManager | undefined
|
||||
|
||||
protected readonly salesChannelLocationService_: SalesChannelLocationService
|
||||
protected readonly salesChannelInventoryService_: SalesChannelInventoryService
|
||||
protected readonly productVariantService_: ProductVariantService
|
||||
protected readonly stockLocationService_: IStockLocationService
|
||||
protected readonly inventoryService_: IInventoryService
|
||||
protected readonly eventBusService_: IEventBusService
|
||||
protected readonly cacheService_: ICacheService
|
||||
|
||||
constructor({
|
||||
@@ -39,6 +45,7 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
salesChannelInventoryService,
|
||||
productVariantService,
|
||||
inventoryService,
|
||||
eventBusService,
|
||||
}: InjectedDependencies) {
|
||||
// eslint-disable-next-line prefer-rest-params
|
||||
super(arguments[0])
|
||||
@@ -48,6 +55,7 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
this.stockLocationService_ = stockLocationService
|
||||
this.productVariantService_ = productVariantService
|
||||
this.inventoryService_ = inventoryService
|
||||
this.eventBusService_ = eventBusService
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,6 +116,10 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
locationIds = stockLocations.map((l) => l.id)
|
||||
}
|
||||
|
||||
if (locationIds.length === 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
const hasInventory = await Promise.all(
|
||||
variantInventory.map(async (inventoryPart) => {
|
||||
const itemQuantity = inventoryPart.required_quantity * quantity
|
||||
@@ -346,7 +358,6 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
}
|
||||
|
||||
const toReserve = {
|
||||
type: "order",
|
||||
line_item_id: context.lineItemId,
|
||||
}
|
||||
|
||||
@@ -385,7 +396,7 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
locationId = locations[0].location_id
|
||||
}
|
||||
|
||||
return await Promise.all(
|
||||
const reservationItems = await Promise.all(
|
||||
variantInventory.map(async (inventoryPart) => {
|
||||
const itemQuantity = inventoryPart.required_quantity * quantity
|
||||
return await this.inventoryService_.createReservationItem({
|
||||
@@ -396,6 +407,8 @@ class ProductVariantInventoryService extends TransactionBaseService {
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
return reservationItems
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,11 @@ import {
|
||||
AbstractCartCompletionStrategy,
|
||||
CartCompletionResponse,
|
||||
} from "../interfaces"
|
||||
import { IInventoryService, ReservationItemDTO } from "@medusajs/types"
|
||||
import {
|
||||
IEventBusService,
|
||||
IInventoryService,
|
||||
ReservationItemDTO,
|
||||
} from "@medusajs/types"
|
||||
import { IdempotencyKey, Order } from "../models"
|
||||
import OrderService, {
|
||||
ORDER_CART_ALREADY_EXISTS_ERROR,
|
||||
@@ -28,6 +32,7 @@ type InjectedDependencies = {
|
||||
swapService: SwapService
|
||||
manager: EntityManager
|
||||
inventoryService: IInventoryService
|
||||
eventBusService: IEventBusService
|
||||
}
|
||||
|
||||
class CartCompletionStrategy extends AbstractCartCompletionStrategy {
|
||||
@@ -39,6 +44,7 @@ class CartCompletionStrategy extends AbstractCartCompletionStrategy {
|
||||
protected readonly orderService_: OrderService
|
||||
protected readonly swapService_: SwapService
|
||||
protected readonly inventoryService_: IInventoryService
|
||||
protected readonly eventBusService_: IEventBusService
|
||||
|
||||
constructor({
|
||||
productVariantInventoryService,
|
||||
@@ -48,6 +54,7 @@ class CartCompletionStrategy extends AbstractCartCompletionStrategy {
|
||||
orderService,
|
||||
swapService,
|
||||
inventoryService,
|
||||
eventBusService,
|
||||
}: InjectedDependencies) {
|
||||
// eslint-disable-next-line prefer-rest-params
|
||||
super(arguments[0])
|
||||
@@ -59,6 +66,7 @@ class CartCompletionStrategy extends AbstractCartCompletionStrategy {
|
||||
this.orderService_ = orderService
|
||||
this.swapService_ = swapService
|
||||
this.inventoryService_ = inventoryService
|
||||
this.eventBusService_ = eventBusService
|
||||
}
|
||||
|
||||
async complete(
|
||||
@@ -384,6 +392,14 @@ class CartCompletionStrategy extends AbstractCartCompletionStrategy {
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
} else if (this.inventoryService_) {
|
||||
await this.eventBusService_.emit("reservation-items.bulk-created", {
|
||||
ids: reservations
|
||||
.filter(([reservation]) => !!reservation)
|
||||
.flatMap(([reservationItemArr]) =>
|
||||
reservationItemArr!.map((item) => item.id)
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user