Inventory Schema
Schema inventory chứa 12 model quản lý mức tồn kho, theo dõi kho, đơn mua hàng, quan hệ nhà cung cấp, và công thức bill-of-materials với theo dõi nguyên vật liệu thô. Nó hỗ trợ kho hàng đa vị trí với nhật ký kiểm toán chi tiết.
Nguồn: packages/core/src/models/schemas/inventory/
Tổng quan Model
| Model | Tên Bảng | Mô tả |
|---|---|---|
| InventoryLocation | inventory.InventoryLocation | Vị trí lưu trữ vật lý hoặc logic |
| InventoryItem | inventory.InventoryItem | Hàng hóa có thể theo dõi liên kết với biến thể sản phẩm hoặc nguyên vật liệu |
| InventoryStock | inventory.InventoryStock | Số lượng tồn kho cho một hàng hóa |
| InventoryTracking | inventory.InventoryTracking | Nhật ký kiểm toán tất cả biến động kho |
| InventoryTrackingType | inventory.InventoryTrackingType | Phân loại biến động theo dõi |
| PurchaseOrder | inventory.PurchaseOrder | Đơn mua hàng từ nhà cung cấp |
| PurchaseOrderItem | inventory.PurchaseOrderItem | Mục hàng trong đơn mua hàng |
| Vendor | inventory.Vendor | Thông tin nhà cung cấp |
| Material | inventory.Material | Nguyên vật liệu thô và bán thành phẩm dùng trong công thức bill-of-materials |
| MaterialIdentifier | inventory.MaterialIdentifier | Định danh theo scheme (SKU, BARCODE, QRCODE, ...) gắn với một Material |
| MaterialRecipe | inventory.MaterialRecipe | Công thức bill-of-materials được đánh phiên bản, gắn với một principal (thường là ProductVariant) |
| MaterialRecipeItem | inventory.MaterialRecipeItem | Một dòng trong MaterialRecipe: một Material được tiêu thụ với số lượng cho trước |
InventoryLocation
Vị trí lưu trữ vật lý hoặc logic với hỗ trợ phân cấp.
| Cột | Kiểu | Ràng buộc | Mô tả |
|---|---|---|---|
identifier | text | NOT NULL, UNIQUE | Tự động tạo (ví dụ: LOC_20260216_...) |
name | jsonb (i18n) | NOT NULL | Tên đa ngôn ngữ |
status | text | NOT NULL, DEFAULT NEW | Trạng thái vị trí (NEW, ACTIVATED, DEACTIVATED, ARCHIVED) |
location | jsonb (ILocation) | Địa chỉ vật lý và tọa độ | |
is_default | boolean | NOT NULL, DEFAULT false | Có phải vị trí mặc định hay không |
merchant_id | text | NOT NULL | FK đến Merchant |
parent_id | text | FK đến InventoryLocation cha | |
| + các cột chung | id, createdAt, modifiedAt, deletedAt, metadata |
InventoryItem
Hàng hóa có thể theo dõi liên kết với principal thông qua tham chiếu đa hình. Principal có thể là Product, ProductVariant, hoặc Material; mặc định là ProductVariant.
| Cột | Kiểu | Ràng buộc | Mô tả |
|---|---|---|---|
item_type | text | Loại thực thể đa hình: Product, ProductVariant, hoặc Material (mặc định: ProductVariant) | |
item_id | text | ID thực thể đa hình | |
identifier | text | NOT NULL, UNIQUE | Tự động tạo (ví dụ: SKU_20260216_...) |
status | text | NOT NULL, DEFAULT ACTIVATED | Trạng thái hàng hóa (ACTIVATED, DEACTIVATED, ARCHIVED) |
min_stock_level | decimal(15,4) | Ngưỡng tồn kho tối thiểu | |
max_stock_level | decimal(15,4) | Ngưỡng tồn kho tối đa | |
base_unit | text | NOT NULL | Đơn vị đo lường cơ bản |
inventory_location_id | text | NOT NULL | FK đến InventoryLocation |
| + các cột chung |
InventoryStock
Số lượng tồn kho cho một hàng hóa. Theo dõi tồn kho thực tế, đã đặt trước, và khả dụng.
| Cột | Kiểu | Ràng buộc | Mô tả |
|---|---|---|---|
quantity_on_hand | decimal(15,4) | NOT NULL, DEFAULT '0' | Tổng tồn kho vật lý |
quantity_reserved | decimal(15,4) | NOT NULL, DEFAULT '0' | Đã phân bổ cho đơn hàng |
quantity_available | decimal(15,4) | NOT NULL, DEFAULT '0' | Khả dụng để bán (thực tế - đặt trước) |
last_counted_at | isoTimestamp | Thời gian kiểm kê vật lý lần cuối | |
last_stocked_at | isoTimestamp | Thời gian nhập kho lần cuối | |
inventory_item_id | text | NOT NULL | FK đến InventoryItem |
| + các cột chung |
InventoryTracking
Bản ghi nhật ký kiểm toán ghi lại mọi biến động kho với số lượng trước/sau.
| Cột | Kiểu | Ràng buộc | Mô tả |
|---|---|---|---|
reference_id | text | ID thực thể tham chiếu (ví dụ: ID SaleOrder, ID PurchaseOrder) | |
reference_type | text | Loại thực thể tham chiếu | |
uom | text | NOT NULL | Đơn vị đo lường cho biến động này |
multiplier | decimal(15,4) | NOT NULL, DEFAULT '1' | Hệ số nhân đơn vị đo |
quantity_before | decimal(15,4) | NOT NULL | Số lượng tồn kho trước biến động |
quantity_change | decimal(15,4) | NOT NULL | Số lượng thay đổi (dương hoặc âm) |
quantity_after | decimal(15,4) | NOT NULL | Số lượng tồn kho sau biến động |
effective_price | decimal(15,4) | Giá mỗi đơn vị cho biến động này | |
inventory_stock_id | text | NOT NULL | FK đến InventoryStock |
inventory_tracking_type_id | text | NOT NULL | FK đến InventoryTrackingType |
note | text | Ghi chú biến động | |
created_by | text | ID người dùng tạo | |
modified_by | text | ID người dùng sửa đổi cuối | |
| + các cột chung |
InventoryTrackingType
Phân loại biến động theo dõi theo hướng (nhập, xuất, trung lập).
| Cột | Kiểu | Ràng buộc | Mô tả |
|---|---|---|---|
type | text | NOT NULL | Mã loại theo dõi |
name | jsonb (i18n) | NOT NULL | Tên đa ngôn ngữ |
description | jsonb (i18n) | Mô tả đa ngôn ngữ | |
direction | text | NOT NULL | Hướng: 000_IN, 100_OUT, 200_NEUTRAL |
status | text | DEFAULT ACTIVATED | Trạng thái (ACTIVATED, DEACTIVATED, ARCHIVED) |
merchant_id | text | FK đến Merchant (null cho loại toàn cục) | |
| + các cột chung |
Ràng buộc duy nhất: (type, merchantId)
Các Loại Theo dõi Tồn kho Cố định
Nhập kho (IN):
| Mã | Giá trị | Mô tả |
|---|---|---|
| STOCK_IN | 000_STOCK_IN | Nhập kho chung |
| PURCHASE | 001_PURCHASE | Nhận từ đơn mua hàng |
| TRANSFER_IN | 002_TRANSFER_IN | Chuyển từ vị trí khác |
| RETURN_FROM_CUSTOMER | 003_RETURN_FROM_CUSTOMER | Khách hàng trả lại |
| ADJUSTMENT_IN | 004_ADJUSTMENT_IN | Điều chỉnh tăng thủ công |
| PRODUCTION_COMPLETE | 005_PRODUCTION_COMPLETE | Sản xuất hoàn thành |
Xuất kho (OUT):
| Mã | Giá trị | Mô tả |
|---|---|---|
| STOCK_OUT | 100_STOCK_OUT | Xuất kho chung |
| SALE | 101_SALE | Bán cho khách hàng |
| TRANSFER_OUT | 102_TRANSFER_OUT | Chuyển đến vị trí khác |
| RETURN_TO_VENDOR | 103_RETURN_TO_VENDOR | Trả lại nhà cung cấp |
| ADJUSTMENT_OUT | 104_ADJUSTMENT_OUT | Điều chỉnh giảm thủ công |
| EXPIRED | 105_EXPIRED | Hàng hết hạn |
| LOST | 106_LOST | Hàng thất lạc |
| DAMAGED | 106_DAMAGED | Hàng hư hỏng |
| USED_INTERNAL | 107_USED_INTERNAL | Sử dụng nội bộ |
| USED_AS_MATERIAL | 107_USED_AS_MATERIAL | Được tiêu thụ như nguyên vật liệu trong luồng BOM/sản xuất |
Trung lập (NEUTRAL):
| Mã | Giá trị | Mô tả |
|---|---|---|
| INVENTORY_COUNT | 200_INVENTORY_COUNT | Kiểm kê vật lý |
| ADJUSTMENT_NEUTRAL | 201_ADJUSTMENT_NEUTRAL | Điều chỉnh trung lập (không thay đổi số lượng) |
PurchaseOrder
Đơn mua hàng từ nhà cung cấp với vòng đời trạng thái giống SaleOrder.
Vòng đời Trạng thái
Giá trị Trạng thái: DRAFT (001_DRAFT), PROCESSING (203_PROCESSING), RECEIVED (205_RECEIVED), COMPLETED (303_COMPLETED), CLOSED (404_CLOSED), CANCELLED (505_CANCELLED)
Active set (có thể sửa hoặc hủy): DRAFT, PROCESSING, RECEIVED, COMPLETED. Receivable set (có thể nhận hàng): PROCESSING, RECEIVED, COMPLETED. Terminal set (chỉ đọc): CLOSED, CANCELLED.
Các Cột
| Cột | Kiểu | Ràng buộc | Mô tả |
|---|---|---|---|
purchase_order_number | text | NOT NULL, UNIQUE | Tự động tạo (ví dụ: 20260216120000-...) |
name | text | Tên đơn hàng (tự động tạo) | |
slug | text | UNIQUE | Định danh thân thiện URL (tự động tạo) |
order_date | isoTimestamp | NOT NULL | Ngày đặt hàng (mặc định hiện tại) |
expected_delivery_date | isoTimestamp | Ngày giao hàng dự kiến | |
actual_delivery_date | isoTimestamp | Ngày giao hàng thực tế | |
status | text | NOT NULL, DEFAULT 001_DRAFT | Trạng thái đơn hàng |
draft_at | isoTimestamp | Thời gian vào trạng thái DRAFT | |
processing_at | isoTimestamp | Thời gian vào trạng thái PROCESSING | |
confirmed_at | isoTimestamp | Thời gian xác nhận | |
received_at | isoTimestamp | Thời gian vào trạng thái RECEIVED | |
completed_at | isoTimestamp | Thời gian vào trạng thái COMPLETED | |
closed_at | isoTimestamp | Thời gian vào trạng thái CLOSED | |
cancelled_at | isoTimestamp | Thời gian vào trạng thái CANCELLED | |
merchant_id | text | NOT NULL | FK đến Merchant |
vendor_id | text | NOT NULL | FK đến Vendor |
inventory_location_id | text | NOT NULL | FK đến InventoryLocation |
currency | text | NOT NULL, DEFAULT 'VND' | Mã tiền tệ |
exchange_rate | decimal(12,6) | DEFAULT '1' | Tỷ giá hối đoái |
subtotal | decimal(15,4) | NOT NULL, DEFAULT '0' | Tổng phụ |
tax | decimal(15,4) | NOT NULL, DEFAULT '0' | Tổng thuế |
discount | decimal(15,4) | NOT NULL, DEFAULT '0' | Tổng giảm giá |
total | decimal(15,4) | NOT NULL, DEFAULT '0' | Tổng cuối cùng |
metadata | jsonb | TPurchaseOrderMetadata | |
created_by | text | ID người dùng tạo | |
modified_by | text | ID người dùng sửa đổi cuối | |
| + các cột chung |
TPurchaseOrderMetadata
type TPurchaseOrderMetadata = {
note?: string;
merchantId?: string;
isDiscountManual?: boolean; // true = use PO.discount, ignore item discounts
isTaxManual?: boolean; // true = use PO.tax, ignore item taxes
[key: string]: any;
};PurchaseOrderItem
Mục hàng trong đơn mua hàng với tham chiếu sản phẩm/nguyên vật liệu đa hình và tổng được tính toán.
| Cột | Kiểu | Ràng buộc | Mô tả |
|---|---|---|---|
purchase_order_id | text | NOT NULL | FK đến PurchaseOrder |
item_type | text | Loại thực thể đa hình: Product, ProductVariant, hoặc Material (mặc định: ProductVariant) | |
item_id | text | ID thực thể đa hình | |
currency | text | NOT NULL, DEFAULT 'VND' | Mã tiền tệ |
uom | text | NOT NULL | Đơn vị đo lường |
multiplier | decimal(15,4) | NOT NULL, DEFAULT '1' | Hệ số nhân đơn vị đo |
quantity | decimal(15,4) | NOT NULL | Số lượng đặt hàng |
received_quantity | decimal(15,4) | NOT NULL, DEFAULT '0' | Số lượng đã nhận |
unit_price | decimal(15,4) | NOT NULL, DEFAULT '0' | Giá mỗi đơn vị |
tax | decimal(15,4) | NOT NULL, DEFAULT '0' | Số tiền thuế |
discount | decimal(15,4) | NOT NULL, DEFAULT '0' | Số tiền giảm giá |
total | decimal(15,4) | NOT NULL, GENERATED | Tính toán: (unit_price * quantity * multiplier + tax - discount) |
created_by | text | ID người dùng tạo | |
modified_by | text | ID người dùng sửa đổi cuối | |
| + các cột chung |
Chế độ Mục: PRODUCT (000_PRODUCT), MATERIAL (001_MATERIAL), CUSTOM (100_CUSTOM)
- PRODUCT mode: dòng hàng tham chiếu đến một ProductVariant (mặc định).
- MATERIAL mode: dòng hàng tham chiếu đến một Material (nguyên liệu thô hoặc bán thành phẩm được mua để tiêu thụ trong BOM).
- CUSTOM mode: dòng hàng tự do, không có tham chiếu SKU — các trường metadata (
name,description,sku,barcode,imageUrl) được dùng thay thế.
Vendor
Thông tin nhà cung cấp.
| Cột | Kiểu | Ràng buộc | Mô tả |
|---|---|---|---|
name | text | NOT NULL | Tên nhà cung cấp |
identifier | text | NOT NULL, UNIQUE | Tự động tạo (ví dụ: VEN_20260216_...) |
emails | text[] | DEFAULT '{}' | Địa chỉ email |
phones | text[] | DEFAULT '{}' | Số điện thoại |
location | jsonb (ILocation) | Địa chỉ vật lý | |
tax_number | text | Mã số thuế | |
note | text | Ghi chú | |
merchant_id | text | NOT NULL | FK đến Merchant |
| + các cột chung |
Material
Nguyên vật liệu thô và bán thành phẩm được sử dụng như các thành phần trong MaterialRecipe (bill-of-materials). Material không phải là hàng bán trực tiếp — chúng tồn tại để được tiêu thụ bởi một recipe sinh ra một ProductVariant có thể bán.
| Cột | Kiểu | Ràng buộc | Mô tả |
|---|---|---|---|
slug | text | NOT NULL | Định danh thân thiện trong phạm vi Merchant |
status | text | NOT NULL, DEFAULT 201_ACTIVATED | Trạng thái (ACTIVATED, DEACTIVATED, ARCHIVED) |
identifier | text | NOT NULL, UNIQUE | Tự động tạo (ví dụ: MAT_20260414_...) |
name | jsonb (i18n) | NOT NULL | Tên đa ngôn ngữ |
description | jsonb (i18n) | Mô tả đa ngôn ngữ | |
merchant_id | text | NOT NULL | FK đến Merchant |
| + các cột chung | id, createdAt, modifiedAt, deletedAt, metadata |
Giá trị Trạng thái: ACTIVATED (201_ACTIVATED), DEACTIVATED (202_DEACTIVATED), ARCHIVED (203_ARCHIVED)
MaterialIdentifier
Định danh theo scheme cho một Material. Cho phép tra cứu Material theo SKU, mã vạch, mã QR, hoặc các hệ thống mã khác. Một Material có thể có nhiều identifier thuộc các scheme khác nhau; cặp (scheme, identifier) là duy nhất toàn cục, nên cùng một mã vạch hoặc SKU không thể đăng ký cho hai Material khác nhau.
| Cột | Kiểu | Ràng buộc | Mô tả |
|---|---|---|---|
scheme | text | NOT NULL, DEFAULT SYSTEM | Scheme định danh (SYSTEM, SLUG, SKU, BARCODE, QRCODE) |
identifier | text | NOT NULL | Giá trị định danh |
material_id | text | NOT NULL | FK đến Material |
| + các cột chung |
Unique index: UQ_MaterialIdentifier_scheme_identifier trên (scheme, identifier).
Schemes: SYSTEM (ID nội bộ, mặc định), SLUG (thân thiện URL), SKU (mã SKU), BARCODE (mã vạch), QRCODE (mã QR).
MaterialRecipe
Công thức bill-of-materials được đánh phiên bản, định nghĩa các Material nào được tiêu thụ để sản xuất một thực thể principal. Principal là đa hình (hiện tại là Product hoặc ProductVariant). Recipe được quản lý phiên bản — một principal có thể có nhiều phiên bản recipe, nhưng chỉ phiên bản được kích hoạt mới được runtime tra cứu.
| Cột | Kiểu | Ràng buộc | Mô tả |
|---|---|---|---|
principal_type | text | Loại principal đa hình: Product hoặc ProductVariant | |
principal_id | text | NOT NULL | ID principal đa hình |
status | text | NOT NULL, DEFAULT 201_ACTIVATED | Trạng thái recipe (DRAFT, ACTIVATED, DEACTIVATED) |
merchantId | text | NOT NULL | FK đến Merchant (chú ý: tên cột camelCase) |
name | jsonb (i18n) | Tên hiển thị tuỳ chọn | |
description | jsonb (i18n) | Mô tả tuỳ chọn | |
version | numeric(10,1) | NOT NULL, DEFAULT '1.0' | Phiên bản recipe |
| + các cột chung |
Unique index: UQ_MaterialRecipe_product_variant_id_version trên (principal_type, principal_id, version). Ngăn recipe trùng phiên bản cho cùng principal.
Giá trị Trạng thái: DRAFT (001_DRAFT), ACTIVATED (201_ACTIVATED), DEACTIVATED (202_DEACTIVATED).
Loại Principal: Product, ProductVariant — được phân giải qua cặp đa hình (principal_type, principal_id).
INFO
Cột merchantId được viết theo camelCase trong cơ sở dữ liệu (khác với các bảng inventory khác dùng snake_case). Đây là di sản lịch sử từ migration 0004_abnormal_photon.sql khi cột này được thêm sau. Khi dùng raw SQL, hãy dùng "merchantId" kèm dấu ngoặc kép.
MaterialRecipeItem
Một dòng trong MaterialRecipe: "tiêu thụ X đơn vị của Material Y". Một recipe có nhiều item; mỗi item tham chiếu đến đúng một Material.
| Cột | Kiểu | Ràng buộc | Mô tả |
|---|---|---|---|
quantity | decimal(15,4) | NOT NULL | Số lượng material tiêu thụ cho mỗi đơn vị sản xuất |
unit | text | NOT NULL | Đơn vị đo lường cho quantity |
material_id | text | NOT NULL | FK đến Material |
material_recipe_id | text | NOT NULL | FK đến MaterialRecipe |
| + các cột chung |
Unique index: UQ_MaterialRecipeItem_material_id_material_recipe_id trên (material_id, material_recipe_id). Một Material chỉ xuất hiện tối đa một lần trong cùng một recipe.
Quan hệ Thực thể
Tài liệu Liên quan
- Tổng quan Cơ sở dữ liệu -- Tóm tắt schema, cột chung, kiểu chia sẻ
- Sơ đồ Quan hệ Thực thể -- ERD toàn diện cho tất cả 55 model
- Public Schema -- 30 model trong public schema
- Pricing Schema -- 7 model định giá
- Allocation Schema -- 4 model phân bổ
- Sale Schema -- 2 model đơn hàng bán
- Finance Schema -- 3 model tài chính
- Payment Schema -- 1 model cấu hình webhook
- Migration -- DDL migration và framework dữ liệu mẫu