feat: Add support for setting sales channel when creating a product (#6986)
This commit is contained in:
@@ -9,7 +9,6 @@ const {
|
|||||||
createVariantPriceSet,
|
createVariantPriceSet,
|
||||||
} = require("../../../modules/helpers/create-variant-price-set")
|
} = require("../../../modules/helpers/create-variant-price-set")
|
||||||
const { PriceListStatus, PriceListType } = require("@medusajs/types")
|
const { PriceListStatus, PriceListType } = require("@medusajs/types")
|
||||||
const { ContainerRegistrationKeys } = require("@medusajs/utils")
|
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ProductOptionValue,
|
ProductOptionValue,
|
||||||
@@ -85,12 +84,9 @@ medusaIntegrationTestRunner({
|
|||||||
let publishedCollection
|
let publishedCollection
|
||||||
|
|
||||||
let baseType
|
let baseType
|
||||||
|
|
||||||
let baseRegion
|
let baseRegion
|
||||||
|
|
||||||
let pricingService
|
let pricingService
|
||||||
let scService
|
|
||||||
let remoteLink
|
|
||||||
let container
|
let container
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
@@ -219,20 +215,10 @@ medusaIntegrationTestRunner({
|
|||||||
await api.delete(`/admin/products/${deletedProduct.id}`, adminHeaders)
|
await api.delete(`/admin/products/${deletedProduct.id}`, adminHeaders)
|
||||||
|
|
||||||
pricingService = container.resolve(ModuleRegistrationName.PRICING)
|
pricingService = container.resolve(ModuleRegistrationName.PRICING)
|
||||||
scService = container.resolve(ModuleRegistrationName.SALES_CHANNEL)
|
|
||||||
remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("/admin/products", () => {
|
describe("/admin/products", () => {
|
||||||
describe("GET /admin/products", () => {
|
describe("GET /admin/products", () => {
|
||||||
beforeEach(async () => {
|
|
||||||
await simpleSalesChannelFactory(dbConnection, {
|
|
||||||
name: "Default channel",
|
|
||||||
id: "default-channel",
|
|
||||||
is_default: true,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it("returns a list of products with all statuses when no status or invalid status is provided", async () => {
|
it("returns a list of products with all statuses when no status or invalid status is provided", async () => {
|
||||||
const res = await api
|
const res = await api
|
||||||
.get("/admin/products", adminHeaders)
|
.get("/admin/products", adminHeaders)
|
||||||
@@ -1057,7 +1043,7 @@ medusaIntegrationTestRunner({
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("should return products filtered by sales_channel_id", async () => {
|
it("should return products filtered by sales_channel_id", async () => {
|
||||||
const { salesChannel } = await breaking(
|
const [productId, salesChannelId] = await breaking(
|
||||||
async () => {
|
async () => {
|
||||||
const salesChannel = await simpleSalesChannelFactory(
|
const salesChannel = await simpleSalesChannelFactory(
|
||||||
dbConnection,
|
dbConnection,
|
||||||
@@ -1068,29 +1054,34 @@ medusaIntegrationTestRunner({
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
return { salesChannel }
|
return [baseProduct.id, salesChannel.id]
|
||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
const salesChannel = await scService.create({
|
const salesChannel = await simpleSalesChannelFactory(
|
||||||
name: "Test channel",
|
dbConnection,
|
||||||
description: "Lorem Ipsum",
|
{
|
||||||
})
|
name: "test name",
|
||||||
|
description: "test description",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
await remoteLink.create({
|
// Currently the product update doesn't support managing sales channels
|
||||||
[Modules.PRODUCT]: {
|
const newProduct = (
|
||||||
product_id: baseProduct.id,
|
await api.post(
|
||||||
},
|
"/admin/products",
|
||||||
[Modules.SALES_CHANNEL]: {
|
getProductFixture({
|
||||||
sales_channel_id: salesChannel.id,
|
title: "Test saleschannel",
|
||||||
},
|
sales_channels: [{ id: salesChannel.id }],
|
||||||
})
|
}),
|
||||||
|
adminHeaders
|
||||||
return { salesChannel }
|
)
|
||||||
|
).data.product
|
||||||
|
return [newProduct.id, salesChannel.id]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const res = await api.get(
|
const res = await api.get(
|
||||||
`/admin/products?sales_channel_id[]=${salesChannel.id}`,
|
`/admin/products?sales_channel_id[]=${salesChannelId}`,
|
||||||
adminHeaders
|
adminHeaders
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1098,8 +1089,7 @@ medusaIntegrationTestRunner({
|
|||||||
expect(res.data.products.length).toEqual(1)
|
expect(res.data.products.length).toEqual(1)
|
||||||
expect(res.data.products).toEqual([
|
expect(res.data.products).toEqual([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: baseProduct.id,
|
id: productId,
|
||||||
status: "draft",
|
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
@@ -1216,14 +1206,6 @@ medusaIntegrationTestRunner({
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe("POST /admin/products", () => {
|
describe("POST /admin/products", () => {
|
||||||
beforeEach(async () => {
|
|
||||||
await simpleSalesChannelFactory(dbConnection, {
|
|
||||||
name: "Default channel",
|
|
||||||
id: "default-channel",
|
|
||||||
is_default: true,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it("creates a product", async () => {
|
it("creates a product", async () => {
|
||||||
const response = await api
|
const response = await api
|
||||||
.post(
|
.post(
|
||||||
@@ -1957,15 +1939,6 @@ medusaIntegrationTestRunner({
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe("updates a variant's default prices (ignores prices associated with a Price List)", () => {
|
describe("updates a variant's default prices (ignores prices associated with a Price List)", () => {
|
||||||
beforeEach(async () => {
|
|
||||||
// await priceListSeeder(dbConnection)
|
|
||||||
await simpleSalesChannelFactory(dbConnection, {
|
|
||||||
name: "Default channel",
|
|
||||||
id: "default-channel",
|
|
||||||
is_default: true,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it("successfully updates a variant's default prices by changing an existing price (currency_code)", async () => {
|
it("successfully updates a variant's default prices by changing an existing price (currency_code)", async () => {
|
||||||
const data = {
|
const data = {
|
||||||
prices: [
|
prices: [
|
||||||
@@ -2843,14 +2816,6 @@ medusaIntegrationTestRunner({
|
|||||||
|
|
||||||
// TODO: Discuss how this should be handled
|
// TODO: Discuss how this should be handled
|
||||||
describe.skip("GET /admin/products/tag-usage", () => {
|
describe.skip("GET /admin/products/tag-usage", () => {
|
||||||
beforeEach(async () => {
|
|
||||||
await simpleSalesChannelFactory(dbConnection, {
|
|
||||||
name: "Default channel",
|
|
||||||
id: "default-channel",
|
|
||||||
is_default: true,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it("successfully gets the tags usage", async () => {
|
it("successfully gets the tags usage", async () => {
|
||||||
const res = await api
|
const res = await api
|
||||||
.get("/admin/products/tag-usage", adminHeaders)
|
.get("/admin/products/tag-usage", adminHeaders)
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export const removeRemoteLinkStep = createStep(
|
|||||||
)
|
)
|
||||||
await link.delete(grouped)
|
await link.delete(grouped)
|
||||||
|
|
||||||
return new StepResponse(void 0, grouped)
|
return new StepResponse(grouped, grouped)
|
||||||
},
|
},
|
||||||
async (removedLinks, { container }) => {
|
async (removedLinks, { container }) => {
|
||||||
if (!removedLinks) {
|
if (!removedLinks) {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ export * from "./update-products"
|
|||||||
export * from "./delete-products"
|
export * from "./delete-products"
|
||||||
export * from "./get-products"
|
export * from "./get-products"
|
||||||
export * from "./create-variant-pricing-link"
|
export * from "./create-variant-pricing-link"
|
||||||
export * from "./remove-variant-pricing-link"
|
|
||||||
export * from "./create-product-options"
|
export * from "./create-product-options"
|
||||||
export * from "./update-product-options"
|
export * from "./update-product-options"
|
||||||
export * from "./delete-product-options"
|
export * from "./delete-product-options"
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
import { Modules } from "@medusajs/modules-sdk"
|
|
||||||
import { ContainerRegistrationKeys } from "@medusajs/utils"
|
|
||||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
|
||||||
|
|
||||||
type StepInput = {
|
|
||||||
variant_ids: string[]
|
|
||||||
}
|
|
||||||
|
|
||||||
export const removeVariantPricingLinkStepId = "remove-variant-pricing-link"
|
|
||||||
export const removeVariantPricingLinkStep = createStep(
|
|
||||||
removeVariantPricingLinkStepId,
|
|
||||||
async (data: StepInput, { container }) => {
|
|
||||||
if (!data.variant_ids.length) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
|
||||||
await remoteLink.delete({
|
|
||||||
[Modules.PRODUCT]: { variant_id: data.variant_ids },
|
|
||||||
})
|
|
||||||
return new StepResponse(void 0, data.variant_ids)
|
|
||||||
},
|
|
||||||
async (prevData, { container }) => {
|
|
||||||
if (!prevData?.length) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
|
||||||
await remoteLink.restore({
|
|
||||||
[Modules.PRODUCT]: { variant_id: prevData },
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
@@ -6,11 +6,13 @@ import {
|
|||||||
} from "@medusajs/workflows-sdk"
|
} from "@medusajs/workflows-sdk"
|
||||||
import { createProductsStep, createVariantPricingLinkStep } from "../steps"
|
import { createProductsStep, createVariantPricingLinkStep } from "../steps"
|
||||||
import { createPriceSetsStep } from "../../pricing"
|
import { createPriceSetsStep } from "../../pricing"
|
||||||
|
import { associateProductsWithSalesChannelsStep } from "../../sales-channel"
|
||||||
|
|
||||||
// TODO: We should have separate types here as input, not the module DTO. Eg. the HTTP request that we are handling
|
// TODO: We should have separate types here as input, not the module DTO. Eg. the HTTP request that we are handling
|
||||||
// has different data than the DTO, so that needs to be represented differently.
|
// has different data than the DTO, so that needs to be represented differently.
|
||||||
type WorkflowInput = {
|
type WorkflowInput = {
|
||||||
products: (Omit<ProductTypes.CreateProductDTO, "variants"> & {
|
products: (Omit<ProductTypes.CreateProductDTO, "variants"> & {
|
||||||
|
sales_channels?: { id: string }[]
|
||||||
variants?: (ProductTypes.CreateProductVariantDTO & {
|
variants?: (ProductTypes.CreateProductVariantDTO & {
|
||||||
prices?: PricingTypes.CreateMoneyAmountDTO[]
|
prices?: PricingTypes.CreateMoneyAmountDTO[]
|
||||||
})[]
|
})[]
|
||||||
@@ -24,9 +26,10 @@ export const createProductsWorkflow = createWorkflow(
|
|||||||
input: WorkflowData<WorkflowInput>
|
input: WorkflowData<WorkflowInput>
|
||||||
): WorkflowData<ProductTypes.ProductDTO[]> => {
|
): WorkflowData<ProductTypes.ProductDTO[]> => {
|
||||||
// Passing prices to the product module will fail, we want to keep them for after the product is created.
|
// Passing prices to the product module will fail, we want to keep them for after the product is created.
|
||||||
const productWithoutPrices = transform({ input }, (data) =>
|
const productWithoutExternalRelations = transform({ input }, (data) =>
|
||||||
data.input.products.map((p) => ({
|
data.input.products.map((p) => ({
|
||||||
...p,
|
...p,
|
||||||
|
sales_channels: undefined,
|
||||||
variants: p.variants?.map((v) => ({
|
variants: p.variants?.map((v) => ({
|
||||||
...v,
|
...v,
|
||||||
prices: undefined,
|
prices: undefined,
|
||||||
@@ -34,7 +37,23 @@ export const createProductsWorkflow = createWorkflow(
|
|||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
|
|
||||||
const createdProducts = createProductsStep(productWithoutPrices)
|
const createdProducts = createProductsStep(productWithoutExternalRelations)
|
||||||
|
|
||||||
|
const salesChannelLinks = transform({ input, createdProducts }, (data) => {
|
||||||
|
return data.createdProducts
|
||||||
|
.map((createdProduct, i) => {
|
||||||
|
const inputProduct = data.input.products[i]
|
||||||
|
return (
|
||||||
|
inputProduct.sales_channels?.map((salesChannel) => ({
|
||||||
|
sales_channel_id: salesChannel.id,
|
||||||
|
product_id: createdProduct.id,
|
||||||
|
})) ?? []
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.flat()
|
||||||
|
})
|
||||||
|
|
||||||
|
associateProductsWithSalesChannelsStep({ links: salesChannelLinks })
|
||||||
|
|
||||||
// Note: We rely on the same order of input and output when creating products here, ensure this always holds true
|
// Note: We rely on the same order of input and output when creating products here, ensure this always holds true
|
||||||
const variantsWithAssociatedPrices = transform(
|
const variantsWithAssociatedPrices = transform(
|
||||||
@@ -83,23 +102,6 @@ export const createProductsWorkflow = createWorkflow(
|
|||||||
|
|
||||||
createVariantPricingLinkStep(variantAndPriceSetLinks)
|
createVariantPricingLinkStep(variantAndPriceSetLinks)
|
||||||
|
|
||||||
// TODO: Should we just refetch the products here?
|
return createdProducts
|
||||||
return transform(
|
|
||||||
{
|
|
||||||
createdProducts,
|
|
||||||
variantAndPriceSets,
|
|
||||||
},
|
|
||||||
(data) => {
|
|
||||||
return data.createdProducts.map((product) => ({
|
|
||||||
...product,
|
|
||||||
variants: product.variants?.map((variant) => ({
|
|
||||||
...variant,
|
|
||||||
price_set: data.variantAndPriceSets.find(
|
|
||||||
(v) => v.variant.id === variant.id
|
|
||||||
)?.price_set,
|
|
||||||
})),
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||||
import {
|
import { Modules } from "@medusajs/modules-sdk"
|
||||||
deleteProductVariantsStep,
|
import { deleteProductVariantsStep } from "../steps"
|
||||||
removeVariantPricingLinkStep,
|
import { removeRemoteLinkStep } from "../../common"
|
||||||
} from "../steps"
|
|
||||||
|
|
||||||
type WorkflowInput = { ids: string[] }
|
type WorkflowInput = { ids: string[] }
|
||||||
|
|
||||||
@@ -10,7 +9,10 @@ export const deleteProductVariantsWorkflowId = "delete-product-variants"
|
|||||||
export const deleteProductVariantsWorkflow = createWorkflow(
|
export const deleteProductVariantsWorkflow = createWorkflow(
|
||||||
deleteProductVariantsWorkflowId,
|
deleteProductVariantsWorkflowId,
|
||||||
(input: WorkflowData<WorkflowInput>): WorkflowData<void> => {
|
(input: WorkflowData<WorkflowInput>): WorkflowData<void> => {
|
||||||
removeVariantPricingLinkStep({ variant_ids: input.ids })
|
removeRemoteLinkStep({
|
||||||
|
[Modules.PRODUCT]: { variant_id: input.ids },
|
||||||
|
}).config({ name: "remove-variant-link-step" })
|
||||||
|
|
||||||
return deleteProductVariantsStep(input.ids)
|
return deleteProductVariantsStep(input.ids)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,11 +3,9 @@ import {
|
|||||||
createWorkflow,
|
createWorkflow,
|
||||||
transform,
|
transform,
|
||||||
} from "@medusajs/workflows-sdk"
|
} from "@medusajs/workflows-sdk"
|
||||||
import {
|
import { Modules } from "@medusajs/modules-sdk"
|
||||||
deleteProductsStep,
|
import { deleteProductsStep, getProductsStep } from "../steps"
|
||||||
getProductsStep,
|
import { removeRemoteLinkStep } from "../../common"
|
||||||
removeVariantPricingLinkStep,
|
|
||||||
} from "../steps"
|
|
||||||
|
|
||||||
type WorkflowInput = { ids: string[] }
|
type WorkflowInput = { ids: string[] }
|
||||||
|
|
||||||
@@ -22,7 +20,14 @@ export const deleteProductsWorkflow = createWorkflow(
|
|||||||
.map((variant) => variant.id)
|
.map((variant) => variant.id)
|
||||||
})
|
})
|
||||||
|
|
||||||
removeVariantPricingLinkStep({ variant_ids: variantsToBeDeleted })
|
removeRemoteLinkStep({
|
||||||
|
[Modules.PRODUCT]: { variant_id: variantsToBeDeleted },
|
||||||
|
}).config({ name: "remove-variant-link-step" })
|
||||||
|
|
||||||
|
removeRemoteLinkStep({
|
||||||
|
[Modules.PRODUCT]: { product_id: input.ids },
|
||||||
|
}).config({ name: "remove-product-link-step" })
|
||||||
|
|
||||||
return deleteProductsStep(input.ids)
|
return deleteProductsStep(input.ids)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export const updateProductsWorkflow = createWorkflow(
|
|||||||
input: WorkflowData<WorkflowInput>
|
input: WorkflowData<WorkflowInput>
|
||||||
): WorkflowData<ProductTypes.ProductDTO[]> => {
|
): WorkflowData<ProductTypes.ProductDTO[]> => {
|
||||||
// TODO: Delete price sets for removed variants
|
// TODO: Delete price sets for removed variants
|
||||||
|
// TODO Update sales channel links
|
||||||
return updateProductsStep(input)
|
return updateProductsStep(input)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
|||||||
interface StepInput {
|
interface StepInput {
|
||||||
links: {
|
links: {
|
||||||
sales_channel_id: string
|
sales_channel_id: string
|
||||||
product_ids: string[]
|
product_id: string
|
||||||
}[]
|
}[]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14,25 +14,23 @@ export const associateProductsWithSalesChannelsStepId =
|
|||||||
export const associateProductsWithSalesChannelsStep = createStep(
|
export const associateProductsWithSalesChannelsStep = createStep(
|
||||||
associateProductsWithSalesChannelsStepId,
|
associateProductsWithSalesChannelsStepId,
|
||||||
async (input: StepInput, { container }) => {
|
async (input: StepInput, { container }) => {
|
||||||
const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
if (!input.links.length) {
|
||||||
|
return new StepResponse([], [])
|
||||||
|
}
|
||||||
|
|
||||||
const links = input.links
|
const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
||||||
.map((link) => {
|
const links = input.links.map((link) => {
|
||||||
return link.product_ids.map((id) => {
|
return {
|
||||||
return {
|
[Modules.PRODUCT]: {
|
||||||
[Modules.PRODUCT]: {
|
product_id: link.product_id,
|
||||||
product_id: id,
|
},
|
||||||
},
|
[Modules.SALES_CHANNEL]: {
|
||||||
[Modules.SALES_CHANNEL]: {
|
sales_channel_id: link.sales_channel_id,
|
||||||
sales_channel_id: link.sales_channel_id,
|
},
|
||||||
},
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
})
|
|
||||||
.flat()
|
|
||||||
|
|
||||||
const createdLinks = await remoteLink.create(links)
|
const createdLinks = await remoteLink.create(links)
|
||||||
|
|
||||||
return new StepResponse(createdLinks, links)
|
return new StepResponse(createdLinks, links)
|
||||||
},
|
},
|
||||||
async (links, { container }) => {
|
async (links, { container }) => {
|
||||||
|
|||||||
+15
-16
@@ -5,7 +5,7 @@ import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
|||||||
interface StepInput {
|
interface StepInput {
|
||||||
links: {
|
links: {
|
||||||
sales_channel_id: string
|
sales_channel_id: string
|
||||||
product_ids: string[]
|
product_id: string
|
||||||
}[]
|
}[]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14,22 +14,21 @@ export const detachProductsFromSalesChannelsStepId =
|
|||||||
export const detachProductsFromSalesChannelsStep = createStep(
|
export const detachProductsFromSalesChannelsStep = createStep(
|
||||||
detachProductsFromSalesChannelsStepId,
|
detachProductsFromSalesChannelsStepId,
|
||||||
async (input: StepInput, { container }) => {
|
async (input: StepInput, { container }) => {
|
||||||
const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
if (!input.links.length) {
|
||||||
|
return new StepResponse(void 0, [])
|
||||||
|
}
|
||||||
|
|
||||||
const links = input.links
|
const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
||||||
.map((link) => {
|
const links = input.links.map((link) => {
|
||||||
return link.product_ids.map((id) => {
|
return {
|
||||||
return {
|
[Modules.PRODUCT]: {
|
||||||
[Modules.PRODUCT]: {
|
product_id: link.product_id,
|
||||||
product_id: id,
|
},
|
||||||
},
|
[Modules.SALES_CHANNEL]: {
|
||||||
[Modules.SALES_CHANNEL]: {
|
sales_channel_id: link.sales_channel_id,
|
||||||
sales_channel_id: link.sales_channel_id,
|
},
|
||||||
},
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
})
|
|
||||||
.flat()
|
|
||||||
|
|
||||||
await remoteLink.dismiss(links)
|
await remoteLink.dismiss(links)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { SalesChannelDTO } from "@medusajs/types"
|
import { SalesChannelDTO } from "@medusajs/types"
|
||||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||||
import { associateProductsWithSalesChannelsStep } from "../steps/associate-products-with-channels"
|
import { associateProductsWithSalesChannelsStep } from "../steps/associate-products-with-channels"
|
||||||
|
import { transform } from "@medusajs/workflows-sdk"
|
||||||
|
|
||||||
type WorkflowInput = {
|
type WorkflowInput = {
|
||||||
data: {
|
data: {
|
||||||
@@ -14,6 +15,19 @@ export const addProductsToSalesChannelsWorkflowId =
|
|||||||
export const addProductsToSalesChannelsWorkflow = createWorkflow(
|
export const addProductsToSalesChannelsWorkflow = createWorkflow(
|
||||||
addProductsToSalesChannelsWorkflowId,
|
addProductsToSalesChannelsWorkflowId,
|
||||||
(input: WorkflowData<WorkflowInput>): WorkflowData<SalesChannelDTO[]> => {
|
(input: WorkflowData<WorkflowInput>): WorkflowData<SalesChannelDTO[]> => {
|
||||||
return associateProductsWithSalesChannelsStep({ links: input.data })
|
const links = transform({ input }, (data) => {
|
||||||
|
return data.input.data
|
||||||
|
.map(({ sales_channel_id, product_ids }) => {
|
||||||
|
return product_ids.map((product_id) => {
|
||||||
|
return {
|
||||||
|
sales_channel_id,
|
||||||
|
product_id,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.flat()
|
||||||
|
})
|
||||||
|
|
||||||
|
return associateProductsWithSalesChannelsStep({ links })
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
+15
-1
@@ -1,6 +1,7 @@
|
|||||||
import { SalesChannelDTO } from "@medusajs/types"
|
import { SalesChannelDTO } from "@medusajs/types"
|
||||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||||
import { detachProductsFromSalesChannelsStep } from "../steps/detach-products-from-sales-channels"
|
import { detachProductsFromSalesChannelsStep } from "../steps/detach-products-from-sales-channels"
|
||||||
|
import { transform } from "@medusajs/workflows-sdk"
|
||||||
|
|
||||||
type WorkflowInput = {
|
type WorkflowInput = {
|
||||||
data: {
|
data: {
|
||||||
@@ -14,6 +15,19 @@ export const removeProductsFromSalesChannelsWorkflowId =
|
|||||||
export const removeProductsFromSalesChannelsWorkflow = createWorkflow(
|
export const removeProductsFromSalesChannelsWorkflow = createWorkflow(
|
||||||
removeProductsFromSalesChannelsWorkflowId,
|
removeProductsFromSalesChannelsWorkflowId,
|
||||||
(input: WorkflowData<WorkflowInput>): WorkflowData<SalesChannelDTO[]> => {
|
(input: WorkflowData<WorkflowInput>): WorkflowData<SalesChannelDTO[]> => {
|
||||||
return detachProductsFromSalesChannelsStep({ links: input.data })
|
const links = transform({ input }, (data) => {
|
||||||
|
return data.input.data
|
||||||
|
.map(({ sales_channel_id, product_ids }) => {
|
||||||
|
return product_ids.map((product_id) => {
|
||||||
|
return {
|
||||||
|
sales_channel_id,
|
||||||
|
product_id,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.flat()
|
||||||
|
})
|
||||||
|
|
||||||
|
return detachProductsFromSalesChannelsStep({ links })
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -202,6 +202,7 @@ export const AdminCreateProduct = z
|
|||||||
tags: z.array(AdminUpdateProductTag).optional(),
|
tags: z.array(AdminUpdateProductTag).optional(),
|
||||||
options: z.array(AdminCreateProductOption).optional(),
|
options: z.array(AdminCreateProductOption).optional(),
|
||||||
variants: z.array(AdminCreateProductVariant).optional(),
|
variants: z.array(AdminCreateProductVariant).optional(),
|
||||||
|
sales_channels: z.array(z.object({ id: z.string() })).optional(),
|
||||||
weight: z.number().optional(),
|
weight: z.number().optional(),
|
||||||
length: z.number().optional(),
|
length: z.number().optional(),
|
||||||
height: z.number().optional(),
|
height: z.number().optional(),
|
||||||
@@ -231,12 +232,3 @@ export const AdminUpdateProduct = AdminCreateProduct.omit({ is_giftcard: true })
|
|||||||
// @ValidateNested({ each: true })
|
// @ValidateNested({ each: true })
|
||||||
// @IsArray()
|
// @IsArray()
|
||||||
// categories?: ProductProductCategoryReq[]
|
// categories?: ProductProductCategoryReq[]
|
||||||
|
|
||||||
// TODO: Deal with in next iteration
|
|
||||||
// @FeatureFlagDecorators(SalesChannelFeatureFlag.key, [
|
|
||||||
// IsOptional(),
|
|
||||||
// Type(() => ProductSalesChannelReq),
|
|
||||||
// ValidateNested({ each: true }),
|
|
||||||
// IsArray(),
|
|
||||||
// ])
|
|
||||||
// sales_channels?: ProductSalesChannelReq[]
|
|
||||||
|
|||||||
Reference in New Issue
Block a user