From d1728990e989aed6675d6505944a7a72d9818c86 Mon Sep 17 00:00:00 2001 From: Oli Juhl <59018053+olivermrbl@users.noreply.github.com> Date: Sun, 7 Apr 2024 10:59:08 +0200 Subject: [PATCH] feat: Delete service zone (#6984) --- .../__tests__/admin/fulfillment-sets.spec.ts | 68 +++++++++++++++++++ .../fulfillment/steps/delete-service-zones.ts | 28 ++++++++ .../core-flows/src/fulfillment/steps/index.ts | 1 + .../workflows/delete-service-zones.ts | 10 +++ .../src/fulfillment/workflows/index.ts | 1 + .../[id]/service-zones/[zone_id]/route.ts | 36 ++++++++++ .../admin/fulfillment-sets/middlewares.ts | 7 +- 7 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 packages/core-flows/src/fulfillment/steps/delete-service-zones.ts create mode 100644 packages/core-flows/src/fulfillment/workflows/delete-service-zones.ts create mode 100644 packages/medusa/src/api-v2/admin/fulfillment-sets/[id]/service-zones/[zone_id]/route.ts diff --git a/integration-tests/api/__tests__/admin/fulfillment-sets.spec.ts b/integration-tests/api/__tests__/admin/fulfillment-sets.spec.ts index 6e9c2d8f64..d24a01e67e 100644 --- a/integration-tests/api/__tests__/admin/fulfillment-sets.spec.ts +++ b/integration-tests/api/__tests__/admin/fulfillment-sets.spec.ts @@ -249,6 +249,74 @@ medusaIntegrationTestRunner({ `Invalid request body: ${JSON.stringify(expectedErrors)}` ) }) + + describe("POST /admin/fulfillment-sets/:id/service-zones", () => { + it("should delete a service zone for a fulfillment set", async () => { + const stockLocationResponse = await api.post( + `/admin/stock-locations`, + { + name: "test location", + }, + adminHeaders + ) + + const stockLocationId = stockLocationResponse.data.stock_location.id + + const locationWithFSetResponse = await api.post( + `/admin/stock-locations/${stockLocationId}/fulfillment-sets?fields=id,*fulfillment_sets`, + { + name: "Fulfillment Set", + type: "shipping", + }, + adminHeaders + ) + + const fulfillmentSetId = + locationWithFSetResponse.data.stock_location.fulfillment_sets[0].id + + const response = await api.post( + `/admin/fulfillment-sets/${fulfillmentSetId}/service-zones`, + { + name: "Test Zone", + geo_zones: [], + }, + adminHeaders + ) + + const fset = response.data.fulfillment_set + + const serviceZoneId = fset.service_zones[0].id + + const deleteResponse = await api.delete( + `/admin/fulfillment-sets/${fulfillmentSetId}/service-zones/${serviceZoneId}`, + adminHeaders + ) + + expect(deleteResponse.status).toEqual(200) + expect(deleteResponse.data).toEqual( + expect.objectContaining({ + id: serviceZoneId, + object: "service-zone", + deleted: true, + parent: expect.objectContaining({ + id: fulfillmentSetId, + }), + }) + ) + }) + + it("should throw when fulfillment set doesn't exist", async () => { + const deleteResponse = await api + .delete( + `/admin/fulfillment-sets/foo/service-zones/bar`, + adminHeaders + ) + .catch((e) => e.response) + + expect(deleteResponse.status).toEqual(404) + expect(deleteResponse.data.message).toEqual("FulfillmentSet with id: foo was not found") + }) + }) }) }, }) diff --git a/packages/core-flows/src/fulfillment/steps/delete-service-zones.ts b/packages/core-flows/src/fulfillment/steps/delete-service-zones.ts new file mode 100644 index 0000000000..8cbe4bf7da --- /dev/null +++ b/packages/core-flows/src/fulfillment/steps/delete-service-zones.ts @@ -0,0 +1,28 @@ +import { ModuleRegistrationName } from "@medusajs/modules-sdk" +import { IFulfillmentModuleService } from "@medusajs/types" +import { StepResponse, createStep } from "@medusajs/workflows-sdk" + +export const deleteServiceZonesStepId = "delete-service-zones" +export const deleteServiceZonesStep = createStep( + deleteServiceZonesStepId, + async (ids: string[], { container }) => { + const service = container.resolve( + ModuleRegistrationName.FULFILLMENT + ) + + await service.softDelete(ids) + + return new StepResponse(void 0, ids) + }, + async (prevIds, { container }) => { + if (!prevIds?.length) { + return + } + + const service = container.resolve( + ModuleRegistrationName.FULFILLMENT + ) + + await service.restore(prevIds) + } +) diff --git a/packages/core-flows/src/fulfillment/steps/index.ts b/packages/core-flows/src/fulfillment/steps/index.ts index e725b41d7f..7c4893c164 100644 --- a/packages/core-flows/src/fulfillment/steps/index.ts +++ b/packages/core-flows/src/fulfillment/steps/index.ts @@ -3,4 +3,5 @@ export * from "./add-shipping-options-prices" export * from "./create-fulfillment-set" export * from "./create-service-zones" export * from "./create-shipping-options" +export * from "./delete-service-zones" export * from "./remove-rules-from-fulfillment-shipping-option" diff --git a/packages/core-flows/src/fulfillment/workflows/delete-service-zones.ts b/packages/core-flows/src/fulfillment/workflows/delete-service-zones.ts new file mode 100644 index 0000000000..30b93d7e1a --- /dev/null +++ b/packages/core-flows/src/fulfillment/workflows/delete-service-zones.ts @@ -0,0 +1,10 @@ +import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk" +import { deleteServiceZonesStep } from "../steps" + +export const deleteServiceZonesWorkflowId = "delete-service-zones-workflow" +export const deleteServiceZonesWorkflow = createWorkflow( + deleteServiceZonesWorkflowId, + (input: WorkflowData<{ ids: string[] }>) => { + deleteServiceZonesStep(input.ids) + } +) diff --git a/packages/core-flows/src/fulfillment/workflows/index.ts b/packages/core-flows/src/fulfillment/workflows/index.ts index fc7da77d6b..5d6c33855e 100644 --- a/packages/core-flows/src/fulfillment/workflows/index.ts +++ b/packages/core-flows/src/fulfillment/workflows/index.ts @@ -1,4 +1,5 @@ export * from "./add-rules-to-fulfillment-shipping-option" export * from "./create-service-zones" +export * from "./delete-service-zones" export * from "./create-shipping-options" export * from "./remove-rules-from-fulfillment-shipping-option" diff --git a/packages/medusa/src/api-v2/admin/fulfillment-sets/[id]/service-zones/[zone_id]/route.ts b/packages/medusa/src/api-v2/admin/fulfillment-sets/[id]/service-zones/[zone_id]/route.ts new file mode 100644 index 0000000000..90a2d7c279 --- /dev/null +++ b/packages/medusa/src/api-v2/admin/fulfillment-sets/[id]/service-zones/[zone_id]/route.ts @@ -0,0 +1,36 @@ +import { ModuleRegistrationName } from "@medusajs/modules-sdk" +import { IFulfillmentModuleService } from "@medusajs/types" +import { deleteServiceZonesWorkflow } from "../../../../../../../../core-flows/dist" +import { + AuthenticatedMedusaRequest, + MedusaResponse, +} from "../../../../../../types/routing" + +export const DELETE = async ( + req: AuthenticatedMedusaRequest, + res: MedusaResponse +) => { + const { id, zone_id } = req.params + + const fulfillmentModuleService = req.scope.resolve( + ModuleRegistrationName.FULFILLMENT + ) + + const fulfillmentSet = await fulfillmentModuleService.retrieve(id) + + const { errors } = await deleteServiceZonesWorkflow(req.scope).run({ + input: { ids: [zone_id] }, + throwOnError: false, + }) + + if (Array.isArray(errors) && errors[0]) { + throw errors[0].error + } + + res.status(200).json({ + id: zone_id, + object: "service-zone", + deleted: true, + parent: fulfillmentSet, + }) +} diff --git a/packages/medusa/src/api-v2/admin/fulfillment-sets/middlewares.ts b/packages/medusa/src/api-v2/admin/fulfillment-sets/middlewares.ts index 0f1d6e9298..683d63af69 100644 --- a/packages/medusa/src/api-v2/admin/fulfillment-sets/middlewares.ts +++ b/packages/medusa/src/api-v2/admin/fulfillment-sets/middlewares.ts @@ -5,7 +5,7 @@ import { validateAndTransformQuery } from "../../utils/validate-query" import * as QueryConfig from "./query-config" import { AdminCreateFulfillmentSetServiceZonesSchema, - AdminFulfillmentSetParams + AdminFulfillmentSetParams, } from "./validators" export const adminFulfillmentSetsRoutesMiddlewares: MiddlewareRoute[] = [ @@ -25,4 +25,9 @@ export const adminFulfillmentSetsRoutesMiddlewares: MiddlewareRoute[] = [ ), ], }, + { + method: ["DELETE"], + matcher: "/admin/fulfillment-sets/:id/service-zones/:zone_id", + middlewares: [], + }, ]