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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user