Feat/tax dml (#10525)

Fixes: FRMW-2842

There are zero breaking changes and the users will have to run the migrations
This commit is contained in:
Harminder Virk
2024-12-12 09:35:11 +00:00
committed by GitHub
parent bf6d14cb54
commit e021c9258c
9 changed files with 389 additions and 546 deletions
+10 -14
View File
@@ -1,16 +1,12 @@
import { Entity, OptionalProps, PrimaryKey, Property } from "@mikro-orm/core"
import { model } from "@medusajs/framework/utils"
import { TaxRegion } from "@models"
const TABLE_NAME = "tax_provider"
@Entity({ tableName: TABLE_NAME })
export default class TaxProvider {
[OptionalProps]?: "is_enabled"
const TaxProvider = model.define("TaxProvider", {
id: model.id().primaryKey(),
is_enabled: model.boolean().default(true),
regions: model.hasMany(() => TaxRegion, {
mappedBy: "provider",
}),
})
@PrimaryKey({ columnType: "text" })
id: string
@Property({
default: true,
columnType: "boolean",
})
is_enabled: boolean = true
}
export default TaxProvider
+25 -113
View File
@@ -1,117 +1,29 @@
import { DAL } from "@medusajs/framework/types"
import {
createPsqlIndexStatementHelper,
DALUtils,
generateEntityId,
} from "@medusajs/framework/utils"
import {
BeforeCreate,
Entity,
Filter,
ManyToOne,
OnInit,
OptionalProps,
PrimaryKey,
Property,
Rel,
} from "@mikro-orm/core"
import { model } from "@medusajs/framework/utils"
import TaxRate from "./tax-rate"
const TABLE_NAME = "tax_rate_rule"
type OptionalRuleProps = DAL.SoftDeletableModelDateColumns
const taxRateIdIndexName = "IDX_tax_rate_rule_tax_rate_id"
const taxRateIdIndexStatement = createPsqlIndexStatementHelper({
name: taxRateIdIndexName,
tableName: TABLE_NAME,
columns: "tax_rate_id",
where: "deleted_at IS NULL",
})
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
tableName: TABLE_NAME,
columns: "deleted_at",
where: "deleted_at IS NOT NULL",
})
const referenceIdIndexName = "IDX_tax_rate_rule_reference_id"
const referenceIdIndexStatement = createPsqlIndexStatementHelper({
name: referenceIdIndexName,
tableName: TABLE_NAME,
columns: "reference_id",
where: "deleted_at IS NULL",
})
export const uniqueRateReferenceIndexName =
"IDX_tax_rate_rule_unique_rate_reference"
const uniqueRateReferenceIndexStatement = createPsqlIndexStatementHelper({
name: uniqueRateReferenceIndexName,
tableName: TABLE_NAME,
columns: ["tax_rate_id", "reference_id"],
unique: true,
where: "deleted_at IS NULL",
})
@Entity({ tableName: TABLE_NAME })
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
@uniqueRateReferenceIndexStatement.MikroORMIndex()
export default class TaxRateRule {
[OptionalProps]?: OptionalRuleProps
@PrimaryKey({ columnType: "text" })
id!: string
@ManyToOne(() => TaxRate, {
type: "text",
fieldName: "tax_rate_id",
mapToPk: true,
onDelete: "cascade",
const TaxRateRule = model
.define("TaxRateRule", {
id: model.id({ prefix: "txrule" }).primaryKey(),
metadata: model.json().nullable(),
created_by: model.text().nullable(),
tax_rate: model.belongsTo(() => TaxRate, {
mappedBy: "rules",
}),
reference: model.text(),
reference_id: model.text(),
})
@taxRateIdIndexStatement.MikroORMIndex()
tax_rate_id: string
.indexes([
{
name: "IDX_tax_rate_rule_reference_id",
on: ["reference_id"],
where: "deleted_at IS NULL",
},
{
name: "IDX_tax_rate_rule_unique_rate_reference",
on: ["tax_rate_id", "reference_id"],
unique: true,
where: "deleted_at IS NULL",
},
])
@Property({ columnType: "text" })
@referenceIdIndexStatement.MikroORMIndex()
reference_id: string
@Property({ columnType: "text" })
reference: string
@ManyToOne(() => TaxRate, { persist: false })
tax_rate: Rel<TaxRate>
@Property({ columnType: "jsonb", nullable: true })
metadata: Record<string, unknown> | null = null
@Property({
onCreate: () => new Date(),
columnType: "timestamptz",
defaultRaw: "now()",
})
created_at: Date
@Property({
onCreate: () => new Date(),
onUpdate: () => new Date(),
columnType: "timestamptz",
defaultRaw: "now()",
})
updated_at: Date
@Property({ columnType: "text", nullable: true })
created_by: string | null = null
@deletedAtIndexStatement.MikroORMIndex()
@Property({ columnType: "timestamptz", nullable: true })
deleted_at: Date | null = null
@BeforeCreate()
onCreate() {
this.id = generateEntityId(this.id, "txrule")
}
@OnInit()
onInit() {
this.id = generateEntityId(this.id, "txrule")
}
}
export default TaxRateRule
+33 -122
View File
@@ -1,128 +1,39 @@
import { DAL } from "@medusajs/framework/types"
import {
createPsqlIndexStatementHelper,
DALUtils,
generateEntityId,
Searchable,
} from "@medusajs/framework/utils"
import {
BeforeCreate,
Cascade,
Collection,
Entity,
Filter,
ManyToOne,
OneToMany,
OnInit,
OptionalProps,
PrimaryKey,
Property,
Rel,
} from "@mikro-orm/core"
import { model } from "@medusajs/framework/utils"
import TaxRateRule from "./tax-rate-rule"
import TaxRegion from "./tax-region"
type OptionalTaxRateProps = DAL.SoftDeletableModelDateColumns
const TABLE_NAME = "tax_rate"
export const singleDefaultRegionIndexName = "IDX_single_default_region"
const singleDefaultRegionIndexStatement = createPsqlIndexStatementHelper({
name: singleDefaultRegionIndexName,
tableName: TABLE_NAME,
columns: "tax_region_id",
unique: true,
where: "is_default = true AND deleted_at IS NULL",
})
const taxRegionIdIndexName = "IDX_tax_rate_tax_region_id"
const taxRegionIdIndexStatement = createPsqlIndexStatementHelper({
name: taxRegionIdIndexName,
tableName: TABLE_NAME,
columns: "tax_region_id",
where: "deleted_at IS NULL",
})
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
tableName: TABLE_NAME,
columns: "deleted_at",
where: "deleted_at IS NOT NULL",
})
@singleDefaultRegionIndexStatement.MikroORMIndex()
@Entity({ tableName: TABLE_NAME })
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
export default class TaxRate {
[OptionalProps]?: OptionalTaxRateProps
@PrimaryKey({ columnType: "text" })
id!: string
@Property({ columnType: "real", nullable: true })
rate: number | null = null
@Searchable()
@Property({ columnType: "text" })
code: string
@Searchable()
@Property({ columnType: "text" })
name: string
@Property({ columnType: "bool", default: false })
is_default: boolean = false
@Property({ columnType: "bool", default: false })
is_combinable: boolean = false
@ManyToOne(() => TaxRegion, {
columnType: "text",
fieldName: "tax_region_id",
mapToPk: true,
onDelete: "cascade",
const TaxRate = model
.define("TaxRate", {
id: model.id({ prefix: "txr" }).primaryKey(),
rate: model.float().nullable(),
code: model.text().searchable(),
name: model.text().searchable(),
is_default: model.boolean().default(false),
is_combinable: model.boolean().default(false),
tax_region: model.belongsTo(() => TaxRegion, {
mappedBy: "tax_rates",
}),
rules: model.hasMany(() => TaxRateRule, {
mappedBy: "tax_rate",
}),
metadata: model.json().nullable(),
created_by: model.text().nullable(),
})
@taxRegionIdIndexStatement.MikroORMIndex()
tax_region_id: string
@ManyToOne({ entity: () => TaxRegion, persist: false })
tax_region: Rel<TaxRegion>
@OneToMany(() => TaxRateRule, (rule) => rule.tax_rate, {
cascade: ["soft-remove" as Cascade],
.indexes([
{
name: "IDX_tax_rate_tax_region_id",
on: ["tax_region_id"],
where: "deleted_at IS NULL",
},
{
name: "IDX_single_default_region",
on: ["tax_region_id"],
unique: true,
where: "is_default = true AND deleted_at IS NULL",
},
])
.cascades({
delete: ["rules"],
})
rules = new Collection<Rel<TaxRateRule>>(this)
@Property({ columnType: "jsonb", nullable: true })
metadata: Record<string, unknown> | null = null
@Property({
onCreate: () => new Date(),
columnType: "timestamptz",
defaultRaw: "now()",
})
created_at: Date
@Property({
onCreate: () => new Date(),
onUpdate: () => new Date(),
columnType: "timestamptz",
defaultRaw: "now()",
})
updated_at: Date
@Property({ columnType: "text", nullable: true })
created_by: string | null = null
@deletedAtIndexStatement.MikroORMIndex()
@Property({ columnType: "timestamptz", nullable: true })
deleted_at: Date | null = null
@BeforeCreate()
onCreate() {
this.id = generateEntityId(this.id, "txr")
}
@OnInit()
onInit() {
this.id = generateEntityId(this.id, "txr")
}
}
export default TaxRate
+51 -143
View File
@@ -1,153 +1,61 @@
import { DAL } from "@medusajs/framework/types"
import {
createPsqlIndexStatementHelper,
DALUtils,
generateEntityId,
Searchable,
} from "@medusajs/framework/utils"
import {
BeforeCreate,
Cascade,
Check,
Collection,
Entity,
Filter,
ManyToOne,
OneToMany,
OnInit,
OptionalProps,
PrimaryKey,
Property,
Rel,
} from "@mikro-orm/core"
import { model } from "@medusajs/framework/utils"
import TaxProvider from "./tax-provider"
import TaxRate from "./tax-rate"
type OptionalTaxRegionProps = DAL.SoftDeletableModelDateColumns
const TABLE_NAME = "tax_region"
export const countryCodeNullProvinceIndexName =
"IDX_tax_region_unique_country_nullable_province"
export const countryCodeProvinceIndexName =
"IDX_tax_region_unique_country_province"
const countryCodeProvinceIndexStatement = createPsqlIndexStatementHelper({
name: countryCodeProvinceIndexName,
tableName: TABLE_NAME,
columns: ["country_code", "province_code"],
unique: true,
where: "deleted_at IS NULL",
})
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
tableName: TABLE_NAME,
columns: "deleted_at",
where: "deleted_at IS NOT NULL",
})
const countryCodeNullableProvinceIndexStatement =
createPsqlIndexStatementHelper({
name: countryCodeNullProvinceIndexName,
tableName: TABLE_NAME,
columns: ["country_code"],
unique: true,
where: "province_code IS NULL AND deleted_at IS NULL",
})
export const taxRegionProviderTopLevelCheckName =
"CK_tax_region_provider_top_level"
export const taxRegionCountryTopLevelCheckName =
"CK_tax_region_country_top_level"
@Check({
name: taxRegionProviderTopLevelCheckName,
expression: `parent_id IS NULL OR provider_id IS NULL`,
})
@Check({
name: taxRegionCountryTopLevelCheckName,
expression: `parent_id IS NULL OR province_code IS NOT NULL`,
})
@countryCodeNullableProvinceIndexStatement.MikroORMIndex()
@countryCodeProvinceIndexStatement.MikroORMIndex()
@Entity({ tableName: TABLE_NAME })
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
export default class TaxRegion {
[OptionalProps]?: OptionalTaxRegionProps
@PrimaryKey({ columnType: "text" })
id!: string
@ManyToOne(() => TaxProvider, {
fieldName: "provider_id",
mapToPk: true,
nullable: true,
const TaxRegion = model
.define("TaxRegion", {
id: model.id({ prefix: "txreg" }).primaryKey(),
country_code: model.text().searchable(),
province_code: model.text().searchable().nullable(),
metadata: model.json().nullable(),
created_by: model.text().nullable(),
provider: model
.belongsTo(() => TaxProvider, {
mappedBy: "regions",
})
.nullable(),
parent: model
.belongsTo(() => TaxRegion, {
mappedBy: "children",
})
.nullable(),
children: model.hasMany(() => TaxRegion, {
mappedBy: "parent",
}),
tax_rates: model.hasMany(() => TaxRate, {
mappedBy: "tax_region",
}),
})
provider_id: string | null = null
@ManyToOne(() => TaxProvider, { persist: false })
provider: Rel<TaxProvider>
@Searchable()
@Property({ columnType: "text" })
country_code: string
@Searchable()
@Property({ columnType: "text", nullable: true })
province_code: string | null = null
@ManyToOne(() => TaxRegion, {
index: "IDX_tax_region_parent_id",
fieldName: "parent_id",
onDelete: "cascade",
mapToPk: true,
nullable: true,
.checks([
{
name: taxRegionProviderTopLevelCheckName,
expression: `parent_id IS NULL OR provider_id IS NULL`,
},
{
name: taxRegionCountryTopLevelCheckName,
expression: `parent_id IS NULL OR province_code IS NOT NULL`,
},
])
.indexes([
{
name: "IDX_tax_region_unique_country_province",
on: ["country_code", "province_code"],
unique: true,
where: "deleted_at IS NULL",
},
{
name: "IDX_tax_region_unique_country_nullable_province",
on: ["country_code"],
unique: true,
where: "province_code IS NULL AND deleted_at IS NULL",
},
])
.cascades({
delete: ["children", "tax_rates"],
})
parent_id: string | null = null
@ManyToOne(() => TaxRegion, { persist: false })
parent: Rel<TaxRegion>
@OneToMany(() => TaxRate, (label) => label.tax_region, {
cascade: ["soft-remove" as Cascade],
})
tax_rates = new Collection<TaxRate>(this)
@OneToMany(() => TaxRegion, (label) => label.parent, {
cascade: ["soft-remove" as Cascade],
})
children = new Collection<Rel<TaxRegion>>(this)
@Property({ columnType: "jsonb", nullable: true })
metadata: Record<string, unknown> | null = null
@Property({
onCreate: () => new Date(),
columnType: "timestamptz",
defaultRaw: "now()",
})
created_at: Date
@Property({
onCreate: () => new Date(),
onUpdate: () => new Date(),
columnType: "timestamptz",
defaultRaw: "now()",
})
updated_at: Date
@Property({ columnType: "text", nullable: true })
created_by: string | null = null
@deletedAtIndexStatement.MikroORMIndex()
@Property({ columnType: "timestamptz", nullable: true })
deleted_at: Date | null = null
@BeforeCreate()
onCreate() {
this.id = generateEntityId(this.id, "txreg")
}
@OnInit()
onInit() {
this.id = generateEntityId(this.id, "txreg")
}
}
export default TaxRegion