feat(medusa, medusa-plugin-brightpearl): Inventory management for Brightpearl (#3192)

This commit is contained in:
Philip Korsholm authored and GitHub committed 2023-04-23 12:50:19 +02:00
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"`
)
}
}
+4 -1
View File
@@ -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)
),
})
}
}