feat(medusa): Add purchasable prop on variants when setting availability (#3811)

* write integration tests

* update variant inventory decorator

* update types

* add changeset

* feedback comments

* add yaml schemas

* different oas approach

* pr feedback

* update oas

---------

Co-authored-by: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
Philip Korsholm
2023-04-20 08:54:26 +02:00
committed by GitHub
parent 7d1a78a84f
commit 2be144ff05
27 changed files with 395 additions and 70 deletions

View File

@@ -50,6 +50,7 @@ describe("Create Variant", () => {
describe("list-products", () => {
const productId = "test-product"
const variantId = "test-variant"
let sc2
beforeEach(async () => {
await adminSeeder(dbConnection)
@@ -66,13 +67,14 @@ describe("Create Variant", () => {
dbConnection,
{
id: productId,
status: "published",
variants: [{ id: variantId }],
},
100
)
const sc1 = await simpleSalesChannelFactory(dbConnection, {})
const sc2 = await simpleSalesChannelFactory(dbConnection, {})
sc2 = await simpleSalesChannelFactory(dbConnection, {})
const sc3 = await simpleSalesChannelFactory(dbConnection, {})
const sl1 = await stockLocationService.create({ name: "sl1" })
@@ -120,5 +122,203 @@ describe("Create Variant", () => {
}),
])
})
describe("/store/products", () => {
beforeEach(async () => {
const inventoryService = appContainer.resolve("inventoryService")
const productVariantInventoryService = appContainer.resolve(
"productVariantInventoryService"
)
await simpleProductFactory(
dbConnection,
{
id: `${productId}-1`,
status: "published",
variants: [
{
id: `${variantId}-1`,
manage_inventory: false,
},
],
},
101
)
await simpleProductFactory(
dbConnection,
{
id: `${productId}-2`,
status: "published",
variants: [{ id: `${variantId}-2`, manage_inventory: true }],
},
102
)
await simpleProductFactory(
dbConnection,
{
id: `${productId}-3`,
status: "published",
variants: [
{
id: `${variantId}-3`,
manage_inventory: true,
allow_backorder: true,
},
],
},
103
)
const invItem = await inventoryService.createInventoryItem({
sku: "test-sku-1",
})
await productVariantInventoryService.attachInventoryItem(
`${variantId}-3`,
invItem.id
)
await simpleProductFactory(
dbConnection,
{
id: `${productId}-4`,
status: "published",
variants: [
{
id: `${variantId}-4`,
manage_inventory: true,
allow_backorder: false,
},
],
},
104
)
const invItem1 = await inventoryService.createInventoryItem({
sku: "test-sku-2",
})
await productVariantInventoryService.attachInventoryItem(
`${variantId}-4`,
invItem1.id
)
})
it("lists location availability correctly for store", async () => {
const api = useApi()
const res = await api.get(`/store/products`)
expect(res.status).toEqual(200)
expect(res.data.products).toEqual([
expect.objectContaining({
id: `${productId}-4`,
variants: [
expect.objectContaining({
purchasable: false,
}),
],
}),
expect.objectContaining({
id: `${productId}-3`,
variants: [
expect.objectContaining({
purchasable: false,
}),
],
}),
expect.objectContaining({
id: `${productId}-2`,
variants: [
expect.objectContaining({
purchasable: true,
}),
],
}),
expect.objectContaining({
id: `${productId}-1`,
variants: [
expect.objectContaining({
inventory_quantity: 10,
purchasable: true,
}),
],
}),
expect.objectContaining({
id: productId,
variants: [
expect.objectContaining({
purchasable: false,
}),
],
}),
])
})
it("lists location availability correctly for store with sales channel id", async () => {
const api = useApi()
const productService = appContainer.resolve("productService")
const ids = [
`${productId}`,
`${productId}-1`,
`${productId}-2`,
`${productId}-3`,
`${productId}-4`,
]
for (const id of ids) {
await productService.update(id, {
sales_channels: [{ id: sc2.id }],
})
}
const res = await api.get(
`/store/products?sales_channel_id[]=${sc2.id}`
)
expect(res.status).toEqual(200)
expect(res.data.products).toEqual([
expect.objectContaining({
id: `${productId}-4`,
variants: [
expect.objectContaining({
purchasable: false,
}),
],
}),
expect.objectContaining({
id: `${productId}-3`,
variants: [
expect.objectContaining({
purchasable: true,
}),
],
}),
expect.objectContaining({
id: `${productId}-2`,
variants: [
expect.objectContaining({
purchasable: true,
}),
],
}),
expect.objectContaining({
id: `${productId}-1`,
variants: [
expect.objectContaining({
inventory_quantity: 10,
purchasable: true,
}),
],
}),
expect.objectContaining({
id: productId,
variants: [
expect.objectContaining({
purchasable: true,
inventory_quantity: 4,
}),
],
}),
])
})
})
})
})

View File

@@ -1,14 +1,15 @@
import { Product, ProductOption, ProductStatus, ProductType, ShippingProfile, ShippingProfileType, } from "@medusajs/medusa"
import { ProductVariantFactoryData, simpleProductVariantFactory, } from "./simple-product-variant-factory"
import { Connection } from "typeorm"
import faker from "faker"
import { Product, ProductOption, ProductType, ShippingProfile, ShippingProfileType, } from "@medusajs/medusa"
import { ProductVariantFactoryData, simpleProductVariantFactory, } from "./simple-product-variant-factory"
export type ProductFactoryData = {
id?: string
is_giftcard?: boolean
title?: string
type?: string
status?: ProductStatus
options?: { id: string; title: string }[]
variants?: ProductVariantFactoryData[]
}
@@ -45,6 +46,7 @@ export const simpleProductFactory = async (
const toSave = manager.create(Product, {
id: prodId,
type_id: typeId,
status: data.status || ProductStatus.DRAFT,
title: data.title || faker.commerce.productName(),
is_giftcard: data.is_giftcard || false,
discountable: !data.is_giftcard,

View File

@@ -1,17 +1,20 @@
import { Connection } from "typeorm"
import faker from "faker"
import {
MoneyAmount,
ProductOptionValue,
ProductVariant,
MoneyAmount,
} from "@medusajs/medusa"
import { Connection } from "typeorm"
import faker from "faker"
export type ProductVariantFactoryData = {
product_id: string
id?: string
is_giftcard?: boolean
inventory_quantity?: number
title?: string
allow_backorder?: boolean
manage_inventory?: boolean
options?: { option_id: string; value: string }[]
prices?: { currency: string; amount: number }[]
}
@@ -31,6 +34,8 @@ export const simpleProductVariantFactory = async (
const toSave = manager.create(ProductVariant, {
id,
product_id: data.product_id,
allow_backorder: data.allow_backorder || false,
manage_inventory: typeof data.manage_inventory !== 'undefined' ? data.manage_inventory : true,
inventory_quantity:
typeof data.inventory_quantity !== "undefined"
? data.inventory_quantity