feat(tax): introduce tax override data models (#6422)

**What**
- Adds Tax rules to allow overrides of tax rates for certain products, product types or shipping options.

**Punted to future PR**
- Currently, the creation methods only support bulk operations. A later PR will include support for singular operations, too.
- It should be possible to add products, types, and shipping options to a tax rate after creating it. Add, remove, update will come in a later PR.
This commit is contained in:
Sebastian Rindom
2024-02-20 16:50:19 +00:00
committed by GitHub
parent 43ed6a990d
commit 137cc0ebf8
7 changed files with 197 additions and 6 deletions
+1
View File
@@ -1,2 +1,3 @@
export { default as TaxRate } from "./tax-rate"
export { default as TaxRegion } from "./tax-region"
export { default as TaxRateRule } from "./tax-rate-rule"
+55
View File
@@ -0,0 +1,55 @@
import {
Cascade,
Entity,
ManyToOne,
PrimaryKey,
PrimaryKeyProp,
Property,
} from "@mikro-orm/core"
import TaxRate from "./tax-rate"
const TABLE_NAME = "tax_rate_rule"
const taxRateIdIndexName = "IDX_tax_rate_rule_tax_rate_id"
@Entity({ tableName: TABLE_NAME })
export default class TaxRateRule {
@PrimaryKey({ columnType: "text" })
tax_rate_id!: string
@PrimaryKey({ columnType: "text" })
reference_id!: string;
[PrimaryKeyProp]?: ["tax_rate_id", "reference_id"]
@Property({ columnType: "text" })
reference: string
@ManyToOne(() => TaxRate, {
fieldName: "tax_rate_id",
index: taxRateIdIndexName,
cascade: [Cascade.REMOVE, Cascade.PERSIST],
})
tax_rate: 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
}
@@ -13,32 +13,46 @@ import {
MedusaContext,
ModulesSdkUtils,
} from "@medusajs/utils"
import { TaxRate, TaxRegion } from "@models"
import { TaxRate, TaxRegion, TaxRateRule } from "@models"
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
import { TaxRegionDTO } from "@medusajs/types"
type InjectedDependencies = {
baseRepository: DAL.RepositoryService
taxRateService: ModulesSdkTypes.InternalModuleService<any>
taxRegionService: ModulesSdkTypes.InternalModuleService<any>
taxRateRuleService: ModulesSdkTypes.InternalModuleService<any>
}
const generateForModels = [TaxRegion, TaxRateRule]
export default class TaxModuleService<
TTaxRate extends TaxRate = TaxRate,
TTaxRegion extends TaxRegion = TaxRegion
TTaxRegion extends TaxRegion = TaxRegion,
TTaxRateRule extends TaxRateRule = TaxRateRule
>
extends ModulesSdkUtils.abstractModuleServiceFactory<
InjectedDependencies,
TaxTypes.TaxRateDTO,
{ TaxRegion: { dto: TaxTypes.TaxRegionDTO } }
>(TaxRate, [TaxRegion], entityNameToLinkableKeysMap)
{
TaxRegion: { dto: TaxTypes.TaxRegionDTO }
TaxRateRule: { dto: TaxTypes.TaxRateRuleDTO }
}
>(TaxRate, generateForModels, entityNameToLinkableKeysMap)
implements ITaxModuleService
{
protected baseRepository_: DAL.RepositoryService
protected taxRateService_: ModulesSdkTypes.InternalModuleService<TTaxRate>
protected taxRegionService_: ModulesSdkTypes.InternalModuleService<TTaxRegion>
protected taxRateRuleService_: ModulesSdkTypes.InternalModuleService<TTaxRateRule>
constructor(
{ baseRepository, taxRateService, taxRegionService }: InjectedDependencies,
{
baseRepository,
taxRateService,
taxRegionService,
taxRateRuleService,
}: InjectedDependencies,
protected readonly moduleDeclaration: InternalModuleDeclaration
) {
// @ts-ignore
@@ -47,6 +61,7 @@ export default class TaxModuleService<
this.baseRepository_ = baseRepository
this.taxRateService_ = taxRateService
this.taxRegionService_ = taxRegionService
this.taxRateRuleService_ = taxRateRuleService
}
__joinerConfig(): ModuleJoinerConfig {
@@ -85,6 +100,7 @@ export default class TaxModuleService<
return await this.taxRateService_.create(data, sharedContext)
}
@InjectManager("baseRepository_")
async createTaxRegions(
data: TaxTypes.CreateTaxRegionDTO[],
@MedusaContext() sharedContext: Context = {}
@@ -128,4 +144,26 @@ export default class TaxModuleService<
}
)
}
@InjectManager("baseRepository_")
async createTaxRateRules(
data: TaxTypes.CreateTaxRateRuleDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<TaxTypes.TaxRateRuleDTO[]> {
const rules = await this.taxRateRuleService_.create(data, sharedContext)
const result = await this.baseRepository_.serialize<
TaxTypes.TaxRateRuleDTO[]
>(rules, {
populate: true,
})
return result
}
@InjectTransactionManager("baseRepository_")
async createTaxRateRules_(
data: TaxTypes.CreateTaxRateRuleDTO[],
@MedusaContext() sharedContext: Context = {}
) {
return await this.taxRateRuleService_.create(data, sharedContext)
}
}