feat(tax): v2 api tax rates and regions deletes (#6541)
This commit is contained in:
@@ -295,4 +295,82 @@ describe("Taxes - Admin", () => {
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it("can create a tax rate and delete it", async () => {
|
||||
const api = useApi() as any
|
||||
const regionRes = await api.post(
|
||||
`/admin/tax-regions`,
|
||||
{
|
||||
country_code: "us",
|
||||
default_tax_rate: { code: "default", rate: 2, name: "default rate" },
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const usRegionId = regionRes.data.tax_region.id
|
||||
|
||||
const rateRes = await api.post(
|
||||
`/admin/tax-rates`,
|
||||
{
|
||||
tax_region_id: usRegionId,
|
||||
code: "RATE2",
|
||||
name: "another rate",
|
||||
rate: 10,
|
||||
rules: [{ reference: "product", reference_id: "prod_1234" }],
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const deleteRes = await api.delete(
|
||||
`/admin/tax-rates/${rateRes.data.tax_rate.id}`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(deleteRes.status).toEqual(200)
|
||||
expect(deleteRes.data).toEqual({
|
||||
id: rateRes.data.tax_rate.id,
|
||||
object: "tax_rate",
|
||||
deleted: true,
|
||||
})
|
||||
|
||||
const rates = await service.list(
|
||||
{ id: rateRes.data.tax_rate.id },
|
||||
{ withDeleted: true }
|
||||
)
|
||||
expect(rates.length).toEqual(1)
|
||||
expect(rates[0].deleted_at).not.toBeNull()
|
||||
})
|
||||
|
||||
it("can create a tax region and delete it", async () => {
|
||||
const api = useApi() as any
|
||||
const regionRes = await api.post(
|
||||
`/admin/tax-regions`,
|
||||
{
|
||||
country_code: "us",
|
||||
default_tax_rate: { code: "default", rate: 2, name: "default rate" },
|
||||
},
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
const usRegionId = regionRes.data.tax_region.id
|
||||
|
||||
const deleteRes = await api.delete(
|
||||
`/admin/tax-regions/${usRegionId}`,
|
||||
adminHeaders
|
||||
)
|
||||
|
||||
expect(deleteRes.status).toEqual(200)
|
||||
expect(deleteRes.data).toEqual({
|
||||
id: usRegionId,
|
||||
object: "tax_region",
|
||||
deleted: true,
|
||||
})
|
||||
|
||||
const rates = await service.listTaxRegions(
|
||||
{ id: usRegionId },
|
||||
{ withDeleted: true }
|
||||
)
|
||||
expect(rates.length).toEqual(1)
|
||||
expect(rates[0].deleted_at).not.toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
28
packages/core-flows/src/tax/steps/delete-tax-rates.ts
Normal file
28
packages/core-flows/src/tax/steps/delete-tax-rates.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { ITaxModuleService } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
export const deleteTaxRatesStepId = "delete-tax-rates"
|
||||
export const deleteTaxRatesStep = createStep(
|
||||
deleteTaxRatesStepId,
|
||||
async (ids: string[], { container }) => {
|
||||
const service = container.resolve<ITaxModuleService>(
|
||||
ModuleRegistrationName.TAX
|
||||
)
|
||||
|
||||
await service.softDelete(ids)
|
||||
|
||||
return new StepResponse(void 0, ids)
|
||||
},
|
||||
async (prevIds, { container }) => {
|
||||
if (!prevIds?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<ITaxModuleService>(
|
||||
ModuleRegistrationName.TAX
|
||||
)
|
||||
|
||||
await service.restore(prevIds)
|
||||
}
|
||||
)
|
||||
28
packages/core-flows/src/tax/steps/delete-tax-regions.ts
Normal file
28
packages/core-flows/src/tax/steps/delete-tax-regions.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||
import { ITaxModuleService } from "@medusajs/types"
|
||||
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||
|
||||
export const deleteTaxRegionsStepId = "delete-tax-regions"
|
||||
export const deleteTaxRegionsStep = createStep(
|
||||
deleteTaxRegionsStepId,
|
||||
async (ids: string[], { container }) => {
|
||||
const service = container.resolve<ITaxModuleService>(
|
||||
ModuleRegistrationName.TAX
|
||||
)
|
||||
|
||||
await service.softDeleteTaxRegions(ids)
|
||||
|
||||
return new StepResponse(void 0, ids)
|
||||
},
|
||||
async (prevIds, { container }) => {
|
||||
if (!prevIds?.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const service = container.resolve<ITaxModuleService>(
|
||||
ModuleRegistrationName.TAX
|
||||
)
|
||||
|
||||
await service.restoreTaxRegions(prevIds)
|
||||
}
|
||||
)
|
||||
@@ -1,3 +1,5 @@
|
||||
export * from "./create-tax-regions"
|
||||
export * from "./delete-tax-regions"
|
||||
export * from "./create-tax-rates"
|
||||
export * from "./update-tax-rates"
|
||||
export * from "./delete-tax-rates"
|
||||
|
||||
12
packages/core-flows/src/tax/workflows/delete-tax-rates.ts
Normal file
12
packages/core-flows/src/tax/workflows/delete-tax-rates.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { deleteTaxRatesStep } from "../steps"
|
||||
|
||||
type WorkflowInput = { ids: string[] }
|
||||
|
||||
export const deleteTaxRatesWorkflowId = "delete-tax-rates"
|
||||
export const deleteTaxRatesWorkflow = createWorkflow(
|
||||
deleteTaxRatesWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<void> => {
|
||||
return deleteTaxRatesStep(input.ids)
|
||||
}
|
||||
)
|
||||
12
packages/core-flows/src/tax/workflows/delete-tax-regions.ts
Normal file
12
packages/core-flows/src/tax/workflows/delete-tax-regions.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||
import { deleteTaxRegionsStep } from "../steps"
|
||||
|
||||
type WorkflowInput = { ids: string[] }
|
||||
|
||||
export const deleteTaxRegionsWorkflowId = "delete-tax-regions"
|
||||
export const deleteTaxRegionsWorkflow = createWorkflow(
|
||||
deleteTaxRegionsWorkflowId,
|
||||
(input: WorkflowData<WorkflowInput>): WorkflowData<void> => {
|
||||
return deleteTaxRegionsStep(input.ids)
|
||||
}
|
||||
)
|
||||
@@ -1,3 +1,5 @@
|
||||
export * from "./create-tax-regions"
|
||||
export * from "./delete-tax-regions"
|
||||
export * from "./create-tax-rates"
|
||||
export * from "./update-tax-rates"
|
||||
export * from "./delete-tax-rates"
|
||||
|
||||
@@ -6,7 +6,10 @@ import {
|
||||
import { defaultAdminTaxRateFields } from "../query-config"
|
||||
import { remoteQueryObjectFromString } from "@medusajs/utils"
|
||||
import { AdminPostTaxRatesTaxRateReq } from "../../../../api/routes/admin/tax-rates"
|
||||
import { updateTaxRatesWorkflow } from "@medusajs/core-flows"
|
||||
import {
|
||||
deleteTaxRatesWorkflow,
|
||||
updateTaxRatesWorkflow,
|
||||
} from "@medusajs/core-flows"
|
||||
|
||||
export const POST = async (
|
||||
req: AuthenticatedMedusaRequest<AdminPostTaxRatesTaxRateReq>,
|
||||
@@ -55,3 +58,25 @@ export const GET = async (
|
||||
|
||||
res.status(200).json({ tax_rate: taxRate })
|
||||
}
|
||||
|
||||
export const DELETE = async (
|
||||
req: AuthenticatedMedusaRequest,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const id = req.params.id
|
||||
|
||||
const { errors } = await deleteTaxRatesWorkflow(req.scope).run({
|
||||
input: { ids: [id] },
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
if (Array.isArray(errors) && errors[0]) {
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
id,
|
||||
object: "tax_rate",
|
||||
deleted: true,
|
||||
})
|
||||
}
|
||||
|
||||
27
packages/medusa/src/api-v2/admin/tax-regions/[id]/route.ts
Normal file
27
packages/medusa/src/api-v2/admin/tax-regions/[id]/route.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { deleteTaxRegionsWorkflow } from "@medusajs/core-flows"
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "../../../../types/routing"
|
||||
|
||||
export const DELETE = async (
|
||||
req: AuthenticatedMedusaRequest,
|
||||
res: MedusaResponse
|
||||
) => {
|
||||
const id = req.params.id
|
||||
|
||||
const { errors } = await deleteTaxRegionsWorkflow(req.scope).run({
|
||||
input: { ids: [id] },
|
||||
throwOnError: false,
|
||||
})
|
||||
|
||||
if (Array.isArray(errors) && errors[0]) {
|
||||
throw errors[0].error
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
id,
|
||||
object: "tax_region",
|
||||
deleted: true,
|
||||
})
|
||||
}
|
||||
@@ -78,6 +78,7 @@ export interface TaxRegionDTO {
|
||||
created_at: string | Date
|
||||
updated_at: string | Date
|
||||
created_by: string | null
|
||||
deleted_at: string | Date | null
|
||||
}
|
||||
|
||||
export interface FilterableTaxRegionProps
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { FindConfig } from "../common"
|
||||
import { SoftDeleteReturn } from "../dal"
|
||||
import { RestoreReturn, SoftDeleteReturn } from "../dal"
|
||||
import { IModuleService } from "../modules-sdk"
|
||||
import { Context } from "../shared-context"
|
||||
import {
|
||||
@@ -73,6 +73,12 @@ export interface ITaxModuleService extends IModuleService {
|
||||
delete(taxRateIds: string[], sharedContext?: Context): Promise<void>
|
||||
delete(taxRateId: string, sharedContext?: Context): Promise<void>
|
||||
|
||||
restore<TReturnableLinkableKeys extends string = string>(
|
||||
taxRateIds: string[],
|
||||
config?: RestoreReturn<TReturnableLinkableKeys>,
|
||||
sharedContext?: Context
|
||||
): Promise<Record<string, string[]> | void>
|
||||
|
||||
createTaxRegions(
|
||||
data: CreateTaxRegionDTO,
|
||||
sharedContext?: Context
|
||||
@@ -136,6 +142,12 @@ export interface ITaxModuleService extends IModuleService {
|
||||
sharedContext?: Context
|
||||
): Promise<Record<string, string[]> | void>
|
||||
|
||||
restoreTaxRegions<TReturnableLinkableKeys extends string = string>(
|
||||
taxRegionIds: string[],
|
||||
config?: RestoreReturn<TReturnableLinkableKeys>,
|
||||
sharedContext?: Context
|
||||
): Promise<Record<string, string[]> | void>
|
||||
|
||||
softDeleteTaxRateRules<TReturnableLinkableKeys extends string = string>(
|
||||
taxRateRulePairs: { tax_rate_id: string; reference_id: string }[],
|
||||
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
|
||||
|
||||
Reference in New Issue
Block a user