Skip to content

Sản phẩm & Kho — Business Rules

Tổng quan

Domain này bao phủ hai lớp khác nhau nhưng gắn chặt với nhau:

  • Product master: sản phẩm, danh mục, nhóm, loại, đơn vị, nguồn gốc, nhà cung cấp.
  • Inventory operations: tồn kho, phiếu nhập/xuất, phiếu chuyển, kiểm kho, nội bộ, shipping note.

Điểm khó nhất của domain này là dữ liệu tồn kho không nằm ở một bảng duy nhất. Source of truth thực tế là:

  • product_supplying cho movement/ledger,
  • product_sku_stockproduct_lot_no_stock cho số dư đọc nhanh.

Product master

Thành phần chính

Thành phầnVai trò
productBản ghi sản phẩm/DV gốc
product_contentsNội dung đa ngôn ngữ
product_category_referenceGắn category nhiều-nhiều
supplier / product_supplyingNhà cung cấp + lịch sử nhập/xuất theo supplier
product_group, product_type, product_unit, product_originMaster data bổ trợ
branch_productKhả năng bán/cấu hình theo chi nhánh

Quy tắc nghiệp vụ

Quy tắc
BR-PI-001Product master là đa ngôn ngữ qua product_contents, không phải chỉ một cột name duy nhất.
BR-PI-002Category của sản phẩm là many-to-many qua product_category_reference.
BR-PI-003Supplier không phải quan hệ 1-1 đơn giản; một sản phẩm có thể gắn nhiều supplier/movement khác nhau.
BR-PI-004Cùng một product có thể chạy ở nhiều chi nhánh với cấu hình riêng qua branch_product.

Mô hình tồn kho

Ledger vs Snapshot

text
Product
  -> ProductSupplying (mọi movement: nhập, xuất, hold, release, transfer ship/receive)
  -> ProductSkuStock (snapshot theo SKU/kho)
  -> ProductLotNoStock (snapshot theo lot/kho)

Ý nghĩa nghiệp vụ

Bảng / viewVai trò
product_supplyingSổ cái tồn kho theo movement
product_sku_stockSố dư hiện tại theo SKU/kho
product_lot_no_stockSố dư hiện tại theo lot/kho

Quy tắc nghiệp vụ

Quy tắc
BR-PI-005Tồn kho thực tế để xem list/detail lấy từ product_sku_stock hoặc product_lot_no_stock, không lấy trực tiếp từ ledger.
BR-PI-006Ledger product_supplying ghi nhiều loại movement khác nhau; muốn đọc đúng phải biết source document.
BR-PI-007Snapshot tồn kho phụ thuộc scheduler refresh materialized view, nên có thể lệch nhẹ so với real-time event.

Nhập kho từ supplier

text
Tạo import request
  -> chọn kho nhận
  -> nhập SKU / supplier / lot / expiry / quantity / discount
  -> validate file hoặc form
  -> release / complete document
  -> sinh movement nhập kho

Quy tắc nghiệp vụ

Quy tắc
BR-PI-008SKU phải hợp lệ, supplier code phải thuộc đúng product.
BR-PI-009quantity > 0, expiry phải lớn hơn hiện tại.
BR-PI-010Discount không được vượt giá nhập hoặc vượt 100%.
BR-PI-011Kho nhận nhập từ supplier bị filter: kho không phải sales, hoặc là sales nhưng imported_product = true.

Xuất kho / phiếu xuất

text
Tạo export request
  -> chọn loại xuất, kho xuất, danh sách item
  -> duyệt / release
  -> inventory_document update status
  -> cập nhật order / notification / movement

Quy tắc nghiệp vụ

Quy tắc
BR-PI-012changeInventoryDocumentStatus hiện chỉ xử lý rõ 2 nhánh inventory_releasedinventory_canceled.
BR-PI-013Nhiều side effect của phiếu xuất nằm ở event update status, không nằm trong mutation FE.

Kiểm kho

text
Tạo check sheet
  -> đếm thực tế theo lot/SKU
  -> submit chênh lệch
  -> chuyển balanced
  -> hệ thống tự sinh phiếu nhập hoặc xuất bù chênh lệch

Quy tắc nghiệp vụ

Quy tắc
BR-PI-014Khi check sheet balanced, hệ thống tự sinh phiếu nhập/xuất phần chênh ngay trên cùng kho kiểm.
BR-PI-015UI chặn đổi trạng thái nếu còn item chưa gán lot_number.

Chuyển kho / chuyển hàng / nội bộ

Domain này có ít nhất 2 lớp dễ nhầm:

LuồngMô tả
inventory_request / order_transferRequest và order vận hành cho luồng chuyển
shipping_note / transfer_goodsChuyển hàng thực nhận, tạo movement ship/receive

Quy tắc nghiệp vụ

Quy tắc
BR-PI-016Transfer request khi complete sẽ sinh order_transfer; luồng không dừng ở request.
BR-PI-017shipping_note ở trạng thái delivered tạo xuất âm; received tạo nhập dương; canceled xóa movement liên quan.
BR-PI-018Complete internal/transfer order bị chặn nếu còn inventory document ở trạng thái inventory_new.

Rủi ro / Findings

MứcMô tả
P1product_supplying ôm quá nhiều nghĩa, rất dễ bị hiểu nhầm là bảng snapshot.
P1Có hai lớp transfer song song (inventory_request/order_transfershipping_note/transfer_goods) nên tài liệu cũ dễ mô tả sai.
P2List import đang reuse hook/query của export và phân biệt bằng type_id = import, làm semantics FE khó đọc.
P2Route/menu naming của transfer/internal chưa sát nghĩa business, dễ gây hiểu nhầm cho người mới.
P2Snapshot tồn kho phụ thuộc scheduler refresh product_sku_stock, nên số liệu không hẳn realtime tuyệt đối.