feat(tax): migration file (#6523)

**What**
- Tax Module Migration file.
- Skeleton for API routes and integrations tests for tax API in v2
This commit is contained in:
Sebastian Rindom
2024-02-28 15:40:35 +01:00
committed by GitHub
parent 0d46abf0ff
commit adad66e13f
15 changed files with 912 additions and 6 deletions

View File

@@ -0,0 +1,77 @@
import path from "path"
import { ITaxModuleService } from "@medusajs/types"
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { createAdminUser } from "../../../helpers/create-admin-user"
import { initDb, useDb } from "../../../../environment-helpers/use-db"
import { getContainer } from "../../../../environment-helpers/use-container"
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
import { useApi } from "../../../../environment-helpers/use-api"
jest.setTimeout(50000)
const env = { MEDUSA_FF_MEDUSA_V2: true }
const adminHeaders = {
headers: { "x-medusa-access-token": "test_token" },
}
describe("Taxes - Admin", () => {
let dbConnection
let appContainer
let shutdownServer
let service: ITaxModuleService
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", "..", ".."))
dbConnection = await initDb({ cwd, env } as any)
shutdownServer = await startBootstrapApp({ cwd, env })
appContainer = getContainer()
service = appContainer.resolve(ModuleRegistrationName.TAX)
})
beforeEach(async () => {
await createAdminUser(dbConnection, adminHeaders)
})
afterAll(async () => {
const db = useDb()
await db.shutdown()
await shutdownServer()
})
afterEach(async () => {
const db = useDb()
await db.teardown()
})
it("can retrieve a tax rate", async () => {
const region = await service.createTaxRegions({
country_code: "us",
})
const rate = await service.create({
tax_region_id: region.id,
code: "test",
rate: 2.5,
name: "Test Rate",
})
const api = useApi() as any
const response = await api.get(`/admin/tax-rates/${rate.id}`, adminHeaders)
expect(response.status).toEqual(200)
expect(response.data).toEqual({
tax_rate: {
id: rate.id,
code: "test",
rate: 2.5,
name: "Test Rate",
metadata: null,
tax_region_id: region.id,
created_at: expect.any(String),
updated_at: expect.any(String),
deleted_at: null,
created_by: null,
},
})
})
})

View File

@@ -123,5 +123,10 @@ module.exports = {
resources: "shared",
resolve: "@medusajs/store",
},
[Modules.TAX]: {
scope: "internal",
resources: "shared",
resolve: "@medusajs/tax",
},
},
}

View File

@@ -22,6 +22,7 @@
"@medusajs/promotion": "workspace:^",
"@medusajs/region": "workspace:^",
"@medusajs/store": "workspace:^",
"@medusajs/tax": "workspace:^",
"@medusajs/user": "workspace:^",
"@medusajs/utils": "workspace:^",
"@medusajs/workflow-engine-inmemory": "workspace:*",

View File

@@ -0,0 +1,26 @@
import {
AuthenticatedMedusaRequest,
MedusaResponse,
} from "../../../../types/routing"
import { defaultAdminTaxRateFields } from "../query-config"
import { remoteQueryObjectFromString } from "@medusajs/utils"
export const GET = async (
req: AuthenticatedMedusaRequest,
res: MedusaResponse
) => {
const remoteQuery = req.scope.resolve("remoteQuery")
const variables = { id: req.params.id }
const queryObject = remoteQueryObjectFromString({
entryPoint: "tax_rate",
variables,
fields: defaultAdminTaxRateFields,
})
const [taxRate] = await remoteQuery(queryObject)
res.status(200).json({ tax_rate: taxRate })
}

View File

@@ -0,0 +1,25 @@
import * as QueryConfig from "./query-config"
import { AdminGetTaxRatesTaxRateParams } from "./validators"
import { transformQuery } from "../../../api/middlewares"
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
import { authenticate } from "../../../utils/authenticate-middleware"
export const adminTaxRateRoutesMiddlewares: MiddlewareRoute[] = [
{
method: ["ALL"],
matcher: "/admin/tax-rates*",
middlewares: [authenticate("admin", ["bearer", "session", "api-key"])],
},
{
method: ["GET"],
matcher: "/admin/tax-rates/:id",
middlewares: [
transformQuery(
AdminGetTaxRatesTaxRateParams,
QueryConfig.retrieveTransformQueryConfig
),
],
},
]

View File

@@ -0,0 +1,26 @@
export const defaultAdminTaxRateRelations = []
export const allowedAdminTaxRateRelations = []
export const defaultAdminTaxRateFields = [
"id",
"name",
"code",
"rate",
"tax_region_id",
"created_by",
"created_at",
"updated_at",
"deleted_at",
"metadata",
]
export const retrieveTransformQueryConfig = {
defaultFields: defaultAdminTaxRateFields,
defaultRelations: defaultAdminTaxRateRelations,
allowedRelations: allowedAdminTaxRateRelations,
isList: false,
}
export const listTransformQueryConfig = {
defaultLimit: 20,
isList: true,
}

View File

@@ -0,0 +1,3 @@
import { FindParams } from "../../../types/common"
export class AdminGetTaxRatesTaxRateParams extends FindParams {}

View File

@@ -7,6 +7,7 @@ import { adminInviteRoutesMiddlewares } from "./admin/invites/middlewares"
import { adminPromotionRoutesMiddlewares } from "./admin/promotions/middlewares"
import { adminRegionRoutesMiddlewares } from "./admin/regions/middlewares"
import { adminStoreRoutesMiddlewares } from "./admin/stores/middlewares"
import { adminTaxRateRoutesMiddlewares } from "./admin/tax-rates/middlewares"
import { adminUserRoutesMiddlewares } from "./admin/users/middlewares"
import { adminWorkflowsExecutionsMiddlewares } from "./admin/workflows-executions/middlewares"
import { authRoutesMiddlewares } from "./auth/middlewares"
@@ -30,6 +31,7 @@ export const config: MiddlewaresConfig = {
...adminRegionRoutesMiddlewares,
...adminUserRoutesMiddlewares,
...adminInviteRoutesMiddlewares,
...adminTaxRateRoutesMiddlewares,
...adminApiKeyRoutesMiddlewares,
...hooksRoutesMiddlewares,
...adminStoreRoutesMiddlewares,

View File

@@ -1,9 +1,13 @@
import { Modules } from "@medusajs/modules-sdk"
import { ModuleJoinerConfig } from "@medusajs/types"
import { MapToConfig } from "@medusajs/utils"
import { TaxRate, TaxRegion, TaxRateRule, TaxProvider } from "@models"
export const LinkableKeys: Record<string, string> = {
tax_rate_id: "TaxRate",
tax_rate_id: TaxRate.name,
tax_region_id: TaxRegion.name,
tax_rate_rule_id: TaxRateRule.name,
tax_provider_id: TaxProvider.name,
}
const entityLinkableKeysMap: MapToConfig = {}
@@ -21,5 +25,33 @@ export const joinerConfig: ModuleJoinerConfig = {
serviceName: Modules.TAX,
primaryKeys: ["id"],
linkableKeys: LinkableKeys,
alias: [],
alias: [
{
name: ["tax_rate", "tax_rates"],
args: {
entity: TaxRate.name,
},
},
{
name: ["tax_region", "tax_regions"],
args: {
entity: TaxRegion.name,
methodSuffix: "TaxRegions",
},
},
{
name: ["tax_rate_rule", "tax_rate_rules"],
args: {
entity: TaxRateRule.name,
methodSuffix: "TaxRateRules",
},
},
{
name: ["tax_provider", "tax_providers"],
args: {
entity: TaxProvider.name,
methodSuffix: "TaxProviders",
},
},
],
} as ModuleJoinerConfig

View File

@@ -0,0 +1,558 @@
{
"namespaces": [
"public"
],
"name": "public",
"tables": [
{
"columns": {
"id": {
"name": "id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"is_enabled": {
"name": "is_enabled",
"type": "boolean",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"default": "true",
"mappedType": "boolean"
}
},
"name": "tax_provider",
"schema": "public",
"indexes": [
{
"keyName": "tax_provider_pkey",
"columnNames": [
"id"
],
"composite": false,
"primary": true,
"unique": true
}
],
"checks": [],
"foreignKeys": {}
},
{
"columns": {
"id": {
"name": "id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"provider_id": {
"name": "provider_id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "text"
},
"country_code": {
"name": "country_code",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"province_code": {
"name": "province_code",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "text"
},
"parent_id": {
"name": "parent_id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "text"
},
"metadata": {
"name": "metadata",
"type": "jsonb",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "json"
},
"created_at": {
"name": "created_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 6,
"default": "now()",
"mappedType": "datetime"
},
"updated_at": {
"name": "updated_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 6,
"default": "now()",
"mappedType": "datetime"
},
"created_by": {
"name": "created_by",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "text"
},
"deleted_at": {
"name": "deleted_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"length": 6,
"mappedType": "datetime"
}
},
"name": "tax_region",
"schema": "public",
"indexes": [
{
"columnNames": [
"parent_id"
],
"composite": false,
"keyName": "IDX_tax_region_parent_id",
"primary": false,
"unique": false
},
{
"keyName": "IDX_tax_region_deleted_at",
"columnNames": [
"deleted_at"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_tax_region_deleted_at\" ON \"tax_region\" (deleted_at) WHERE deleted_at IS NOT NULL"
},
{
"keyName": "IDX_tax_region_unique_country_province",
"columnNames": [],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_tax_region_unique_country_province\" ON \"tax_region\" (country_code, province_code)"
},
{
"keyName": "tax_region_pkey",
"columnNames": [
"id"
],
"composite": false,
"primary": true,
"unique": true
}
],
"checks": [
{
"name": "CK_tax_region_country_top_level",
"expression": "parent_id IS NULL OR province_code IS NOT NULL",
"definition": "check ((parent_id IS NULL OR province_code IS NOT NULL))"
},
{
"name": "CK_tax_region_provider_top_level",
"expression": "parent_id IS NULL OR provider_id IS NULL",
"definition": "check ((parent_id IS NULL OR provider_id IS NULL))"
}
],
"foreignKeys": {
"tax_region_provider_id_foreign": {
"constraintName": "tax_region_provider_id_foreign",
"columnNames": [
"provider_id"
],
"localTableName": "public.tax_region",
"referencedColumnNames": [
"id"
],
"referencedTableName": "public.tax_provider",
"deleteRule": "set null",
"updateRule": "cascade"
},
"tax_region_parent_id_foreign": {
"constraintName": "tax_region_parent_id_foreign",
"columnNames": [
"parent_id"
],
"localTableName": "public.tax_region",
"referencedColumnNames": [
"id"
],
"referencedTableName": "public.tax_region",
"deleteRule": "cascade",
"updateRule": "cascade"
}
}
},
{
"columns": {
"id": {
"name": "id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"rate": {
"name": "rate",
"type": "real",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "float"
},
"code": {
"name": "code",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "text"
},
"name": {
"name": "name",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"is_default": {
"name": "is_default",
"type": "bool",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"default": "false",
"mappedType": "boolean"
},
"is_combinable": {
"name": "is_combinable",
"type": "bool",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"default": "false",
"mappedType": "boolean"
},
"tax_region_id": {
"name": "tax_region_id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"metadata": {
"name": "metadata",
"type": "jsonb",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "json"
},
"created_at": {
"name": "created_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 6,
"default": "now()",
"mappedType": "datetime"
},
"updated_at": {
"name": "updated_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 6,
"default": "now()",
"mappedType": "datetime"
},
"created_by": {
"name": "created_by",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "text"
},
"deleted_at": {
"name": "deleted_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"length": 6,
"mappedType": "datetime"
}
},
"name": "tax_rate",
"schema": "public",
"indexes": [
{
"keyName": "IDX_tax_rate_tax_region_id",
"columnNames": [
"tax_region_id"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_tax_rate_tax_region_id\" ON \"tax_rate\" (tax_region_id) WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_tax_rate_deleted_at",
"columnNames": [
"deleted_at"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_tax_rate_deleted_at\" ON \"tax_rate\" (deleted_at) WHERE deleted_at IS NOT NULL"
},
{
"keyName": "IDX_single_default_region",
"columnNames": [],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_single_default_region\" ON \"tax_rate\" (tax_region_id) WHERE is_default = true AND deleted_at IS NULL"
},
{
"keyName": "tax_rate_pkey",
"columnNames": [
"id"
],
"composite": false,
"primary": true,
"unique": true
}
],
"checks": [],
"foreignKeys": {
"tax_rate_tax_region_id_foreign": {
"constraintName": "tax_rate_tax_region_id_foreign",
"columnNames": [
"tax_region_id"
],
"localTableName": "public.tax_rate",
"referencedColumnNames": [
"id"
],
"referencedTableName": "public.tax_region",
"deleteRule": "cascade",
"updateRule": "cascade"
}
}
},
{
"columns": {
"id": {
"name": "id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"tax_rate_id": {
"name": "tax_rate_id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"reference_id": {
"name": "reference_id",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"reference": {
"name": "reference",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"mappedType": "text"
},
"metadata": {
"name": "metadata",
"type": "jsonb",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "json"
},
"created_at": {
"name": "created_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 6,
"default": "now()",
"mappedType": "datetime"
},
"updated_at": {
"name": "updated_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": false,
"length": 6,
"default": "now()",
"mappedType": "datetime"
},
"created_by": {
"name": "created_by",
"type": "text",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"mappedType": "text"
},
"deleted_at": {
"name": "deleted_at",
"type": "timestamptz",
"unsigned": false,
"autoincrement": false,
"primary": false,
"nullable": true,
"length": 6,
"mappedType": "datetime"
}
},
"name": "tax_rate_rule",
"schema": "public",
"indexes": [
{
"keyName": "IDX_tax_rate_rule_tax_rate_id",
"columnNames": [
"tax_rate_id"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_tax_rate_rule_tax_rate_id\" ON \"tax_rate_rule\" (tax_rate_id) WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_tax_rate_rule_reference_id",
"columnNames": [
"reference_id"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_tax_rate_rule_reference_id\" ON \"tax_rate_rule\" (reference_id) WHERE deleted_at IS NULL"
},
{
"keyName": "IDX_tax_rate_rule_deleted_at",
"columnNames": [
"deleted_at"
],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_tax_rate_rule_deleted_at\" ON \"tax_rate_rule\" (deleted_at) WHERE deleted_at IS NOT NULL"
},
{
"keyName": "IDX_tax_rate_rule_unique_rate_reference",
"columnNames": [],
"composite": false,
"primary": false,
"unique": false,
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_tax_rate_rule_unique_rate_reference\" ON \"tax_rate_rule\" (tax_rate_id, reference_id) WHERE deleted_at IS NULL"
},
{
"keyName": "tax_rate_rule_pkey",
"columnNames": [
"id"
],
"composite": false,
"primary": true,
"unique": true
}
],
"checks": [],
"foreignKeys": {
"tax_rate_rule_tax_rate_id_foreign": {
"constraintName": "tax_rate_rule_tax_rate_id_foreign",
"columnNames": [
"tax_rate_id"
],
"localTableName": "public.tax_rate_rule",
"referencedColumnNames": [
"id"
],
"referencedTableName": "public.tax_rate",
"deleteRule": "cascade",
"updateRule": "cascade"
}
}
}
]
}

View File

@@ -0,0 +1,114 @@
import { generatePostgresAlterColummnIfExistStatement } from "@medusajs/utils"
import { Migration } from "@mikro-orm/migrations"
export class Migration20240227090331 extends Migration {
async up(): Promise<void> {
// Adjust tax_provider table
this.addSql(
`ALTER TABLE IF EXISTS "tax_provider" ADD COLUMN IF NOT EXISTS "is_enabled" bool not null default true;`
)
this.addSql(
`CREATE TABLE IF NOT EXISTS "tax_provider" ("id" text not null, "is_enabled" boolean not null default true, CONSTRAINT "tax_provider_pkey" PRIMARY KEY ("id"));`
)
// Create or update tax_region table
this.addSql(
`CREATE TABLE IF NOT EXISTS "tax_region" ("id" text not null, "provider_id" text null, "country_code" text not null, "province_code" text null, "parent_id" text null, "metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "created_by" text null, "deleted_at" timestamptz null, CONSTRAINT "tax_region_pkey" PRIMARY KEY ("id"), CONSTRAINT "CK_tax_region_country_top_level" CHECK (parent_id IS NULL OR province_code IS NOT NULL), CONSTRAINT "CK_tax_region_provider_top_level" CHECK (parent_id IS NULL OR provider_id IS NULL));`
)
// Indexes for tax_region
this.addSql(
`CREATE INDEX IF NOT EXISTS "IDX_tax_region_parent_id" ON "tax_region" ("parent_id");`
)
this.addSql(
`CREATE INDEX IF NOT EXISTS "IDX_tax_region_deleted_at" ON "tax_region" ("deleted_at") WHERE deleted_at IS NOT NULL;`
)
this.addSql(
`CREATE UNIQUE INDEX IF NOT EXISTS "IDX_tax_region_unique_country_province" ON "tax_region" ("country_code", "province_code");`
)
// Old foreign key on region_id
this.addSql(
generatePostgresAlterColummnIfExistStatement(
"tax_rate",
["region_id"],
"DROP NOT NULL"
)
)
this.addSql(
`ALTER TABLE IF EXISTS "tax_rate" DROP CONSTRAINT IF EXISTS "FK_b95a1e03b051993d208366cb960";`
)
this.addSql(
`ALTER TABLE IF EXISTS "tax_rate" ADD COLUMN IF NOT EXISTS "tax_region_id" text not null;`
)
this.addSql(
`ALTER TABLE IF EXISTS "tax_rate" ADD COLUMN IF NOT EXISTS "deleted_at" timestamptz null;`
)
this.addSql(
`ALTER TABLE IF EXISTS "tax_rate" ADD COLUMN IF NOT EXISTS "created_by" text null;`
)
this.addSql(
`ALTER TABLE IF EXISTS "tax_rate" ADD COLUMN IF NOT EXISTS "is_default" bool not null default false;`
)
this.addSql(
`ALTER TABLE IF EXISTS "tax_rate" ADD COLUMN IF NOT EXISTS "is_combinable" bool not null default false;`
)
this.addSql(
`create table if not exists "tax_rate" ("id" text not null, "rate" real null, "code" text null, "name" text not null, "is_default" bool not null default false, "is_combinable" bool not null default false, "tax_region_id" text not null, "metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "created_by" text null, "deleted_at" timestamptz null, constraint "tax_rate_pkey" primary key ("id"));`
)
// Indexes for tax_rate
this.addSql(
`CREATE INDEX IF NOT EXISTS "IDX_tax_rate_tax_region_id" ON "tax_rate" ("tax_region_id") WHERE deleted_at IS NULL;`
)
this.addSql(
`CREATE INDEX IF NOT EXISTS "IDX_tax_rate_deleted_at" ON "tax_rate" ("deleted_at") WHERE deleted_at IS NOT NULL;`
)
this.addSql(
`CREATE UNIQUE INDEX IF NOT EXISTS "IDX_single_default_region" ON "tax_rate" ("tax_region_id") WHERE is_default = true AND deleted_at IS NULL;`
)
// Adjust or create tax_rate_rule table
this.addSql(
`CREATE TABLE IF NOT EXISTS "tax_rate_rule" ("id" text not null, "tax_rate_id" text not null, "reference_id" text not null, "reference" text not null, "metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "created_by" text null, "deleted_at" timestamptz null, CONSTRAINT "tax_rate_rule_pkey" PRIMARY KEY ("id"));`
)
// Indexes for tax_rate_rule
this.addSql(
`CREATE INDEX IF NOT EXISTS "IDX_tax_rate_rule_tax_rate_id" ON "tax_rate_rule" ("tax_rate_id") WHERE deleted_at IS NULL;`
)
this.addSql(
`CREATE INDEX IF NOT EXISTS "IDX_tax_rate_rule_reference_id" ON "tax_rate_rule" ("reference_id") WHERE deleted_at IS NULL;`
)
this.addSql(
`CREATE INDEX IF NOT EXISTS "IDX_tax_rate_rule_deleted_at" ON "tax_rate_rule" ("deleted_at") WHERE deleted_at IS NOT NULL;`
)
this.addSql(
`CREATE UNIQUE INDEX IF NOT EXISTS "IDX_tax_rate_rule_unique_rate_reference" ON "tax_rate_rule" ("tax_rate_id", "reference_id") WHERE deleted_at IS NULL;`
)
// Foreign keys adjustments
this.addSql(
`ALTER TABLE "tax_region" ADD CONSTRAINT "FK_tax_region_provider_id" FOREIGN KEY ("provider_id") REFERENCES "tax_provider" ("id") ON DELETE SET NULL;`
)
this.addSql(
`ALTER TABLE "tax_region" ADD CONSTRAINT "FK_tax_region_parent_id" FOREIGN KEY ("parent_id") REFERENCES "tax_region" ("id") ON DELETE CASCADE;`
)
this.addSql(
`ALTER TABLE "tax_rate" ADD CONSTRAINT "FK_tax_rate_tax_region_id" FOREIGN KEY ("tax_region_id") REFERENCES "tax_region" ("id") ON DELETE CASCADE;`
)
this.addSql(
`ALTER TABLE "tax_rate_rule" ADD CONSTRAINT "FK_tax_rate_rule_tax_rate_id" FOREIGN KEY ("tax_rate_id") REFERENCES "tax_rate" ("id") ON DELETE CASCADE;`
)
// remove old tax related foreign key constraints
this.addSql(
`ALTER TABLE IF EXISTS "product_tax_rate" DROP CONSTRAINT IF EXISTS "FK_346e0016cf045b9980747747645";`
)
this.addSql(
`ALTER TABLE IF EXISTS "product_type_tax_rate" DROP CONSTRAINT IF EXISTS "FK_ece65a774192b34253abc4cd672";`
)
this.addSql(
`ALTER TABLE IF EXISTS "shipping_tax_rate" DROP CONSTRAINT IF EXISTS "FK_346e0016cf045b9980747747645";`
)
}
}

View File

@@ -1,3 +1,4 @@
export { default as TaxRate } from "./tax-rate"
export { default as TaxRegion } from "./tax-region"
export { default as TaxRateRule } from "./tax-rate-rule"
export { default as TaxProvider } from "./tax-provider"

View File

@@ -14,11 +14,12 @@ import {
MedusaContext,
MedusaError,
ModulesSdkUtils,
arrayDifference,
isDefined,
isString,
promiseAll,
} from "@medusajs/utils"
import { TaxRate, TaxRegion, TaxRateRule } from "@models"
import { TaxProvider, TaxRate, TaxRegion, TaxRateRule } from "@models"
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
import { TaxRegionDTO } from "@medusajs/types"
@@ -27,10 +28,11 @@ type InjectedDependencies = {
taxRateService: ModulesSdkTypes.InternalModuleService<any>
taxRegionService: ModulesSdkTypes.InternalModuleService<any>
taxRateRuleService: ModulesSdkTypes.InternalModuleService<any>
taxProviderService: ModulesSdkTypes.InternalModuleService<any>
[key: `tp_${string}`]: ITaxProvider
}
const generateForModels = [TaxRegion, TaxRateRule]
const generateForModels = [TaxRegion, TaxRateRule, TaxProvider]
type ItemWithRates = {
rates: TaxRate[]
@@ -40,7 +42,8 @@ type ItemWithRates = {
export default class TaxModuleService<
TTaxRate extends TaxRate = TaxRate,
TTaxRegion extends TaxRegion = TaxRegion,
TTaxRateRule extends TaxRateRule = TaxRateRule
TTaxRateRule extends TaxRateRule = TaxRateRule,
TTaxProvider extends TaxProvider = TaxProvider
>
extends ModulesSdkUtils.abstractModuleServiceFactory<
InjectedDependencies,
@@ -48,6 +51,7 @@ export default class TaxModuleService<
{
TaxRegion: { dto: TaxTypes.TaxRegionDTO }
TaxRateRule: { dto: TaxTypes.TaxRateRuleDTO }
TaxProvider: { dto: TaxTypes.TaxProviderDTO }
}
>(TaxRate, generateForModels, entityNameToLinkableKeysMap)
implements ITaxModuleService
@@ -57,6 +61,7 @@ export default class TaxModuleService<
protected taxRateService_: ModulesSdkTypes.InternalModuleService<TTaxRate>
protected taxRegionService_: ModulesSdkTypes.InternalModuleService<TTaxRegion>
protected taxRateRuleService_: ModulesSdkTypes.InternalModuleService<TTaxRateRule>
protected taxProviderService_: ModulesSdkTypes.InternalModuleService<TTaxProvider>
constructor(
{
@@ -64,6 +69,7 @@ export default class TaxModuleService<
taxRateService,
taxRegionService,
taxRateRuleService,
taxProviderService,
}: InjectedDependencies,
protected readonly moduleDeclaration: InternalModuleDeclaration
) {
@@ -75,6 +81,7 @@ export default class TaxModuleService<
this.taxRateService_ = taxRateService
this.taxRegionService_ = taxRegionService
this.taxRateRuleService_ = taxRateRuleService
this.taxProviderService_ = taxProviderService
}
__joinerConfig(): ModuleJoinerConfig {
@@ -613,4 +620,27 @@ export default class TaxModuleService<
private normalizeRegionCodes(code: string) {
return code.toLowerCase()
}
// @InjectTransactionManager("baseRepository_")
// async createProvidersOnLoad(@MedusaContext() sharedContext: Context = {}) {
// const providersToLoad = this.container_["tax_providers"] as ITaxProvider[]
// const ids = providersToLoad.map((p) => p.getIdentifier())
// const existing = await this.taxProviderService_.update(
// { selector: { id: { $in: ids } }, data: { is_enabled: true } },
// sharedContext
// )
// const existingIds = existing.map((p) => p.id)
// const diff = arrayDifference(ids, existingIds)
// await this.taxProviderService_.create(
// diff.map((id) => ({ id, is_enabled: true }))
// )
// await this.taxProviderService_.update({
// selector: { id: { $nin: ids } },
// data: { is_enabled: false },
// })
// }
}

View File

@@ -36,6 +36,11 @@ export interface TaxRateDTO {
created_by: string | null
}
export interface TaxProviderDTO {
id: string
is_enabled: boolean
}
export interface FilterableTaxRateProps
extends BaseFilterable<FilterableTaxRateProps> {
id?: string | string[]

View File

@@ -8779,7 +8779,7 @@ __metadata:
languageName: unknown
linkType: soft
"@medusajs/tax@workspace:packages/tax":
"@medusajs/tax@workspace:^, @medusajs/tax@workspace:packages/tax":
version: 0.0.0-use.local
resolution: "@medusajs/tax@workspace:packages/tax"
dependencies:
@@ -31720,6 +31720,7 @@ __metadata:
"@medusajs/promotion": "workspace:^"
"@medusajs/region": "workspace:^"
"@medusajs/store": "workspace:^"
"@medusajs/tax": "workspace:^"
"@medusajs/types": "workspace:^"
"@medusajs/user": "workspace:^"
"@medusajs/utils": "workspace:^"