Skip to content

Domain Model

Tất cả schema do @nx/core sở hữu. Taxation chỉ subclass repository. Root nguồn: packages/core/src/models/schemas/tax/.../pricing/.

1. ERD đầy đủ

2. Entities

TaxGroup

Thuộc tínhGiá trị
Bảngtax.TaxGroup
Nguồnpackages/core/src/models/schemas/tax/tax-group/schema.ts
Soft-delete
Cột Owner IDmerchantId (nullable — null = template hệ thống)

Trường:

TrườngKiểuBắt buộcMặc địnhMô tả
idtextSnowflakeKhóa chính
identifiertextSnowflakeCode ổn định unique (vd VN_DEDUCTION_VAT10)
namejsonbi18n { default, en, vi }
descriptionjsonbi18n
taxMethodtext000_DIRECT / 100_DEDUCTION
statustextACTIVATEDXem enum bên dưới
merchantIdtextMerchant sở hữu; null = system

Enum status: ACTIVATED · DEACTIVATED · ARCHIVED (Statuses).

Index: UQ_TaxGroup_identifier, IDX_TaxGroup_merchantId, IDX_TaxGroup_merchantId_status.

Quan hệ: merchant (M:1 → Merchant.id), items (1:M → TaxGroupItem, relationName taxGroup).

TaxGroupItem

Thuộc tínhGiá trị
Bảngtax.TaxGroupItem
Nguồnpackages/core/src/models/schemas/tax/tax-group-item/schema.ts
Soft-delete
Cột Owner ID— (sở hữu qua parent taxGroupId)

Trường:

TrườngKiểuBắt buộcMặc địnhMô tả
idtextSnowflakeKhóa chính
taxGroupIdtextGroup cha
discriminationTypeIdtextPhân loại thuế (VAT/PIT/...) qua DiscriminationType
typetext100_PERCENTAGETaxMode
valuedecimal(15,4)0Tỷ lệ hoặc số tiền
isInclusivebooleanfalseThuế nhúng trong giá
priorityinteger0Thứ tự áp dụng (tăng dần)
usagetext000_SALE000_SALE / 100_PURCHASE
chargeTargettext000_CUSTOMER000_CUSTOMER / 100_MERCHANT

Index: IDX_TaxGroupItem_discriminationTypeId, IDX_TaxGroupItem_taxGroupId.

Quan hệ: taxGroup (M:1 → TaxGroup.id), discriminationType (M:1 → DiscriminationType.id).

TaxSet

Thuộc tínhGiá trị
Bảngpricing.TaxSet
Nguồnpackages/core/src/models/schemas/pricing/tax-set/schema.ts
Soft-delete
Cột Owner ID— (đa hình principalId/principalType)

Trường:

TrườngKiểuBắt buộcMặc địnhMô tả
idtextSnowflakeKhóa chính
principalIdtextid Product hoặc ProductVariant
principalTypetextProduct (mặc định) / ProductVariant (override)
namejsonbi18n (copy từ TaxGroup)
statustextACTIVATEDXem enum bên dưới
sourceTypetextTaxGroup (auto) / null (thủ công)
sourceIdtextTaxGroup.id khi auto-provision

Enum status: ACTIVATED · DEACTIVATED · ARCHIVED.

Index: partial unique UPI_TaxSet_principalId_principalType_status (where deletedAt IS NULL), IDX_TaxSet_sourceId, IDX_TaxSet_sourceType_sourceId, IDX_TaxSet_status.

Tax

Thuộc tínhGiá trị
Bảngpricing.Tax
Nguồnpackages/core/src/models/schemas/pricing/tax/schema.ts
Soft-delete
Cột Owner ID— (sở hữu qua taxSetId)

Trường (liên quan provisioning):

TrườngKiểuBắt buộcMặc địnhMô tả
idtextSnowflakeKhóa chính
namejsonbi18n (từ DiscriminationType / group)
typetext100_PERCENTAGETaxMode
valuedecimal(15,4)Tỷ lệ hoặc số tiền
effectiveFromtimestamptzthời điểm provisionKhi thuế bắt đầu active
effectiveTotimestamptzHết hạn (null = mở)
priorityinteger0Thứ tự áp dụng
isInclusivebooleanfalseNhúng trong giá
shouldApplyOnDiscountedbooleantrueÁp trên base đã giảm giá
isCompoundbooleantrueCộng dồn trên thuế trước
usagetext000_SALESale/purchase
statustextACTIVATED
chargeTargettext000_CUSTOMERCustomer/merchant
taxSetIdtextSet cha
taxTypeIdtextFK legacy tới TaxType (dual-write, nullable)
discriminationTypeIdtextPhân loại (authoritative)

Index: IDX_Tax_discriminationTypeId, IDX_Tax_status, IDX_Tax_taxSetId, IDX_Tax_taxTypeId.

TaxType

Thuộc tínhGiá trị
Bảngpricing.TaxType
Nguồnpackages/core/src/models/schemas/pricing/tax-type/schema.ts
Soft-delete
Cột Owner IDmerchantId (nullable)

Enum type (FixedTaxTypes): 000_VAT, 100_EXCISE, 200_ENVIRONMENTAL, 300_LUXURY, 400_PIT, 999_CUSTOM. chargeTarget: 000_CUSTOMER / 100_MERCHANT. Unique (type, merchantId). Phân loại legacy — DiscriminationType (scope tax_classification) giờ là authoritative; Tax.taxTypeId giữ làm fallback dual-write (ADR-0002).

Bảng tham chiếu VN (read-only)

BảngCột keyFK
tax.VnAdministrativeUnitcodeName (UK), fullName, shortName (+ *_en)
tax.VnProvincecode (UK), name, fullName, administrativeUnitCodeVnAdministrativeUnit.codeName
tax.VnWardcode (UK), name, provinceCode, administrativeUnitCodeVnProvince.code, VnAdministrativeUnit.codeName

Phục vụ read-only; không được seed bởi migration của package này (load bên ngoài).

3. Bất biến xuyên entity

Bất biếnCách thực thi
Nhiều nhất một TaxSet ACTIVATED cho mỗi (principalId, principalType)Partial unique index UPI_TaxSet_principalId_principalType_status (where not deleted)
Provision idempotent cho cùng source groupTaxProvisioningService skip khi TaxSet active có sourceType=TaxGroupsourceId khớp
Chỉ TaxSet có nguồn TaxGroup bị deactivate khi (de)provision_deactivateExistingTaxSet guard trên sourceType === TaxGroup
Merchant taxMethod phải khớp TaxGroup.taxMethodTaxGroupService.validateTaxGroupForMerchant (DIRECT ≠ DEDUCTION)
Mỗi Tax được provision phản chiếu một TaxGroupItemprovisionForProduct lặp các item của group

4. Hành vi Soft-delete

Hành viChi tiết
Đọc mặc địnhdeletedAt IS NULL (model defaultFilter)
DeprovisionLật status thành DEACTIVATEDkhông phải soft-delete (dòng tích lũy)
Hard-deleteKhông bao giờ theo mặc định
RestoreRe-provision tạo một TaxSet ACTIVATED mới; các dòng DEACTIVATED trước vẫn còn

5. Trang liên quan

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.