Feat(link-module, core-flows, medusa): Add sales channel location management (#6905)
* add locations with sales channels * init, not working location based management * working adding sales channel stock locations * remote sales channels from location * remove console log * rm allowedFields * redo errorhandler * make validation take an array * add changeset * fix build * Update packages/core-flows/src/sales-channel/workflows/remove-locations-from-sales-channel.ts Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com> * add default cases to return early * cleanup * add sc test and remove associations --------- Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
7
.changeset/shaggy-bobcats-camp.md
Normal file
7
.changeset/shaggy-bobcats-camp.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"@medusajs/link-modules": patch
|
||||
"@medusajs/core-flows": patch
|
||||
"@medusajs/medusa": patch
|
||||
---
|
||||
|
||||
feat(link-modules, core-flows, medusa): add sales channel location management endpoint
|
||||
@@ -1,6 +1,9 @@
|
||||
const { ModuleRegistrationName, Modules } = require("@medusajs/modules-sdk")
|
||||
const { medusaIntegrationTestRunner } = require("medusa-test-utils")
|
||||
const { createAdminUser } = require("../../../helpers/create-admin-user")
|
||||
const {
|
||||
createAdminUser,
|
||||
adminHeaders,
|
||||
} = require("../../../helpers/create-admin-user")
|
||||
const { breaking } = require("../../../helpers/breaking")
|
||||
const { ContainerRegistrationKeys } = require("@medusajs/utils")
|
||||
|
||||
@@ -345,7 +348,7 @@ medusaIntegrationTestRunner({
|
||||
})
|
||||
|
||||
it("should delete the requested sales channel", async () => {
|
||||
let toDelete = await breaking(
|
||||
const toDelete = await breaking(
|
||||
async () => {
|
||||
return await dbConnection.manager.findOne(SalesChannel, {
|
||||
where: { id: salesChannel.id },
|
||||
@@ -403,6 +406,48 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it("should successfully delete channel associations", async () => {
|
||||
await breaking(null, async () => {
|
||||
const remoteLink = container.resolve(
|
||||
ContainerRegistrationKeys.REMOTE_LINK
|
||||
)
|
||||
|
||||
console.warn("testing")
|
||||
await remoteLink.create([
|
||||
{
|
||||
[Modules.SALES_CHANNEL]: {
|
||||
sales_channel_id: "test-channel",
|
||||
},
|
||||
[Modules.STOCK_LOCATION]: {
|
||||
stock_location_id: "test-location",
|
||||
},
|
||||
},
|
||||
{
|
||||
[Modules.SALES_CHANNEL]: {
|
||||
sales_channel_id: "test-channel-default",
|
||||
},
|
||||
[Modules.STOCK_LOCATION]: {
|
||||
stock_location_id: "test-location",
|
||||
},
|
||||
},
|
||||
])
|
||||
|
||||
await api
|
||||
.delete(`/admin/sales-channels/test-channel`, adminReqConfig)
|
||||
.catch(console.log)
|
||||
|
||||
const linkService = remoteLink.getLinkModule(
|
||||
Modules.SALES_CHANNEL,
|
||||
"sales_channel_id",
|
||||
Modules.STOCK_LOCATION,
|
||||
"stock_location_id"
|
||||
)
|
||||
|
||||
const channelLinks = await linkService.list()
|
||||
expect(channelLinks).toHaveLength(1)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("GET /admin/orders/:id", () => {
|
||||
|
||||
@@ -279,5 +279,100 @@ medusaIntegrationTestRunner({
|
||||
expect(stockLocationLinks).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
describe("Add sales channels", () => {
|
||||
let salesChannel
|
||||
let location
|
||||
|
||||
beforeEach(async () => {
|
||||
const salesChannelResponse = await api.post(
|
||||
"/admin/sales-channels",
|
||||
{
|
||||
name: "test name",
|
||||
description: "test description",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
salesChannel = salesChannelResponse.data.sales_channel
|
||||
|
||||
const locationResponse = await api.post(
|
||||
"/admin/stock-locations",
|
||||
{
|
||||
name: "test location",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
location = locationResponse.data.stock_location
|
||||
})
|
||||
|
||||
it("should add sales channels to a location", async () => {
|
||||
const salesChannelResponse = await api.post(
|
||||
`/admin/stock-locations/${location.id}/sales-channels/batch/add?fields=*sales_channels`,
|
||||
{ sales_channel_ids: [salesChannel.id] },
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(
|
||||
salesChannelResponse.data.stock_location.sales_channels
|
||||
).toHaveLength(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe("Remove sales channels", () => {
|
||||
let salesChannel1
|
||||
let salesChannel2
|
||||
let location
|
||||
|
||||
beforeEach(async () => {
|
||||
const salesChannelResponse1 = await api.post(
|
||||
"/admin/sales-channels",
|
||||
{
|
||||
name: "test name",
|
||||
description: "test description",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
salesChannel1 = salesChannelResponse1.data.sales_channel
|
||||
|
||||
const salesChannelResponse2 = await api.post(
|
||||
"/admin/sales-channels",
|
||||
{
|
||||
name: "test name",
|
||||
description: "test description",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
salesChannel2 = salesChannelResponse2.data.sales_channel
|
||||
|
||||
const locationResponse = await api.post(
|
||||
"/admin/stock-locations",
|
||||
{
|
||||
name: "test location",
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
location = locationResponse.data.stock_location
|
||||
|
||||
await api.post(
|
||||
`/admin/stock-locations/${location.id}/sales-channels/batch/add?fields=*sales_channels`,
|
||||
{ sales_channel_ids: [salesChannel1.id, salesChannel2.id] },
|
||||
adminHeaders
|
||||
)
|
||||
})
|
||||
|
||||
it("should remove sales channels from a location", async () => {
|
||||
const salesChannelResponse = await api.post(
|
||||
`/admin/stock-locations/${location.id}/sales-channels/batch/remove?fields=*sales_channels`,
|
||||
{ sales_channel_ids: [salesChannel1.id] },
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(
|
||||
salesChannelResponse.data.stock_location.sales_channels
|
||||
).toHaveLength(1)
|
||||
})
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
import { ContainerRegistrationKeys } from "@medusajs/utils"
|
||||
import { Modules } from "@medusajs/modules-sdk"
|
||||
|
||||
interface StepInput {
|
||||
links: {
|
||||
sales_channel_id: string
|
||||
location_ids: string[]
|
||||
}[]
|
||||
}
|
||||
|
||||
export const associateLocationsWithChannelStepId =
|
||||
"associate-locations-with-channel-step"
|
||||
export const associateLocationsWithChannelStep = createStep(
|
||||
associateLocationsWithChannelStepId,
|
||||
async (data: StepInput, { container }) => {
|
||||
if (!data.links.length) {
|
||||
return new StepResponse([], [])
|
||||
}
|
||||
|
||||
const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
||||
|
||||
const links = data.links
|
||||
.map((link) => {
|
||||
return link.location_ids.map((id) => {
|
||||
return {
|
||||
[Modules.SALES_CHANNEL]: {
|
||||
sales_channel_id: link.sales_channel_id,
|
||||
},
|
||||
[Modules.STOCK_LOCATION]: {
|
||||
stock_location_id: id,
|
||||
},
|
||||
}
|
||||
})
|
||||
})
|
||||
.flat()
|
||||
|
||||
const createdLinks = await remoteLink.create(links)
|
||||
|
||||
return new StepResponse(createdLinks, links)
|
||||
},
|
||||
async (links, { container }) => {
|
||||
if (!links?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const remoteLink = container.resolve(ContainerRegistrationKeys.REMOTE_LINK)
|
||||
|
||||
await remoteLink.dismiss(links)
|
||||
}
|
||||
)
|
||||
@@ -4,4 +4,5 @@ export * from "./create-sales-channels"
|
||||
export * from "./delete-sales-channels"
|
||||
export * from "./detach-products-from-sales-channels"
|
||||
export * from "./update-sales-channels"
|
||||
|
||||
export * from "./associate-locations-with-channel"
|
||||
export * from "./remove-locations-from-channels"
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import { Modules, RemoteLink } from "@medusajs/modules-sdk"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
import { ContainerRegistrationKeys } from "@medusajs/utils"
|
||||
|
||||
export const removeLocationsFromSalesChannelStepId =
|
||||
"remove-locations-from-sales-channel"
|
||||
export const removeLocationsFromSalesChannelStep = createStep(
|
||||
removeLocationsFromSalesChannelStepId,
|
||||
async (
|
||||
data: {
|
||||
sales_channel_id: string
|
||||
location_ids: string[]
|
||||
}[],
|
||||
{ container }
|
||||
) => {
|
||||
if (!data.length) {
|
||||
return new StepResponse([], [])
|
||||
}
|
||||
|
||||
const remoteLink = container.resolve<RemoteLink>(
|
||||
ContainerRegistrationKeys.REMOTE_LINK
|
||||
)
|
||||
|
||||
const linkModule = remoteLink.getLinkModule(
|
||||
Modules.SALES_CHANNEL,
|
||||
"sales_channel_id",
|
||||
Modules.STOCK_LOCATION,
|
||||
"stock_location_id"
|
||||
)
|
||||
|
||||
if (!linkModule) {
|
||||
return new StepResponse([], [])
|
||||
}
|
||||
|
||||
const links = data
|
||||
.map((d) =>
|
||||
d.location_ids.map((locId) => ({
|
||||
sales_channel_id: d.sales_channel_id,
|
||||
stock_location_id: locId,
|
||||
}))
|
||||
)
|
||||
.flat()
|
||||
|
||||
await linkModule.softDelete(links)
|
||||
|
||||
return new StepResponse(void 0, links)
|
||||
},
|
||||
async (links, { container }) => {
|
||||
if (!links?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const remoteLink = container.resolve<RemoteLink>(
|
||||
ContainerRegistrationKeys.REMOTE_LINK
|
||||
)
|
||||
|
||||
const linkModule = remoteLink.getLinkModule(
|
||||
Modules.SALES_CHANNEL,
|
||||
"sales_channel_id",
|
||||
Modules.STOCK_LOCATION,
|
||||
"stock_location_id"
|
||||
)
|
||||
|
||||
if (!linkModule) {
|
||||
return
|
||||
}
|
||||
|
||||
await linkModule.restore(links)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,20 @@
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
|
||||
import { SalesChannelDTO } from "@medusajs/types"
|
||||
import { associateLocationsWithChannelStep } from "../steps"
|
||||
|
||||
interface WorkflowInput {
|
||||
data: {
|
||||
sales_channel_id: string
|
||||
location_ids: string[]
|
||||
}[]
|
||||
}
|
||||
|
||||
export const addLocationsToSalesChannelWorkflowId =
|
||||
"add-locations-to-sales-channel"
|
||||
export const addLocationsToSalesChannelWorkflow = createWorkflow(
|
||||
addLocationsToSalesChannelWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<SalesChannelDTO[]> => {
|
||||
return associateLocationsWithChannelStep({ links: input.data })
|
||||
}
|
||||
)
|
||||
@@ -1,5 +1,8 @@
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
|
||||
import { Modules } from "@medusajs/modules-sdk"
|
||||
import { deleteSalesChannelsStep } from "../steps/delete-sales-channels"
|
||||
import { removeRemoteLinkStep } from "../../common/steps/remove-remote-links"
|
||||
|
||||
type WorkflowInput = { ids: string[] }
|
||||
|
||||
@@ -7,6 +10,10 @@ export const deleteSalesChannelsWorkflowId = "delete-sales-channels"
|
||||
export const deleteSalesChannelsWorkflow = createWorkflow(
|
||||
deleteSalesChannelsWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<void> => {
|
||||
return deleteSalesChannelsStep(input.ids)
|
||||
deleteSalesChannelsStep(input.ids)
|
||||
|
||||
removeRemoteLinkStep({
|
||||
[Modules.SALES_CHANNEL]: { sales_channel_id: input.ids },
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
@@ -3,4 +3,5 @@ export * from "./create-sales-channels"
|
||||
export * from "./delete-sales-channels"
|
||||
export * from "./remove-products-from-sales-channels"
|
||||
export * from "./update-sales-channels"
|
||||
|
||||
export * from "./add-locations-to-sales-channel"
|
||||
export * from "./remove-locations-from-sales-channel"
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
|
||||
import { removeLocationsFromSalesChannelStep } from "../steps"
|
||||
|
||||
interface WorkflowInput {
|
||||
data: {
|
||||
sales_channel_id: string
|
||||
location_ids: string[]
|
||||
}[]
|
||||
}
|
||||
|
||||
export const removeLocationsFromSalesChannelWorkflowId =
|
||||
"remove-locations-from-sales-channel"
|
||||
export const removeLocationsFromSalesChannelWorkflow = createWorkflow(
|
||||
removeLocationsFromSalesChannelWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<void> => {
|
||||
removeLocationsFromSalesChannelStep(input.data)
|
||||
}
|
||||
)
|
||||
@@ -100,16 +100,19 @@ export default class LinkModuleService<TLink> implements ILinkModule {
|
||||
return this.primaryKey_.concat(this.foreignKey_).includes(name)
|
||||
}
|
||||
|
||||
private validateFields(data: any) {
|
||||
const keys = Object.keys(data)
|
||||
if (!keys.every((k) => this.isValidKeyName(k))) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Invalid field name provided. Valid field names are ${this.primaryKey_.concat(
|
||||
this.foreignKey_
|
||||
)}`
|
||||
)
|
||||
}
|
||||
private validateFields(data: any | any[]) {
|
||||
const dataToValidate = Array.isArray(data) ? data : [data]
|
||||
dataToValidate.forEach((d) => {
|
||||
const keys = Object.keys(d)
|
||||
if (keys.some((k) => !this.isValidKeyName(k))) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Invalid field name provided. Valid field names are ${this.primaryKey_.concat(
|
||||
this.foreignKey_
|
||||
)}`
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@InjectManager("baseRepository_")
|
||||
@@ -276,10 +279,12 @@ export default class LinkModuleService<TLink> implements ILinkModule {
|
||||
{ returnLinkableKeys }: SoftDeleteReturn = {},
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<Record<string, unknown[]> | void> {
|
||||
this.validateFields(data)
|
||||
const inputArray = Array.isArray(data) ? data : [data]
|
||||
|
||||
this.validateFields(inputArray)
|
||||
|
||||
let [deletedEntities, cascadedEntitiesMap] = await this.softDelete_(
|
||||
data,
|
||||
inputArray,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
@@ -324,7 +329,7 @@ export default class LinkModuleService<TLink> implements ILinkModule {
|
||||
|
||||
@InjectTransactionManager(shouldForceTransaction, "baseRepository_")
|
||||
protected async softDelete_(
|
||||
data: any,
|
||||
data: any[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<[object[], Record<string, string[]>]> {
|
||||
return await this.linkService_.softDelete(data, sharedContext)
|
||||
@@ -335,10 +340,11 @@ export default class LinkModuleService<TLink> implements ILinkModule {
|
||||
{ returnLinkableKeys }: RestoreReturn = {},
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<Record<string, unknown[]> | void> {
|
||||
this.validateFields(data)
|
||||
const inputArray = Array.isArray(data) ? data : [data]
|
||||
this.validateFields(inputArray)
|
||||
|
||||
let [restoredEntities, cascadedEntitiesMap] = await this.restore_(
|
||||
data,
|
||||
inputArray,
|
||||
sharedContext
|
||||
)
|
||||
|
||||
|
||||
@@ -87,15 +87,24 @@ export default class LinkService<TEntity> {
|
||||
|
||||
@InjectTransactionManager(doNotForceTransaction, "linkRepository_")
|
||||
async softDelete(
|
||||
data: any,
|
||||
data: any[],
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<[object[], Record<string, string[]>]> {
|
||||
const filter = {}
|
||||
for (const key in data) {
|
||||
filter[key] = { $in: Array.isArray(data[key]) ? data[key] : [data[key]] }
|
||||
const deleteFilters = {
|
||||
$or: data.map((dataEntry) => {
|
||||
const filter = {}
|
||||
for (const key in dataEntry) {
|
||||
filter[key] = {
|
||||
$in: Array.isArray(dataEntry[key])
|
||||
? dataEntry[key]
|
||||
: [dataEntry[key]],
|
||||
}
|
||||
}
|
||||
return filter
|
||||
}),
|
||||
}
|
||||
|
||||
return await this.linkRepository_.softDelete(filter, {
|
||||
return await this.linkRepository_.softDelete(deleteFilters, {
|
||||
transactionManager: sharedContext.transactionManager,
|
||||
})
|
||||
}
|
||||
@@ -105,12 +114,21 @@ export default class LinkService<TEntity> {
|
||||
data: any,
|
||||
@MedusaContext() sharedContext: Context = {}
|
||||
): Promise<[object[], Record<string, string[]>]> {
|
||||
const filter = {}
|
||||
for (const key in data) {
|
||||
filter[key] = { $in: Array.isArray(data[key]) ? data[key] : [data[key]] }
|
||||
const restoreFilters = {
|
||||
$or: data.map((dataEntry) => {
|
||||
const filter = {}
|
||||
for (const key in dataEntry) {
|
||||
filter[key] = {
|
||||
$in: Array.isArray(dataEntry[key])
|
||||
? dataEntry[key]
|
||||
: [dataEntry[key]],
|
||||
}
|
||||
}
|
||||
return filter
|
||||
}),
|
||||
}
|
||||
|
||||
return await this.linkRepository_.restore(data, {
|
||||
return await this.linkRepository_.restore(restoreFilters, {
|
||||
transactionManager: sharedContext.transactionManager,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { removeRulesFromPromotionsWorkflow } from "@medusajs/core-flows"
|
||||
import { RuleType } from "@medusajs/utils"
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../../../../../types/routing"
|
||||
|
||||
import { AdminPostPromotionsPromotionRulesBatchRemoveReq } from "../../../../validators"
|
||||
import { RuleType } from "@medusajs/utils"
|
||||
import { removeRulesFromPromotionsWorkflow } from "@medusajs/core-flows"
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<AdminPostPromotionsPromotionRulesBatchRemoveReq>,
|
||||
|
||||
@@ -25,7 +25,7 @@ export const GET = async (
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "sales_channels",
|
||||
variables,
|
||||
fields: defaultAdminSalesChannelFields,
|
||||
fields: req.remoteQueryConfig.fields,
|
||||
})
|
||||
|
||||
const [sales_channel] = await remoteQuery(queryObject)
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../../../../../types/routing"
|
||||
|
||||
import { AdminStockLocationsLocationSalesChannelBatchReq } from "../../../../validators"
|
||||
import { addLocationsToSalesChannelWorkflow } from "@medusajs/core-flows"
|
||||
|
||||
export const POST = async (
|
||||
req: MedusaRequest<AdminStockLocationsLocationSalesChannelBatchReq>,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const workflowInput = {
|
||||
data: req.validatedBody.sales_channel_ids.map((id) => ({
|
||||
sales_channel_id: id,
|
||||
location_ids: [req.params.id],
|
||||
})),
|
||||
}
|
||||
|
||||
const { errors } = await addLocationsToSalesChannelWorkflow(req.scope).run({
|
||||
input: workflowInput,
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
if (Array.isArray(errors) && errors[0]) {
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "stock_locations",
|
||||
variables: { id: req.params.id },
|
||||
fields: req.remoteQueryConfig.fields,
|
||||
})
|
||||
|
||||
const [stock_location] = await remoteQuery(queryObject)
|
||||
|
||||
res.status(200).json({ stock_location })
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import {
|
||||
ContainerRegistrationKeys,
|
||||
remoteQueryObjectFromString,
|
||||
} from "@medusajs/utils"
|
||||
import {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../../../../../types/routing"
|
||||
|
||||
import { AdminStockLocationsLocationSalesChannelBatchReq } from "../../../../validators"
|
||||
import { removeLocationsFromSalesChannelWorkflow } from "@medusajs/core-flows"
|
||||
|
||||
export const POST = async (
|
||||
req: MedusaRequest<AdminStockLocationsLocationSalesChannelBatchReq>,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const workflowInput = {
|
||||
data: req.validatedBody.sales_channel_ids.map((id) => ({
|
||||
sales_channel_id: id,
|
||||
location_ids: [req.params.id],
|
||||
})),
|
||||
}
|
||||
|
||||
const { errors } = await removeLocationsFromSalesChannelWorkflow(
|
||||
req.scope
|
||||
).run({
|
||||
input: workflowInput,
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
if (Array.isArray(errors) && errors[0]) {
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||
|
||||
const queryObject = remoteQueryObjectFromString({
|
||||
entryPoint: "stock_locations",
|
||||
variables: { id: req.params.id },
|
||||
fields: req.remoteQueryConfig.fields,
|
||||
})
|
||||
|
||||
const [stock_location] = await remoteQuery(queryObject)
|
||||
|
||||
res.status(200).json({ stock_location })
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
AdminPostStockLocationsLocationReq,
|
||||
AdminPostStockLocationsParams,
|
||||
AdminPostStockLocationsReq,
|
||||
AdminStockLocationsLocationSalesChannelBatchReq,
|
||||
} from "./validators"
|
||||
import { transformBody, transformQuery } from "../../../api/middlewares"
|
||||
|
||||
@@ -53,6 +54,17 @@ export const adminStockLocationRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["POST"],
|
||||
matcher: "/admin/stock-locations/:id/sales-channels/batch*",
|
||||
middlewares: [
|
||||
transformBody(AdminStockLocationsLocationSalesChannelBatchReq),
|
||||
transformQuery(
|
||||
AdminPostStockLocationsLocationParams,
|
||||
QueryConfig.retrieveTransformQueryConfig
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["GET"],
|
||||
matcher: "/admin/stock-locations/:id",
|
||||
|
||||
@@ -17,7 +17,6 @@ export const defaultAdminStockLocationFields = [
|
||||
|
||||
export const retrieveTransformQueryConfig = {
|
||||
defaults: defaultAdminStockLocationFields,
|
||||
allowed: defaultAdminStockLocationFields,
|
||||
isList: false,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
import { FindParams, extendedFindParamsMixin } from "../../../types/common"
|
||||
import {
|
||||
DateComparisonOperator,
|
||||
FindParams,
|
||||
NumericalComparisonOperator,
|
||||
StringComparisonOperator,
|
||||
extendedFindParamsMixin,
|
||||
} from "../../../types/common"
|
||||
import {
|
||||
IsBoolean,
|
||||
IsEmail,
|
||||
IsNotEmpty,
|
||||
IsNumber,
|
||||
IsObject,
|
||||
IsOptional,
|
||||
IsString,
|
||||
@@ -290,3 +281,8 @@ export class AdminPostStockLocationsLocationReq {
|
||||
export class AdminPostStockLocationsLocationParams extends FindParams {}
|
||||
|
||||
export class AdminGetStockLocationsLocationParams extends FindParams {}
|
||||
|
||||
export class AdminStockLocationsLocationSalesChannelBatchReq {
|
||||
@IsString({ each: true })
|
||||
sales_channel_ids: string[]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user