Skip to content

Commit

Permalink
Merge branch 'develop' into feat/remove-reservations-for-line-items-w…
Browse files Browse the repository at this point in the history
…hen-confirming-order-edit
  • Loading branch information
kodiakhq[bot] authored Mar 30, 2023
2 parents 9e47a45 + 999aeb1 commit 409813e
Show file tree
Hide file tree
Showing 10 changed files with 172 additions and 73 deletions.
5 changes: 5 additions & 0 deletions .changeset/poor-bulldogs-repeat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@medusajs/medusa-oas-cli": patch
---

fix(oas:test): fix beforeAll timeout silent failure
5 changes: 5 additions & 0 deletions .changeset/serious-geckos-change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@medusajs/medusa": patch
---

fix(medusa): Fix hanging inventory item migration script
90 changes: 59 additions & 31 deletions packages/medusa/src/scripts/migrate-inventory-items.ts
Original file line number Diff line number Diff line change
@@ -1,58 +1,80 @@
import { AwilixContainer } from "awilix"
import dotenv from "dotenv"
import express from "express"

import { IInventoryService, IStockLocationService } from "@medusajs/types"
import loaders from "../loaders"
import { ProductVariant } from "../models"
import {
ProductVariantInventoryService,
ProductVariantService,
} from "../services"

import { AwilixContainer } from "awilix"
import { EntityManager } from "typeorm"
import { ProductVariant } from "../models"
import dotenv from "dotenv"
import express from "express"
import loaders from "../loaders"

dotenv.config()

const BATCH_SIZE = 100

const migrateProductVariant = async (
variant: ProductVariant,
locationId: string,
{ container }: { container: AwilixContainer }
{
container,
transactionManager,
}: { container: AwilixContainer; transactionManager: EntityManager }
) => {
const productVariantInventoryService: ProductVariantInventoryService =
container.resolve("productVariantInventoryService")

const productVariantInventoryServiceTx =
productVariantInventoryService.withTransaction(transactionManager)

const existingVariantInventoryItems =
await productVariantInventoryServiceTx.listByVariant(variant.id)

if (existingVariantInventoryItems.length) {
return
}

const inventoryService: IInventoryService =
container.resolve("inventoryService")

if (!variant.manage_inventory) {
return
}

const inventoryItem = await inventoryService.createInventoryItem({
sku: variant.sku,
material: variant.material,
width: variant.width,
length: variant.length,
height: variant.height,
weight: variant.weight,
origin_country: variant.origin_country,
hs_code: variant.hs_code,
mid_code: variant.mid_code,
requires_shipping: true,
})
const context = { transactionManager }
const inventoryItem = await inventoryService.createInventoryItem(
{
sku: variant.sku,
material: variant.material,
width: variant.width,
length: variant.length,
height: variant.height,
weight: variant.weight,
origin_country: variant.origin_country,
hs_code: variant.hs_code,
mid_code: variant.mid_code,
requires_shipping: true,
},
context
)

await productVariantInventoryService.attachInventoryItem(
await productVariantInventoryServiceTx.attachInventoryItem(
variant.id,
inventoryItem.id,
1
)

await inventoryService.createInventoryLevel({
location_id: locationId,
inventory_item_id: inventoryItem.id,
stocked_quantity: variant.inventory_quantity,
incoming_quantity: 0,
})
await inventoryService.createInventoryLevel(
{
location_id: locationId,
inventory_item_id: inventoryItem.id,
stocked_quantity: variant.inventory_quantity,
incoming_quantity: 0,
},
context
)
}

const migrateStockLocation = async (container: AwilixContainer) => {
Expand All @@ -75,11 +97,17 @@ const processBatch = async (
locationId: string,
container: AwilixContainer
) => {
await Promise.all(
variants.map(async (variant) => {
await migrateProductVariant(variant, locationId, { container })
})
)
const manager = container.resolve("manager")
return await manager.transaction(async (transactionManager) => {
await Promise.all(
variants.map(async (variant) => {
await migrateProductVariant(variant, locationId, {
container,
transactionManager,
})
})
)
})
}

const migrate = async function ({ directory }) {
Expand Down
10 changes: 7 additions & 3 deletions packages/medusa/src/services/product-variant-inventory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,13 @@ class ProductVariantInventoryService extends TransactionBaseService {
})

// Verify that item exists
await this.inventoryService_.retrieveInventoryItem(inventoryItemId, {
select: ["id"],
})
await this.inventoryService_.retrieveInventoryItem(
inventoryItemId,
{
select: ["id"],
},
{ transactionManager: this.activeManager_ }
)

const variantInventoryRepo = this.activeManager_.getRepository(
ProductVariantInventoryItem
Expand Down
11 changes: 5 additions & 6 deletions packages/medusa/src/services/staged-job.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { EventBusTypes } from "@medusajs/types"
import { DeepPartial, EntityManager, In } from "typeorm"

import { EventBusTypes } from "@medusajs/types"
import { FindConfig } from "../types/common"
import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity"
import { TransactionBaseService } from "../interfaces"
import { StagedJob } from "../models"
import { StagedJobRepository } from "../repositories/staged-job"
import { FindConfig } from "../types/common"
import { TransactionBaseService } from "../interfaces"
import { isString } from "../utils"

type StagedJobServiceProps = {
Expand Down Expand Up @@ -42,8 +43,7 @@ class StagedJobService extends TransactionBaseService {
}

async create(data: EventBusTypes.EmitData[] | EventBusTypes.EmitData) {
return await this.atomicPhase_(async (manager) => {
const stagedJobRepo = manager.withRepository(this.stagedJobRepository_)
const stagedJobRepo = this.activeManager_.withRepository(this.stagedJobRepository_)

const data_ = Array.isArray(data) ? data : [data]

Expand All @@ -56,7 +56,6 @@ class StagedJobService extends TransactionBaseService {
) as QueryDeepPartialEntity<StagedJob>[]

return await stagedJobRepo.insertBulk(stagedJobs)
})
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/oas/medusa-oas-cli/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ module.exports = {
},
testEnvironment: `node`,
moduleFileExtensions: [`js`, `ts`],
testTimeout: 30000,
testTimeout: 60000,
}
5 changes: 5 additions & 0 deletions packages/oas/medusa-oas-cli/src/__tests__/command-oas.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ describe("command oas", () => {
describe("--type admin", () => {
let oas: OpenAPIObject

/**
* In a CI context, beforeAll might exceed the configured jest timeout.
* Until we upgrade our jest version, the timeout error will be swallowed
* and the test will fail in unexpected ways.
*/
beforeAll(async () => {
const outDir = path.resolve(tmpDir, uid())
await runCLI("oas", ["--type", "admin", "--out-dir", outDir])
Expand Down
5 changes: 5 additions & 0 deletions packages/oas/medusa-oas-cli/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": "./tsconfig.json",
"include": ["src"],
"exclude": ["node_modules"]
}
86 changes: 61 additions & 25 deletions packages/types/src/inventory/inventory.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { FindConfig } from "../common"

import {
CreateInventoryItemInput,
CreateInventoryLevelInput,
Expand All @@ -14,101 +12,139 @@ import {
UpdateReservationItemInput,
} from "./common"

import { FindConfig } from "../common"
import { SharedContext } from ".."

export interface IInventoryService {
listInventoryItems(
selector: FilterableInventoryItemProps,
config?: FindConfig<InventoryItemDTO>
config?: FindConfig<InventoryItemDTO>,
context?: SharedContext
): Promise<[InventoryItemDTO[], number]>

listReservationItems(
selector: FilterableReservationItemProps,
config?: FindConfig<ReservationItemDTO>
config?: FindConfig<ReservationItemDTO>,
context?: SharedContext
): Promise<[ReservationItemDTO[], number]>

listInventoryLevels(
selector: FilterableInventoryLevelProps,
config?: FindConfig<InventoryLevelDTO>
config?: FindConfig<InventoryLevelDTO>,
context?: SharedContext
): Promise<[InventoryLevelDTO[], number]>

retrieveInventoryItem(
inventoryItemId: string,
config?: FindConfig<InventoryItemDTO>
config?: FindConfig<InventoryItemDTO>,
context?: SharedContext
): Promise<InventoryItemDTO>

retrieveInventoryLevel(
inventoryItemId: string,
locationId: string
locationId: string,
context?: SharedContext
): Promise<InventoryLevelDTO>

retrieveReservationItem(reservationId: string): Promise<ReservationItemDTO>
retrieveReservationItem(
reservationId: string,
context?: SharedContext
): Promise<ReservationItemDTO>

createReservationItem(
input: CreateReservationItemInput
input: CreateReservationItemInput,
context?: SharedContext
): Promise<ReservationItemDTO>

createInventoryItem(
input: CreateInventoryItemInput
input: CreateInventoryItemInput,
context?: SharedContext
): Promise<InventoryItemDTO>

createInventoryLevel(
data: CreateInventoryLevelInput
data: CreateInventoryLevelInput,
context?: SharedContext
): Promise<InventoryLevelDTO>

updateInventoryLevel(
inventoryItemId: string,
locationId: string,
update: UpdateInventoryLevelInput
update: UpdateInventoryLevelInput,
context?: SharedContext
): Promise<InventoryLevelDTO>

updateInventoryItem(
inventoryItemId: string,
input: CreateInventoryItemInput
input: CreateInventoryItemInput,
context?: SharedContext
): Promise<InventoryItemDTO>

updateReservationItem(
reservationItemId: string,
input: UpdateReservationItemInput
input: UpdateReservationItemInput,
context?: SharedContext
): Promise<ReservationItemDTO>

deleteReservationItemsByLineItem(lineItemId: string): Promise<void>
deleteReservationItemsByLineItem(
lineItemId: string,
context?: SharedContext
): Promise<void>

deleteReservationItem(reservationItemId: string | string[]): Promise<void>
deleteReservationItem(
reservationItemId: string | string[],
context?: SharedContext
): Promise<void>

deleteInventoryItem(inventoryItemId: string): Promise<void>
deleteInventoryItem(
inventoryItemId: string,
context?: SharedContext
): Promise<void>

deleteInventoryItemLevelByLocationId(locationId: string): Promise<void>
deleteInventoryItemLevelByLocationId(
locationId: string,
context?: SharedContext
): Promise<void>

deleteReservationItemByLocationId(locationId: string): Promise<void>
deleteReservationItemByLocationId(
locationId: string,
context?: SharedContext
): Promise<void>

deleteInventoryLevel(
inventoryLevelId: string,
locationId: string
locationId: string,
context?: SharedContext
): Promise<void>

adjustInventory(
inventoryItemId: string,
locationId: string,
adjustment: number
adjustment: number,
context?: SharedContext
): Promise<InventoryLevelDTO>

confirmInventory(
inventoryItemId: string,
locationIds: string[],
quantity: number
quantity: number,
context?: SharedContext
): Promise<boolean>

retrieveAvailableQuantity(
inventoryItemId: string,
locationIds: string[]
locationIds: string[],
context?: SharedContext
): Promise<number>

retrieveStockedQuantity(
inventoryItemId: string,
locationIds: string[]
locationIds: string[],
context?: SharedContext
): Promise<number>

retrieveReservedQuantity(
inventoryItemId: string,
locationIds: string[]
locationIds: string[],
context?: SharedContext
): Promise<number>
}
Loading

0 comments on commit 409813e

Please sign in to comment.