feat(core-flows,dashboard,types,fulfillment,medusa): uses requires shipping throughout lifecycle (#9170)

what:

- uses requires shipping throughout lifecycle

https://github.com/user-attachments/assets/d5ba89d3-5ea0-49c4-b2d5-490c4764933e
This commit is contained in:
Riqwan Thamir
2024-09-24 10:26:22 +02:00
committed by GitHub
parent e54b339324
commit 69f6645716
22 changed files with 490 additions and 108 deletions

View File

@@ -1,10 +1,30 @@
import {
AdminInventoryItem,
AdminProduct,
AdminStockLocation,
MedusaContainer,
} from "@medusajs/types"
import {
adminHeaders,
generatePublishableKey,
generateStoreHeaders,
} from "../../../helpers/create-admin-user"
export async function createOrderSeeder({ api, container }) {
export async function createOrderSeeder({
api,
container,
productOverride,
additionalProducts,
stockChannelOverride,
inventoryItemOverride,
}: {
api: any
container: MedusaContainer
productOverride?: AdminProduct
stockChannelOverride?: AdminStockLocation
additionalProducts?: AdminProduct[]
inventoryItemOverride?: AdminInventoryItem
}) {
const publishableKey = await generatePublishableKey(container)
const storeHeaders = generateStoreHeaders({ publishableKey })
@@ -24,21 +44,25 @@ export async function createOrderSeeder({ api, container }) {
)
).data.sales_channel
const stockLocation = (
await api.post(
`/admin/stock-locations`,
{ name: "test location" },
adminHeaders
)
).data.stock_location
const stockLocation =
stockChannelOverride ??
(
await api.post(
`/admin/stock-locations`,
{ name: "test location" },
adminHeaders
)
).data.stock_location
const inventoryItem = (
await api.post(
`/admin/inventory-items`,
{ sku: "test-variant" },
adminHeaders
)
).data.inventory_item
const inventoryItem =
inventoryItemOverride ??
(
await api.post(
`/admin/inventory-items`,
{ sku: "test-variant" },
adminHeaders
)
).data.inventory_item
await api.post(
`/admin/inventory-items/${inventoryItem.id}/location-levels`,
@@ -63,41 +87,43 @@ export async function createOrderSeeder({ api, container }) {
)
).data.shipping_profile
const product = (
await api.post(
"/admin/products",
{
title: `Test fixture ${shippingProfile.id}`,
options: [
{ title: "size", values: ["large", "small"] },
{ title: "color", values: ["green"] },
],
variants: [
{
title: "Test variant",
sku: "test-variant",
inventory_items: [
{
inventory_item_id: inventoryItem.id,
required_quantity: 1,
const product =
productOverride ??
(
await api.post(
"/admin/products",
{
title: `Test fixture ${shippingProfile.id}`,
options: [
{ title: "size", values: ["large", "small"] },
{ title: "color", values: ["green"] },
],
variants: [
{
title: "Test variant",
sku: "test-variant",
inventory_items: [
{
inventory_item_id: inventoryItem.id,
required_quantity: 1,
},
],
prices: [
{
currency_code: "usd",
amount: 100,
},
],
options: {
size: "large",
color: "green",
},
],
prices: [
{
currency_code: "usd",
amount: 100,
},
],
options: {
size: "large",
color: "green",
},
},
],
},
adminHeaders
)
).data.product
],
},
adminHeaders
)
).data.product
const fulfillmentSets = (
await api.post(
@@ -167,7 +193,13 @@ export async function createOrderSeeder({ api, container }) {
postal_code: "94016",
},
sales_channel_id: salesChannel.id,
items: [{ quantity: 1, variant_id: product.variants[0].id }],
items: [
{ quantity: 1, variant_id: product.variants[0].id },
...(additionalProducts || []).map((p) => ({
quantity: 1,
variant_id: p.variants?.[0]?.id,
})),
],
},
storeHeaders
)

View File

@@ -18,13 +18,192 @@ medusaIntegrationTestRunner({
await setupTaxStructure(container.resolve(ModuleRegistrationName.TAX))
await createAdminUser(dbConnection, adminHeaders, container)
seeder = await createOrderSeeder({ api, container })
order = seeder.order
order = (await api.get(`/admin/orders/${order.id}`, adminHeaders)).data
.order
})
describe("POST /orders/:id/fulfillments", () => {
beforeEach(async () => {
const stockChannelOverride = (
await api.post(
`/admin/stock-locations`,
{ name: "test location" },
adminHeaders
)
).data.stock_location
const inventoryItemOverride = (
await api.post(
`/admin/inventory-items`,
{ sku: "test-variant", requires_shipping: true },
adminHeaders
)
).data.inventory_item
const productOverride = (
await api.post(
"/admin/products",
{
title: `Test fixture`,
options: [
{ title: "size", values: ["large", "small"] },
{ title: "color", values: ["green"] },
],
variants: [
{
title: "Test variant",
sku: "test-variant",
inventory_items: [
{
inventory_item_id: inventoryItemOverride.id,
required_quantity: 1,
},
],
prices: [
{
currency_code: "usd",
amount: 100,
},
],
options: {
size: "large",
color: "green",
},
},
],
},
adminHeaders
)
).data.product
const inventoryItemOverride2 = (
await api.post(
`/admin/inventory-items`,
{ sku: "test-variant-2", requires_shipping: false },
adminHeaders
)
).data.inventory_item
await api.post(
`/admin/inventory-items/${inventoryItemOverride2.id}/location-levels`,
{
location_id: stockChannelOverride.id,
stocked_quantity: 10,
},
adminHeaders
)
const productOverride2 = (
await api.post(
"/admin/products",
{
title: `Test fixture 2`,
options: [
{ title: "size", values: ["large", "small"] },
{ title: "color", values: ["green"] },
],
variants: [
{
title: "Test variant 2",
sku: "test-variant-2",
inventory_items: [
{
inventory_item_id: inventoryItemOverride2.id,
required_quantity: 1,
},
],
prices: [
{
currency_code: "usd",
amount: 100,
},
],
options: {
size: "large",
color: "green",
},
},
],
},
adminHeaders
)
).data.product
seeder = await createOrderSeeder({
api,
container: getContainer(),
productOverride,
additionalProducts: [productOverride2],
stockChannelOverride,
inventoryItemOverride,
})
order = seeder.order
order = (await api.get(`/admin/orders/${order.id}`, adminHeaders)).data
.order
})
it("should only create fulfillments grouped by shipping requirement", async () => {
const {
response: { data },
} = await api
.post(
`/admin/orders/${order.id}/fulfillments`,
{
location_id: seeder.stockLocation.id,
items: [
{
id: order.items[0].id,
quantity: 1,
},
{
id: order.items[1].id,
quantity: 1,
},
],
},
adminHeaders
)
.catch((e) => e)
expect(data).toEqual({
type: "invalid_data",
message: `Fulfillment can only be created entirely with items with shipping or items without shipping. Split this request into 2 fulfillments.`,
})
const {
data: { order: fulfillableOrder },
} = await api.post(
`/admin/orders/${order.id}/fulfillments?fields=+fulfillments.id,fulfillments.requires_shipping`,
{
location_id: seeder.stockLocation.id,
items: [{ id: order.items[0].id, quantity: 1 }],
},
adminHeaders
)
expect(fulfillableOrder.fulfillments).toHaveLength(1)
const {
data: { order: fulfillableOrder2 },
} = await api.post(
`/admin/orders/${order.id}/fulfillments?fields=+fulfillments.id,fulfillments.requires_shipping`,
{
location_id: seeder.stockLocation.id,
items: [{ id: order.items[1].id, quantity: 1 }],
},
adminHeaders
)
expect(fulfillableOrder2.fulfillments).toHaveLength(2)
})
})
describe("POST /orders/:id/fulfillments/:id/mark-as-delivered", () => {
beforeEach(async () => {
seeder = await createOrderSeeder({ api, container: getContainer() })
order = seeder.order
order = (await api.get(`/admin/orders/${order.id}`, adminHeaders)).data
.order
})
it("should mark fulfillable item as delivered", async () => {
let fulfillableItem = order.items.find(
(item) => item.detail.fulfilled_quantity < item.detail.quantity