TÀI LIỆU ĐẶC TẢ YÊU CẦU PHẦN MỀM (SRS)
HỆ THỐNG: NỀN TẢNG TRUY XUẤT NGUỒN GỐC GOTRACE
TXNG-F09 – Quản lý Danh sách Lô mã
Thông tin
Chi tiết
Phiên bản
1.0
Ngày tạo
13/03/2026
Tác giả
GoTrace Team
Người review
Người phê duyệt
Lịch sử thay đổi
Ngày
Người cập nhật
Mô tả thay đổi
13/03/2026
GoTrace Team
Khởi tạo tài liệu v1.0
21/04/2026
GoTrace Team
v1.1 — Bổ sung 2 trạng thái DELIVERED và COMBO_ASSEMBLED để phục vụ TXNG-F32 (Combo/Kit tại Điểm Bán). DELIVERED đại diện UID đã giao đến điểm bán (từ F08). COMBO_ASSEMBLED là trạng thái reversible khi UID đang tham gia 1 combo ACTIVE — có thể chuyển lại DELIVERED khi combo bị tháo (Decompose). Cập nhật CHECK constraint trong Migration SQL và mô tả transition.
15/05/2026
GoTrace Team
v1.2 — Bổ sung trạng thái DESTROYED (terminal) phục vụ TXNG-F39 (Quản lý Tiêu hủy Sản phẩm). Thêm 2 cột destroyed_quantity (cộng dồn) + destroyed_at vào bảng batches. Bổ sung BR-F09-11, BR-F09-12 về lifecycle DESTROYED.
1. Tổng quan tài liệu
1.1. Mục đích tài liệu
Tài liệu này mô tả chi tiết quy trình nghiệp vụ và yêu cầu chức năng của chức năng Quản lý Danh sách Lô mã (TXNG-F09) trong Module Truy Xuất Nguồn Gốc (TXNG) của hệ thống GoTrace.
Chức năng cho phép Doanh nghiệp/Cơ sở sản xuất quản lý các lô sản xuất (batch/lot), bao gồm: tạo lô mã theo kế hoạch sản xuất, gán mã lô cho sản phẩm, theo dõi trạng thái lô từ sản xuất đến phân phối. Mỗi lô mã được liên kết với nhật ký sản xuất, vật tư sử dụng, và mã QR truy xuất. Đây là thành phần trung tâm của hệ thống truy xuất nguồn gốc, kết nối tất cả các sự kiện CTE trong chuỗi cung ứng.
Tài liệu là cơ sở cho đội ngũ phát triển (Developer), kiểm thử (QA), và các bên liên quan trong việc hiểu rõ yêu cầu kỹ thuật – nghiệp vụ.
1.2. Thông tin chức năng
Thuộc tính
Giá trị
Mã chức năng
TXNG-F09
Tên chức năng
Quản lý Danh sách Lô mã
Menu
TXNG > Mã hóa & Tem > Quản lý Danh sách Lô mã
Ưu tiên
Bắt buộc
Giai đoạn
v1.0
Pháp lý
TCVN 12850:2019, TT 02/2024/TT-BKHCN, GS1 Standard (GTIN, SSCC)
Liên thông
→ TXNG-F05 (Nhật ký Trồng trọt)
→ TXNG-F06 (Nhật ký Chăn nuôi)
→ TXNG-F07 (Nhật ký Sơ chế – Chế biến – Đóng gói)
→ TXNG-F08 (Nhật ký Phân phối – Vận chuyển)
→ TXNG-F16 (Cấp mã QRcode)
1.3. Tác nhân tham gia (Actors)
Actor
Vai trò
Quyền hạn
ENTERPRISE_ADMIN
Quản trị viên Doanh nghiệp
Tạo, sửa, xóa lô mã; quản lý kế hoạch SX; cấu hình đánh số lô
ENTERPRISE_USER
Nhân viên Doanh nghiệp
Tạo mới, sửa lô do mình tạo; ghi nhận sản lượng
SO_ADMIN
Quản trị viên Sở
Xem danh sách lô mã toàn tỉnh (read-only)
SYSTEM
Hệ thống tự động
Tự động sinh mã lô, cập nhật trạng thái, kiểm tra hết hạn
1.4. Tham chiếu UI/UX
Tài liệu
Link
Mockup
(đính kèm link/attach file)
Design
(đính kèm link/attach file)
2. Luồng nghiệp vụ (Business Flow)
2.1. Luồng nghiệp vụ tổng quan
┌──────────────────────────────────────────────────────────────────────────────┐
│ LUỒNG QUẢN LÝ DANH SÁCH LÔ MÃ │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Kế hoạch SX │───>│ Tạo Lô mã │───>│ Gán Nhật ký │ │
│ │ (Production │ │ (Batch) │ │ SX (F05/F06/ │ │
│ │ Plan) │ │ │ │ F07) │ │
│ └──────────────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │
│ │ ▼ │
│ │ ┌──────────────┐ │
│ │ │ Ghi nhận SL │ │
│ │ │ sản xuất │ │
│ │ └──────┬───────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Cấp mã QR │◄───│ Đóng gói │◄───│ Hoàn thành │ │
│ │ (F16) │ │ (F07) │ │ sản xuất │ │
│ └──────┬───────┘ └──────────────┘ └──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Phân phối │───>│ Theo dõi │───>│ Hết hạn / │ │
│ │ (F08) │ │ tồn kho │ │ Thu hồi │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
2.2. Diễn giải luồng
Bước
Mô tả hành động
Hệ thống thực hiện
B1
DN Admin/User lập kế hoạch sản xuất (sản phẩm, số lượng dự kiến, thời gian)
Hệ thống tạo production plan
B2
Tạo lô mã (batch) từ kế hoạch hoặc tạo thủ công
Tự động sinh mã lô theo format, trạng thái = PLANNED
B3
Gán lô mã vào nhật ký sản xuất (F05/F06/F07)
Liên kết batch_id với production_log
B4
Ghi nhận sản lượng thực tế trong quá trình SX
Cập nhật actual_quantity, trạng thái → IN_PRODUCTION
B5
Hoàn thành sản xuất → Đóng gói (F07)
Trạng thái → PRODUCED
B6
Cấp mã QR cho lô (F16)
Liên kết QR code với batch
B7
Phân phối lô hàng (F08)
Trạng thái → DISTRIBUTED
B8
Theo dõi tồn kho, hết hạn
SYSTEM tự động kiểm tra + cảnh báo
3. Phân loại Lô mã
3.1. Trạng thái Lô mã (Batch Status)
Trạng thái
Mã
Mô tả
Màu hiển thị
Kế hoạch
PLANNED
Lô mã đã tạo từ kế hoạch SX, chưa bắt đầu
⚪ Xám
Đang sản xuất
IN_PRODUCTION
Đang trong quá trình sản xuất
🔵 Xanh dương
Đã sản xuất
PRODUCED
Hoàn thành SX, chờ đóng gói/xuất kho
🟡 Vàng
Đã đóng gói
PACKAGED
Đã đóng gói, sẵn sàng xuất
🟢 Xanh lá nhạt
Đang phân phối
DISTRIBUTING
Đang trong quá trình phân phối
🟠 Cam
Đã phân phối
DISTRIBUTED
Đã giao hết cho điểm bán/kho
🟢 Xanh lá
Đã giao điểm bán
DELIVERED
(v1.1) UID đã giao đến điểm bán (F08 CTE-DIST-04 xác nhận). Sẵn sàng bán lẻ hoặc đưa vào combo (F32).
🟢 Xanh lá đậm
Khoá trong Combo
COMBO_ASSEMBLED
(v1.1) UID đang tham gia 1 combo ACTIVE (F32). Không bán lẻ được. Reversible: khi combo bị tháo (Decompose) → quay lại DELIVERED.
🟣 Tím
Đã hết
DEPLETED
Tồn kho = 0
⚫ Xám đậm
Thu hồi
RECALLED
Lô bị thu hồi do vấn đề chất lượng
🔴 Đỏ
Hết hạn
EXPIRED
Đã quá hạn sử dụng
🔴 Đỏ đậm
Đã tiêu hủy
DESTROYED
(v1.2) Đã tiêu hủy hoàn toàn qua F39 (BATCH_FULL EXECUTED). Terminal — không thể phân phối, vận chuyển, đưa vào combo F32, hoặc recall thêm.
🔴 Đỏ đậm
Hủy
CANCELLED
Lô bị hủy trước khi SX
⚫ Đen
Transition liên quan F32 (Combo/Kit):
DISTRIBUTED ──(CTE-DIST-04 tại POS)──> DELIVERED ◄──(Decompose F32)──┐
│ │
└──(Compose F32)──> COMBO_ASSEMBLED
│
└──(Sold, hoá đơn)──> DEPLETED
DELIVERED ↔ COMBO_ASSEMBLED: reversible qua F32 OP-1 (Compose) và OP-3 (Decompose).
COMBO_ASSEMBLED → RECALLED: khi UID bị thu hồi riêng (F13 trực tiếp), cascade combo (F32 OP-4) cũng sẽ flag combo cha.
Ràng buộc: UID chỉ thay đổi giữa DELIVERED ↔ COMBO_ASSEMBLED do hệ thống F32 trigger, không cho sửa trực tiếp qua UI.
3.2. Loại lô mã
Mã
Tên
Mô tả
CROP
Lô trồng trọt
Sản phẩm từ trồng trọt (rau, quả, lúa...)
LIVESTOCK
Lô chăn nuôi
Sản phẩm từ chăn nuôi (thịt, trứng, sữa...)
AQUACULTURE
Lô thủy sản
Sản phẩm thủy sản
PROCESSED
Lô chế biến
Sản phẩm đã qua chế biến
4. Danh sách màn hình
Mã màn hình
Tên màn hình
Chức năng chính
Vai trò sử dụng
Ghi chú
SCR-F09-01
Danh sách Lô mã
Hiển thị, tìm kiếm, lọc danh sách lô mã
ENTERPRISE_ADMIN, ENTERPRISE_USER, SO_ADMIN
Màn hình chính
SCR-F09-02
Tạo mới / Chỉnh sửa Lô mã
Form tạo/sửa lô mã
ENTERPRISE_ADMIN, ENTERPRISE_USER
SCR-F09-03
Chi tiết Lô mã
Xem toàn bộ thông tin lô + chuỗi truy xuất
Tất cả vai trò
Read-only, timeline
SCR-F09-04
Kế hoạch Sản xuất
Quản lý danh sách kế hoạch sản xuất
ENTERPRISE_ADMIN, ENTERPRISE_USER
Tạo lô từ kế hoạch
SCR-F09-05
Tạo Kế hoạch SX
Form tạo/sửa kế hoạch sản xuất
ENTERPRISE_ADMIN
SCR-F09-06
Dashboard Lô mã
Tổng quan lô mã, tồn kho, hết hạn
ENTERPRISE_ADMIN, SO_ADMIN
Dashboard
5. Mô tả chi tiết trường dữ liệu từng màn hình
5.1. SCR-F09-01: Danh sách Lô mã
Thanh công cụ (Toolbar):
Phần tử
Loại
Mô tả
Tìm kiếm
Text Input
Tìm theo mã lô, tên sản phẩm, mã QR
Lọc theo trạng thái
Dropdown
PLANNED / IN_PRODUCTION / PRODUCED / PACKAGED / DISTRIBUTING / DISTRIBUTED / ... / Tất cả
Lọc theo loại lô
Dropdown
CROP / LIVESTOCK / AQUACULTURE / PROCESSED / Tất cả
Lọc theo sản phẩm
Dropdown (Search)
Danh sách sản phẩm của DN
Lọc theo khoảng thời gian
Date Range Picker
Từ ngày SX – Đến ngày
Nút "Tạo lô"
Button (Primary)
Mở SCR-F09-02 (ENTERPRISE_ADMIN, ENTERPRISE_USER)
Nút "Tạo từ KH SX"
Button (Secondary)
Chuyển đến SCR-F09-04 để chọn kế hoạch
Nút "Xuất Excel"
Button (Secondary)
Xuất danh sách
Bảng dữ liệu (Data Table):
Cột
Kiểu
Sortable
Mô tả
STT
Number
Không
Số thứ tự
Mã lô
Text (Link)
Có
Mã lô sản xuất (auto-generated)
Sản phẩm
Text
Có
Tên sản phẩm
Loại lô
Tag
Có
CROP/LIVESTOCK/... (color-coded)
SL kế hoạch
Number
Có
Số lượng dự kiến
SL thực tế
Number
Có
Số lượng sản xuất thực tế
Tồn kho
Number
Có
Số lượng còn tồn
Ngày SX
Date
Có
Ngày bắt đầu sản xuất
Ngày hết hạn
Date
Có
Ngày hết hạn sử dụng
Trạng thái
Badge
Có
Color-coded status
QR Code
Icon
Không
Icon link đến mã QR (nếu đã cấp)
Thao tác
Actions
Không
Xem / Sửa / Cấp QR / Hủy
Phân trang: 10 / 20 / 50 / 100 bản ghi/trang.
5.2. SCR-F09-02: Tạo mới / Chỉnh sửa Lô mã
5.2.1. Thông tin lô mã
Tên trường
Field name
Kiểu dữ liệu
Bắt buộc
Validation
Mô tả
Mã lô
batch_code
Text (auto)
Có
Auto: LOT-{TYPE}-{YYYYMMDD}-
Mã lô tự động sinh
Loại lô
batch_type
Dropdown
Có
CROP/LIVESTOCK/AQUACULTURE/PROCESSED
Loại lô sản xuất
Sản phẩm
product_id
Dropdown (Search)
Có
Danh sách sản phẩm đang hoạt động
Sản phẩm của lô
Kế hoạch SX
production_plan_id
Dropdown
Không
Danh sách kế hoạch chưa hoàn thành
Liên kết với kế hoạch (nếu có)
Vùng sản xuất
production_area_id
Dropdown
Có
Danh sách vùng SX của DN
Nơi sản xuất
SL kế hoạch
planned_quantity
Decimal (15,3)
Có
> 0
Số lượng dự kiến SX
Đơn vị tính
unit
Dropdown
Có
kg/tấn/con/quả/lít/thùng
Đơn vị đo lường
Ngày bắt đầu SX
production_start_date
Date
Có
≤ ngày kết thúc
Ngày bắt đầu sản xuất
Ngày kết thúc SX (dự kiến)
production_end_date
Date
Không
≥ production_start_date
Ngày dự kiến hoàn thành
Ngày sản xuất (ghi trên SP)
manufacture_date
Date
Không
Ngày SX ghi trên bao bì
Hạn sử dụng
expiry_date
Date
Không
> manufacture_date
Ngày hết hạn sử dụng
Điều kiện bảo quản
storage_conditions
Text (0-300)
Không
VD: "Bảo quản 2-8°C"
Tiêu chuẩn áp dụng
applied_standards
Multi-select
Không
VietGAP/GlobalGAP/Organic/HACCP/ISO22000
Tiêu chuẩn SX
Ghi chú
notes
Textarea (0-1000)
Không
5.2.2. Thông tin bổ sung (theo loại lô)
Loại: CROP (Trồng trọt)
Tên trường
Field name
Kiểu
Bắt buộc
Mô tả
Giống cây trồng
crop_variety
Text (0-200)
Không
Tên giống
Mùa vụ
crop_season
Text (0-100)
Không
VD: "Đông Xuân 2026"
Diện tích (ha)
area_hectares
Decimal
Không
Diện tích canh tác
Loại: LIVESTOCK (Chăn nuôi)
Tên trường
Field name
Kiểu
Bắt buộc
Mô tả
Loài
species
Dropdown
Có
Lợn/Bò/Gà/Vịt/...
Giống
breed
Text (0-200)
Không
Giống vật nuôi
Số lượng con
animal_count
Integer
Không
Số đầu con trong lô
Loại: AQUACULTURE (Thủy sản)
Tên trường
Field name
Kiểu
Bắt buộc
Mô tả
Loài thủy sản
aqua_species
Dropdown
Có
Cá/Tôm/Cua/...
Ao/Bể
pond_id
Dropdown
Không
Mã ao nuôi
Mật độ thả (con/m²)
stocking_density
Decimal
Không
5.3. SCR-F09-03: Chi tiết Lô mã
Section
Nội dung
Thông tin lô
Mã lô, Sản phẩm, Loại, SL kế hoạch/thực tế/tồn kho, Trạng thái
Mã QR
QR code image + link download, mã GTIN (nếu có)
Kế hoạch SX
Thông tin kế hoạch liên kết (nếu có)
Chuỗi truy xuất (Timeline)
Timeline dọc: Tất cả CTE events liên quan đến lô: SX → Đóng gói → Phân phối
Nhật ký SX liên kết
Bảng: Mã nhật ký, Loại (F05/F06/F07), Ngày, CTE events
Vật tư sử dụng
Bảng: Tên vật tư, Loại, Liều lượng, Ngày sử dụng (từ F04)
Lịch sử phân phối
Bảng: Mã phiếu (F08), Kho xuất, Điểm nhận, SL, Ngày
Tồn kho theo kho
Bảng: Kho, SL tồn, Ngày nhập gần nhất
Lịch sử thay đổi
Timeline: Ngày, Người, Hành động, Chi tiết
5.4. SCR-F09-04: Kế hoạch Sản xuất
Bảng dữ liệu:
Cột
Kiểu
Mô tả
Mã KH
Text (Link)
Mã kế hoạch (auto)
Sản phẩm
Text
Tên sản phẩm
SL kế hoạch
Number
Tổng SL dự kiến
SL đã tạo lô
Number
SL đã phân bổ vào các lô
Ngày bắt đầu
Date
Ngày bắt đầu KH
Ngày kết thúc
Date
Ngày kết thúc KH
Trạng thái
Badge
DRAFT / ACTIVE / COMPLETED / CANCELLED
Thao tác
Actions
Xem / Sửa / Tạo lô từ KH
5.5. SCR-F09-05: Tạo Kế hoạch SX
Tên trường
Field name
Kiểu
Bắt buộc
Validation
Mô tả
Mã kế hoạch
plan_code
Text (auto)
Có
Auto: PLAN-{YYYYMMDD}-
Tên kế hoạch
plan_name
Text (5-200)
Có
VD: "KH SX rau hữu cơ Q1/2026"
Sản phẩm
product_id
Dropdown
Có
Sản phẩm mục tiêu
SL mục tiêu
target_quantity
Decimal
Có
> 0
Tổng SL cần SX
Đơn vị
unit
Dropdown
Có
Ngày bắt đầu
start_date
Date
Có
≥ hiện tại
Ngày kết thúc
end_date
Date
Có
> start_date
Số lô dự kiến
planned_batch_count
Integer
Không
> 0
Số lô dự kiến tạo
Ghi chú
notes
Textarea
Không
6. Danh sách Use Case
ID
Tên Usecase
Mô tả
Màn hình
UC-F09-01
Xem danh sách lô mã
Xem, tìm kiếm, lọc danh sách lô
SCR-F09-01
UC-F09-02
Tạo lô mã thủ công
Tạo lô mã mới nhập tay
SCR-F09-01, SCR-F09-02
UC-F09-03
Tạo lô mã từ kế hoạch SX
Tạo lô từ kế hoạch sản xuất
SCR-F09-04, SCR-F09-02
UC-F09-04
Chỉnh sửa lô mã
Cập nhật thông tin lô
SCR-F09-02
UC-F09-05
Xem chi tiết lô mã
Xem toàn bộ + chuỗi truy xuất
SCR-F09-03
UC-F09-06
Cập nhật sản lượng thực tế
Ghi nhận SL SX thực tế
SCR-F09-02
UC-F09-07
Hủy lô mã
Hủy lô chưa SX
SCR-F09-01
UC-F09-08
Thu hồi lô
Đánh dấu lô cần thu hồi
SCR-F09-03
UC-F09-09
Quản lý kế hoạch SX
Tạo/sửa/xem kế hoạch
SCR-F09-04, SCR-F09-05
UC-F09-10
Xuất Excel danh sách lô
Export ra file
SCR-F09-01
UC-F09-11
Xem dashboard lô mã
Tổng quan lô + tồn kho
SCR-F09-06
7. Mô tả chi tiết Use Case
7.1. UC-F09-01: Xem danh sách lô mã
Bước
Tác nhân
Hành động / Mô tả
Phản hồi / Xử lý hệ thống
Ghi chú
1
User
Truy cập TXNG > Mã hóa & Tem > Quản lý Lô mã
Kiểm tra quyền → hiển thị SCR-F09-01, phân trang 20, sắp xếp theo ngày SX DESC
2
User
Tìm kiếm theo mã lô / tên sản phẩm / mã QR
Full-text search, debounce 300ms
Tối thiểu 2 ký tự
3
User
Lọc theo trạng thái / loại lô / sản phẩm / thời gian
Kết hợp nhiều bộ lọc
4
User
Sắp xếp / chuyển trang
Server-side
7.2. UC-F09-02: Tạo lô mã thủ công
Bước
Tác nhân
Hành động / Mô tả
Phản hồi / Xử lý hệ thống
Ghi chú
1
User
Nhấn "Tạo lô" tại SCR-F09-01
Mở SCR-F09-02 (form trống)
2
User
Chọn loại lô
Render trường bổ sung theo loại
3
User
Chọn sản phẩm, vùng SX, nhập SL kế hoạch
Validate real-time
4
User
Nhập ngày SX, hạn sử dụng, điều kiện bảo quản
Validate: hạn SD > ngày SX
5
User
Nhấn "Lưu"
Hệ thống:
1. Validate toàn bộ (server-side)
2. Auto-generate batch_code: LOT-{TYPE}-{YYYYMMDD}-
3. Tạo bản ghi batch, status = PLANNED
4. Ghi log
5. Thông báo "Tạo lô mã thành công: [mã lô]"
6
Hệ thống
Điều hướng về SCR-F09-01
Lô mới ở đầu danh sách
7.3. UC-F09-03: Tạo lô mã từ kế hoạch SX
Bước
Tác nhân
Hành động / Mô tả
Phản hồi / Xử lý hệ thống
Ghi chú
1
User
Tại SCR-F09-04, chọn kế hoạch SX, nhấn "Tạo lô từ KH"
Mở SCR-F09-02 với thông tin pre-fill từ kế hoạch
product_id, planned_quantity auto-fill
2
User
Điều chỉnh SL nếu cần (≤ SL còn lại của KH)
Validate: Tổng SL các lô ≤ SL mục tiêu KH
3
User
Nhấn "Lưu"
Tạo lô + liên kết với production_plan_id
4
Hệ thống
Cập nhật KH: SL đã phân bổ += SL lô mới
Nếu đã phân bổ hết → KH status = COMPLETED
7.4. UC-F09-06: Cập nhật sản lượng thực tế
Bước
Tác nhân
Hành động / Mô tả
Phản hồi / Xử lý hệ thống
Ghi chú
1
User
Tại SCR-F09-02 (sửa), nhập actual_quantity
Validate: ≥ 0
2
User
Nhấn "Cập nhật"
Hệ thống:
1. Cập nhật actual_quantity
2. Cập nhật stock_quantity (nếu chưa phân phối)
3. Nếu actual_quantity > 0 và status = PLANNED → chuyển IN_PRODUCTION
4. Ghi log diff
7.5. UC-F09-08: Thu hồi lô
Bước
Tác nhân
Hành động / Mô tả
Phản hồi / Xử lý hệ thống
Ghi chú
1
ENTERPRISE_ADMIN
Tại SCR-F09-03, nhấn "Thu hồi lô"
Hiển thị dialog: nhập lý do thu hồi, phạm vi ảnh hưởng
Chỉ ENTERPRISE_ADMIN
2
Admin
Nhập lý do, chọn mức độ nghiêm trọng
3
Admin
Nhấn "Xác nhận thu hồi"
Hệ thống:
1. Chuyển status → RECALLED
2. Gửi cảnh báo cho TẤT CẢ điểm bán đã nhận lô này
3. Gửi notification cho SO_ADMIN
4. Ghi log
5. Đánh dấu tồn kho liên quan = blocked
8. Thiết kế Database Schema
8.1. Chi tiết bảng dữ liệu
8.1.1. Bảng batches (Lô mã)
Cột
Kiểu dữ liệu
Nullable
Default
Mô tả
Constraint
id
UUID
NOT NULL
gen_random_uuid()
Khóa chính
PRIMARY KEY
enterprise_id
UUID
NOT NULL
FK → enterprises.id
FOREIGN KEY
batch_code
VARCHAR(50)
NOT NULL
Mã lô (auto)
UNIQUE
batch_type
VARCHAR(20)
NOT NULL
Loại lô
CHECK IN ('CROP','LIVESTOCK','AQUACULTURE','PROCESSED')
product_id
UUID
NOT NULL
FK → products.id
FOREIGN KEY
production_plan_id
UUID
NULL
FK → production_plans.id
FOREIGN KEY
production_area_id
UUID
NOT NULL
FK → production_areas.id
FOREIGN KEY
planned_quantity
DECIMAL(15,3)
NOT NULL
SL kế hoạch
CHECK > 0
actual_quantity
DECIMAL(15,3)
NULL
0
SL thực tế SX
CHECK >= 0
stock_quantity
DECIMAL(15,3)
NOT NULL
0
SL tồn kho hiện tại
CHECK >= 0
unit
VARCHAR(20)
NOT NULL
Đơn vị
production_start_date
DATE
NOT NULL
Ngày bắt đầu SX
production_end_date
DATE
NULL
Ngày kết thúc SX dự kiến
CHECK >= production_start_date
manufacture_date
DATE
NULL
Ngày SX ghi trên SP
expiry_date
DATE
NULL
Hạn sử dụng
CHECK > manufacture_date
storage_conditions
VARCHAR(300)
NULL
Điều kiện bảo quản
applied_standards
JSONB
NULL
'[]'
Tiêu chuẩn áp dụng
status
VARCHAR(20)
NOT NULL
'PLANNED'
Trạng thái
CHECK IN ('PLANNED','IN_PRODUCTION','PRODUCED','PACKAGED','DISTRIBUTING','DISTRIBUTED','DELIVERED','COMBO_ASSEMBLED','DEPLETED','RECALLED','EXPIRED','DESTROYED','CANCELLED') — v1.2: thêm DESTROYED
recall_reason
TEXT
NULL
Lý do thu hồi
recall_severity
VARCHAR(10)
NULL
Mức độ thu hồi
CHECK IN ('LOW','MEDIUM','HIGH','CRITICAL')
recalled_at
TIMESTAMPTZ
NULL
Thời điểm thu hồi
destroyed_quantity
DECIMAL(15,3)
NOT NULL
0
(v1.2) Tổng SL đã tiêu hủy của lô (cộng dồn qua F39 EXECUTED)
CHECK >= 0
destroyed_at
TIMESTAMPTZ
NULL
(v1.2) Thời điểm batch chuyển status=DESTROYED (BATCH_FULL EXECUTED)
notes
TEXT
NULL
Ghi chú
created_by
UUID
NOT NULL
FK → users.id
FOREIGN KEY
updated_by
UUID
NULL
FK → users.id
FOREIGN KEY
created_at
TIMESTAMPTZ
NOT NULL
NOW()
updated_at
TIMESTAMPTZ
NOT NULL
NOW()
deleted_at
TIMESTAMPTZ
NULL
Soft delete
Indexes:
sql CREATE UNIQUE INDEX idx_batches_code ON batches (batch_code);
CREATE INDEX idx_batches_enterprise ON batches (enterprise_id);
CREATE INDEX idx_batches_product ON batches (product_id);
CREATE INDEX idx_batches_status ON batches ( status );
CREATE INDEX idx_batches_type ON batches (batch_type);
CREATE INDEX idx_batches_expiry ON batches ( expiry_date ) WHERE expiry_date IS NOT NULL ;
CREATE INDEX idx_batches_code_search ON batches USING gin(to_tsvector( 'simple' , batch_code));
8.1.2. Bảng batch_crop_ext (Mở rộng – Trồng trọt)
Cột
Kiểu dữ liệu
Nullable
Default
Mô tả
Constraint
batch_id
UUID
NOT NULL
FK → batches.id
PRIMARY KEY, FOREIGN KEY
crop_variety
VARCHAR(200)
NULL
Giống cây trồng
crop_season
VARCHAR(100)
NULL
Mùa vụ
area_hectares
DECIMAL(10,4)
NULL
Diện tích (ha)
CHECK > 0
8.1.3. Bảng batch_livestock_ext (Mở rộng – Chăn nuôi)
Cột
Kiểu dữ liệu
Nullable
Default
Mô tả
Constraint
batch_id
UUID
NOT NULL
FK → batches.id
PRIMARY KEY, FOREIGN KEY
species
VARCHAR(50)
NOT NULL
Loài
breed
VARCHAR(200)
NULL
Giống
animal_count
INTEGER
NULL
Số đầu con
CHECK > 0
8.1.4. Bảng batch_aquaculture_ext (Mở rộng – Thủy sản)
Cột
Kiểu dữ liệu
Nullable
Default
Mô tả
Constraint
batch_id
UUID
NOT NULL
FK → batches.id
PRIMARY KEY, FOREIGN KEY
aqua_species
VARCHAR(50)
NOT NULL
Loài thủy sản
pond_id
UUID
NULL
FK → ponds.id
FOREIGN KEY
stocking_density
DECIMAL(10,2)
NULL
Mật độ thả (con/m²)
CHECK > 0
8.1.5. Bảng production_plans (Kế hoạch sản xuất)
Cột
Kiểu dữ liệu
Nullable
Default
Mô tả
Constraint
id
UUID
NOT NULL
gen_random_uuid()
Khóa chính
PRIMARY KEY
enterprise_id
UUID
NOT NULL
FK → enterprises.id
FOREIGN KEY
plan_code
VARCHAR(30)
NOT NULL
Mã KH (auto)
UNIQUE
plan_name
VARCHAR(200)
NOT NULL
Tên kế hoạch
product_id
UUID
NOT NULL
FK → products.id
FOREIGN KEY
target_quantity
DECIMAL(15,3)
NOT NULL
SL mục tiêu
CHECK > 0
allocated_quantity
DECIMAL(15,3)
NOT NULL
0
SL đã phân bổ vào lô
CHECK >= 0
unit
VARCHAR(20)
NOT NULL
Đơn vị
start_date
DATE
NOT NULL
Ngày bắt đầu
end_date
DATE
NOT NULL
Ngày kết thúc
CHECK > start_date
planned_batch_count
INTEGER
NULL
Số lô dự kiến
CHECK > 0
status
VARCHAR(20)
NOT NULL
'DRAFT'
Trạng thái
CHECK IN ('DRAFT','ACTIVE','COMPLETED','CANCELLED')
notes
TEXT
NULL
created_by
UUID
NOT NULL
FK → users.id
FOREIGN KEY
created_at
TIMESTAMPTZ
NOT NULL
NOW()
updated_at
TIMESTAMPTZ
NOT NULL
NOW()
8.1.6. Bảng batch_history (Lịch sử thay đổi)
Cột
Kiểu dữ liệu
Nullable
Default
Mô tả
Constraint
id
UUID
NOT NULL
gen_random_uuid()
Khóa chính
PRIMARY KEY
batch_id
UUID
NOT NULL
FK → batches.id
FOREIGN KEY
action
VARCHAR(20)
NOT NULL
Hành động
CHECK IN ('CREATE','UPDATE','STATUS_CHANGE','RECALL','CANCEL')
changed_by
UUID
NOT NULL
FK → users.id
FOREIGN KEY
changed_at
TIMESTAMPTZ
NOT NULL
NOW()
changes_json
JSONB
NULL
Chi tiết thay đổi
ip_address
INET
NULL
8.2. Migration SQL
sql -- Migration: 001_create_batches_tables.sql
CREATE TABLE production_plans (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
enterprise_id UUID NOT NULL REFERENCES enterprises(id),
plan_code VARCHAR ( 30 ) NOT NULL UNIQUE ,
plan_name VARCHAR ( 200 ) NOT NULL ,
product_id UUID NOT NULL REFERENCES products(id),
target_quantity DECIMAL ( 15 , 3 ) NOT NULL CHECK (target_quantity > 0 ),
allocated_quantity DECIMAL ( 15 , 3 ) NOT NULL DEFAULT 0 CHECK (allocated_quantity >= 0 ),
unit VARCHAR ( 20 ) NOT NULL ,
start_date DATE NOT NULL ,
end_date DATE NOT NULL ,
planned_batch_count INTEGER CHECK (planned_batch_count IS NULL OR planned_batch_count > 0 ),
status VARCHAR ( 20 ) NOT NULL DEFAULT 'DRAFT' CHECK ( status IN ( 'DRAFT' , 'ACTIVE' , 'COMPLETED' , 'CANCELLED' )),
notes TEXT ,
created_by UUID NOT NULL REFERENCES users(id),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW (),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW (),
CONSTRAINT chk_plan_dates CHECK (end_date > start_date )
);
CREATE TABLE batches (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
enterprise_id UUID NOT NULL REFERENCES enterprises(id),
batch_code VARCHAR ( 50 ) NOT NULL UNIQUE ,
batch_type VARCHAR ( 20 ) NOT NULL CHECK (batch_type IN ( 'CROP' , 'LIVESTOCK' , 'AQUACULTURE' , 'PROCESSED' )),
product_id UUID NOT NULL REFERENCES products(id),
production_plan_id UUID REFERENCES production_plans(id),
production_area_id UUID NOT NULL REFERENCES production_areas(id),
planned_quantity DECIMAL ( 15 , 3 ) NOT NULL CHECK (planned_quantity > 0 ),
actual_quantity DECIMAL ( 15 , 3 ) DEFAULT 0 CHECK (actual_quantity >= 0 ),
stock_quantity DECIMAL ( 15 , 3 ) NOT NULL DEFAULT 0 CHECK (stock_quantity >= 0 ),
unit VARCHAR ( 20 ) NOT NULL ,
production_start_date DATE NOT NULL ,
production_end_date DATE ,
manufacture_date DATE ,
expiry_date DATE ,
storage_conditions VARCHAR ( 300 ),
applied_standards JSONB DEFAULT '[]' ,
status VARCHAR ( 20 ) NOT NULL DEFAULT 'PLANNED' CHECK ( status IN ( 'PLANNED' , 'IN_PRODUCTION' , 'PRODUCED' , 'PACKAGED' , 'DISTRIBUTING' , 'DISTRIBUTED' , 'DELIVERED' , 'COMBO_ASSEMBLED' , 'DEPLETED' , 'RECALLED' , 'EXPIRED' , 'DESTROYED' , 'CANCELLED' )), -- v1.2: thêm DESTROYED
recall_reason TEXT ,
recall_severity VARCHAR ( 10 ) CHECK (recall_severity IS NULL OR recall_severity IN ( 'LOW' , 'MEDIUM' , 'HIGH' , 'CRITICAL' )),
recalled_at TIMESTAMPTZ ,
destroyed_quantity DECIMAL ( 15 , 3 ) NOT NULL DEFAULT 0 CHECK (destroyed_quantity >= 0 ), -- v1.2
destroyed_at TIMESTAMPTZ , -- v1.2
notes TEXT ,
created_by UUID NOT NULL REFERENCES users(id),
updated_by UUID REFERENCES users(id),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW (),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW (),
deleted_at TIMESTAMPTZ ,
CONSTRAINT chk_batch_dates CHECK (production_end_date IS NULL OR production_end_date >= production_start_date),
CONSTRAINT chk_expiry CHECK ( expiry_date IS NULL OR manufacture_date IS NULL OR expiry_date > manufacture_date)
);
CREATE INDEX idx_batches_enterprise ON batches (enterprise_id);
CREATE INDEX idx_batches_status ON batches ( status );
CREATE INDEX idx_batches_product ON batches (product_id);
CREATE INDEX idx_batches_expiry ON batches ( expiry_date ) WHERE expiry_date IS NOT NULL ;
CREATE TABLE batch_crop_ext (
batch_id UUID PRIMARY KEY REFERENCES batches (id) ON DELETE CASCADE ,
crop_variety VARCHAR ( 200 ),
crop_season VARCHAR ( 100 ),
area_hectares DECIMAL ( 10 , 4 ) CHECK (area_hectares IS NULL OR area_hectares > 0 )
);
CREATE TABLE batch_livestock_ext (
batch_id UUID PRIMARY KEY REFERENCES batches (id) ON DELETE CASCADE ,
species VARCHAR ( 50 ) NOT NULL ,
breed VARCHAR ( 200 ),
animal_count INTEGER CHECK (animal_count IS NULL OR animal_count > 0 )
);
CREATE TABLE batch_aquaculture_ext (
batch_id UUID PRIMARY KEY REFERENCES batches (id) ON DELETE CASCADE ,
aqua_species VARCHAR ( 50 ) NOT NULL ,
pond_id UUID,
stocking_density DECIMAL ( 10 , 2 ) CHECK (stocking_density IS NULL OR stocking_density > 0 )
);
CREATE TABLE batch_history (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
batch_id UUID NOT NULL REFERENCES batches (id),
action VARCHAR ( 20 ) NOT NULL CHECK ( action IN ( 'CREATE' , 'UPDATE' , 'STATUS_CHANGE' , 'RECALL' , 'CANCEL' )),
changed_by UUID NOT NULL REFERENCES users(id),
changed_at TIMESTAMPTZ NOT NULL DEFAULT NOW (),
changes_json JSONB,
ip_address INET
);
CREATE INDEX idx_batch_history_batch ON batch_history(batch_id);
CREATE TRIGGER trg_batches_updated_at
BEFORE UPDATE ON batches
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
CREATE TRIGGER trg_plans_updated_at
BEFORE UPDATE ON production_plans
FOR EACH ROW EXECUTE FUNCTION update_updated_at();
9. Thiết kế API
9.1. Tổng quan API Endpoints
Method
Endpoint
Mô tả
Auth
Roles
GET
/api/v1/batches
Danh sách lô mã
Bearer Token
ENTERPRISE_ADMIN, ENTERPRISE_USER, SO_ADMIN
GET
/api/v1/batches/:id
Chi tiết lô mã
Bearer Token
Tất cả
POST
/api/v1/batches
Tạo lô mã
Bearer Token
ENTERPRISE_ADMIN, ENTERPRISE_USER
PUT
/api/v1/batches/:id
Cập nhật lô mã
Bearer Token
ENTERPRISE_ADMIN, ENTERPRISE_USER (owner)
POST
/api/v1/batches/:id/recall
Thu hồi lô
Bearer Token
ENTERPRISE_ADMIN
POST
/api/v1/batches/:id/cancel
Hủy lô
Bearer Token
ENTERPRISE_ADMIN
GET
/api/v1/batches/:id/trace
Chuỗi truy xuất của lô
Bearer Token
Tất cả
GET
/api/v1/batches/:id/history
Lịch sử thay đổi
Bearer Token
ENTERPRISE_ADMIN
GET
/api/v1/batches/export
Xuất Excel
Bearer Token
ENTERPRISE_ADMIN, ENTERPRISE_USER
GET
/api/v1/batches/dashboard
Dashboard dữ liệu
Bearer Token
ENTERPRISE_ADMIN, SO_ADMIN
GET
/api/v1/production-plans
Danh sách kế hoạch SX
Bearer Token
ENTERPRISE_ADMIN, ENTERPRISE_USER
POST
/api/v1/production-plans
Tạo kế hoạch SX
Bearer Token
ENTERPRISE_ADMIN
PUT
/api/v1/production-plans/:id
Cập nhật kế hoạch
Bearer Token
ENTERPRISE_ADMIN
9.2. Chi tiết API
9.2.1. POST /api/v1/batches - Tạo lô mã
Request Body:
json {
"batch_type" : "CROP" ,
"product_id" : "uuid" ,
"production_plan_id" : "uuid" ,
"production_area_id" : "uuid" ,
"planned_quantity" : 5000 ,
"unit" : "kg" ,
"production_start_date" : "2026-03-15" ,
"production_end_date" : "2026-06-15" ,
"manufacture_date" : "2026-06-15" ,
"expiry_date" : "2026-12-15" ,
"storage_conditions" : "Bảo quản nơi khô ráo, thoáng mát" ,
"applied_standards" : [ "VietGAP" ],
"type_specific" : {
"crop_variety" : "Xà lách Mỹ" ,
"crop_season" : "Vụ Xuân 2026" ,
"area_hectares" : 2.5
},
"notes" : ""
}
Response 201:
json {
"success" : true ,
"data" : {
"id" : "uuid" ,
"batch_code" : "LOT-CROP-20260315-001" ,
"status" : "PLANNED" ,
"message" : "Tạo lô mã thành công."
}
}
9.2.2. GET /api/v1/batches/:id/trace - Chuỗi truy xuất
Response 200:
json {
"success" : true ,
"data" : {
"batch" : {
"batch_code" : "LOT-CROP-20260315-001" ,
"product_name" : "Xà lách Mỹ hữu cơ" ,
"status" : "DISTRIBUTED"
},
"trace_events" : [
{
"event_type" : "PRODUCTION_START" ,
"timestamp" : "2026-03-15T08:00:00Z" ,
"description" : "Bắt đầu sản xuất" ,
"source" : "F05 - Nhật ký Trồng trọt" ,
"ref_id" : "uuid"
},
{
"event_type" : "CTE-CROP-04" ,
"timestamp" : "2026-04-01T09:00:00Z" ,
"description" : "Phun thuốc BVTV: Abamectin 1.8EC" ,
"source" : "F05" ,
"ref_id" : "uuid"
},
{
"event_type" : "HARVEST" ,
"timestamp" : "2026-06-10T06:00:00Z" ,
"description" : "Thu hoạch: 4800kg" ,
"source" : "F05" ,
"ref_id" : "uuid"
},
{
"event_type" : "PACKAGING" ,
"timestamp" : "2026-06-12T10:00:00Z" ,
"description" : "Đóng gói: 4750kg" ,
"source" : "F07" ,
"ref_id" : "uuid"
},
{
"event_type" : "CTE-DIST-01" ,
"timestamp" : "2026-06-13T08:00:00Z" ,
"description" : "Xuất kho: Kho Đà Lạt → Siêu thị ABC" ,
"source" : "F08" ,
"ref_id" : "uuid"
},
{
"event_type" : "CTE-DIST-04" ,
"timestamp" : "2026-06-13T16:00:00Z" ,
"description" : "Giao hàng: Siêu thị ABC - 4750kg" ,
"source" : "F08" ,
"ref_id" : "uuid"
}
]
}
}
10. Test Cases cho QA
10.1. TC-F09-01: Xem danh sách lô mã
TC ID
Tên test case
Precondition
Bước thực hiện
Expected Result
Priority
TC-01-01
Xem danh sách có dữ liệu
DN có ≥1 lô
1. Vào Quản lý Lô mã
Hiển thị danh sách, phân trang 20
High
TC-01-02
Tìm kiếm theo mã lô
Có lô LOT-CROP-20260315-001
1. Nhập "LOT-CROP"
Hiển thị các lô match
High
TC-01-03
Lọc theo trạng thái
Có nhiều trạng thái
1. Chọn IN_PRODUCTION
Chỉ hiển thị lô đang SX
High
TC-01-04
Lọc theo loại lô
1. Chọn CROP
Chỉ hiển thị lô trồng trọt
Medium
TC-01-05
SO_ADMIN xem toàn tỉnh
SO_ADMIN đăng nhập
1. Vào danh sách
Thấy lô tất cả DN, không có nút tạo/sửa
High
10.2. TC-F09-02: Tạo lô mã
TC ID
Tên test case
Precondition
Bước thực hiện
Expected Result
Priority
TC-02-01
Tạo lô CROP thành công
1. Chọn loại CROP 2. Chọn SP, vùng SX 3. Nhập SL, ngày 4. Nhấn "Lưu"
Lô tạo thành công, mã auto: LOT-CROP-YYYYMMDD-SEQ, status=PLANNED
Critical
TC-02-02
Tạo lô LIVESTOCK thành công
1. Chọn LIVESTOCK 2. Nhập thông tin + loài, giống, số đầu con
Lô tạo với thông tin chăn nuôi đầy đủ
High
TC-02-03
Tạo từ kế hoạch SX
KH SX đang ACTIVE
1. Chọn KH 2. Nhấn "Tạo lô từ KH"
Form pre-fill, SL ≤ SL còn lại KH
High
TC-02-04
SL vượt KH
KH còn 1000, tổng lô đã 4000/5000
1. Nhập SL = 1500
Lỗi: "Vượt SL còn lại của kế hoạch (1000)"
High
TC-02-05
Thiếu trường bắt buộc
1. Bỏ trống sản phẩm
Lỗi validate
Critical
TC-02-06
Hạn SD < Ngày SX
1. Ngày SX = 2026-06-01, HSD = 2026-05-01
Lỗi: "Hạn sử dụng phải sau ngày sản xuất"
Medium
TC-02-07
Mã lô auto-generate unique
Tạo 3 lô cùng ngày
1. Tạo lô 1, 2, 3
Mã: LOT-CROP-20260313-001, -002, -003
High
10.3. TC-F09-03: Thu hồi lô
TC ID
Tên test case
Precondition
Bước thực hiện
Expected Result
Priority
TC-03-01
Thu hồi lô đang phân phối
Lô DISTRIBUTING
1. Nhấn "Thu hồi" 2. Nhập lý do + mức độ 3. Xác nhận
Status → RECALLED, notification gửi cho điểm bán
Critical
TC-03-02
Thu hồi lô PLANNED
Lô chưa SX
1. Nhấn "Thu hồi"
Không cho phép: sử dụng "Hủy" thay vì "Thu hồi"
Medium
TC-03-03
ENTERPRISE_USER thu hồi
1. Nhấn "Thu hồi"
Không hiển thị nút (chỉ ADMIN)
High
10.4. TC-F09-04: Chuỗi truy xuất
TC ID
Tên test case
Precondition
Bước thực hiện
Expected Result
Priority
TC-04-01
Xem chuỗi truy xuất đầy đủ
Lô đã SX + đóng gói + phân phối
1. Mở chi tiết lô 2. Xem timeline
Timeline hiển thị đủ CTE events: SX → Đóng gói → Phân phối
Critical
TC-04-02
Xem vật tư sử dụng
Lô có liên kết vật tư từ F04
1. Tab "Vật tư sử dụng"
Hiển thị đúng danh sách vật tư + liều lượng
High
TC-04-03
Xem tồn kho theo kho
Lô đã phân bổ nhiều kho
1. Tab "Tồn kho"
Hiển thị SL tồn tại mỗi kho
Medium
10.5. TC-F09-05: Test tích hợp
TC ID
Tên test case
Precondition
Bước thực hiện
Expected Result
Priority
TC-05-01
Lô hiển thị trong F08 khi tạo phiếu phân phối
Lô PACKAGED, có tồn kho
1. Tạo phiếu phân phối (F08) 2. Chọn lô hàng
Lô xuất hiện trong dropdown, thông tin auto-fill
Critical
TC-05-02
Tồn kho giảm khi xuất qua F08
Lô tồn = 1000
1. Xuất 500 qua F08
stock_quantity = 500
Critical
TC-05-03
QR code liên kết đúng lô
Lô đã cấp QR (F16)
1. Scan QR
Hiển thị chuỗi truy xuất đúng lô
Critical
TC-05-04
Hệ thống cảnh báo lô sắp hết hạn
Lô expiry_date trong 30 ngày
1. Kiểm tra dashboard
Hiển thị cảnh báo + notification
High
TC-05-05
Tự động EXPIRED khi quá hạn
Lô expiry_date < hôm nay
1. Chạy job hàng ngày
Status → EXPIRED, notification gửi
High
10.6. TC-F09-06: Test bảo mật
TC ID
Tên test case
Bước thực hiện
Expected Result
Priority
TC-06-01
API không token
GET /api/v1/batches
401
Critical
TC-06-02
Truy cập lô DN khác
GET /api/v1/batches/
403
Critical
TC-06-03
SQL Injection
Tìm kiếm '; DROP TABLE batches; --
Không lỗi
Critical
TC-06-04
XSS
Nhập <script> vào ghi chú
Text escaped
Critical
11. Acceptance Criteria
ID
Tiêu chí chấp nhận
Mô tả kiểm thử
AC-F09-01
Mã lô tự động sinh theo format LOT-{TYPE}-{YYYYMMDD}-
Tạo nhiều lô cùng ngày → SEQ tăng dần, không trùng
AC-F09-02
Lô mã liên kết chính xác với nhật ký SX (F05/F06/F07)
Tạo lô → gán vào nhật ký → chuỗi truy xuất hiển thị đúng
AC-F09-03
Tồn kho cập nhật real-time khi SX/phân phối
SX +SL, xuất kho -SL, nhận hàng trả +SL
AC-F09-04
Chuỗi truy xuất hiển thị đầy đủ từ SX → Phân phối
Timeline gồm tất cả CTE events liên quan
AC-F09-05
Thu hồi lô gửi cảnh báo đến TẤT CẢ điểm bán liên quan
Recall → notification + email cho tất cả POS đã nhận lô
AC-F09-06
Hệ thống tự động cảnh báo lô sắp hết hạn (30 ngày)
Job scheduler kiểm tra daily
AC-F09-07
Kế hoạch SX tự động COMPLETED khi phân bổ hết SL
allocated_quantity >= target_quantity → status COMPLETED
AC-F09-08
Phân quyền đúng: SO_ADMIN chỉ xem
Không có nút tạo/sửa/xóa
AC-F09-09
Lô CANCELLED/EXPIRED không hiển thị trong dropdown F08
Chỉ lô PACKAGED + có tồn kho mới xuất hiện
AC-F09-10
Ghi log mỗi thay đổi trạng thái lô
batch_history ghi đúng action, user, timestamp
12. Chuyển đổi trạng thái Lô mã
Từ trạng thái
Hành động
Chuyển sang
Mô tả
(mới)
Tạo lô
PLANNED
Lô mới từ KH hoặc thủ công
PLANNED
Bắt đầu SX (ghi nhận actual_qty > 0)
IN_PRODUCTION
Đang sản xuất
PLANNED
Hủy
CANCELLED
Hủy trước khi SX
IN_PRODUCTION
Hoàn thành SX
PRODUCED
SX xong
PRODUCED
Đóng gói (F07)
PACKAGED
Đã đóng gói
PACKAGED
Xuất kho (F08)
DISTRIBUTING
Đang phân phối
DISTRIBUTING
Giao hết
DISTRIBUTED
Phân phối xong
DISTRIBUTED
Tồn kho = 0
DEPLETED
Đã hết hàng
Bất kỳ (trừ CANCELLED)
Thu hồi
RECALLED
Thu hồi lô
Bất kỳ (trừ CANCELLED, RECALLED)
Quá hạn sử dụng
EXPIRED
Job tự động
Bất kỳ (trừ CANCELLED)
(v1.2) F39 BATCH_FULL EXECUTED + remaining_qty=0
DESTROYED
Cascade từ F39 destruction; terminal
13. Notification List
ID
Sự kiện
Người nhận
Kênh
Nội dung
N-F09-01
Lô mã được tạo thành công
ENTERPRISE_ADMIN
In-app
"Lô mã [mã lô] đã được tạo. SP: [tên SP], SL: [X] [đơn vị]."
N-F09-02
Lô sắp hết hạn (30 ngày)
ENTERPRISE_ADMIN
In-app, Email
"Lô [mã lô] sẽ hết hạn vào [ngày]. SL tồn: [X]. Vui lòng xử lý."
N-F09-03
Lô đã hết hạn
ENTERPRISE_ADMIN
In-app, Email, Push
"Lô [mã lô] ĐÃ HẾT HẠN từ [ngày]. SL tồn: [X]. Ngừng phân phối ngay."
N-F09-04
Thu hồi lô
ENTERPRISE_ADMIN, Điểm bán, SO_ADMIN
In-app, Email, SMS
"KHẨN CẤP: Lô [mã lô] bị THU HỒI. Lý do: [lý do]. Vui lòng ngừng bán + thu hồi SP."
N-F09-05
KH SX hoàn thành phân bổ
ENTERPRISE_ADMIN
In-app
"Kế hoạch [mã KH] đã phân bổ đủ SL mục tiêu."
N-F09-06
Tồn kho lô xuống thấp (< 10%)
ENTERPRISE_ADMIN
In-app
"Lô [mã lô] tồn kho còn [X] [đơn vị] (<10%). Cân nhắc bổ sung."
14. Error / Warning Message Handling
ID
Mã lỗi
Mô tả
Hành động
ERR01
E-F09-001
Không có quyền truy cập
Ẩn nút hoặc redirect
ERR02
E-F09-002
SL phân bổ vượt SL kế hoạch
Thông báo SL còn lại
ERR03
E-F09-003
Không thể thay đổi ở trạng thái hiện tại
Thông báo trạng thái + hành động được phép
ERR04
E-F09-004
Lô không tồn tại hoặc đã xóa
Redirect về danh sách
ERR05
E-F09-005
Dữ liệu không hợp lệ
Highlight trường lỗi
WARN01
W-F09-001
Lô sắp hết hạn (30 ngày)
Badge vàng + notification
WARN02
W-F09-002
Tồn kho thấp (< 10%)
Badge cam
WARN03
W-F09-003
SL thực tế khác SL kế hoạch > 20%
Cảnh báo chênh lệch
15. Quy tắc nghiệp vụ
Mã
Quy tắc
Giải thích
BR-F09-01
Mã lô unique, auto-generate theo format LOT-{TYPE}-{YYYYMMDD}-
Đảm bảo truy xuất rõ ràng
BR-F09-02
Mỗi lô phải liên kết với ít nhất 1 sản phẩm và 1 vùng SX
Đảm bảo truy xuất nguồn gốc
BR-F09-03
Tồn kho không được âm
stock_quantity >= 0, kiểm tra trước khi xuất
BR-F09-04
Lô RECALLED không thể phân phối thêm
Bảo vệ người tiêu dùng
BR-F09-05
Lô EXPIRED tự động phát hiện bởi job hàng ngày
Chạy 00:00 mỗi ngày
BR-F09-06
SL phân bổ từ KH không được vượt target_quantity
Kiểm tra khi tạo lô từ KH
BR-F09-07
Phân quyền dữ liệu theo enterprise_id
DN chỉ thấy lô của mình
BR-F09-08
Loại lô không thể thay đổi sau khi tạo
Tránh ảnh hưởng dữ liệu liên kết
BR-F09-09
Chuỗi truy xuất phải liên kết được từ lô → SX → vật tư → phân phối
End-to-end traceability
BR-F09-10
Thu hồi lô phải thông báo TẤT CẢ điểm đã nhận lô
Yêu cầu pháp lý về thu hồi sản phẩm
BR-F09-11
(v1.2) Lô DESTROYED không thể phân phối, vận chuyển (F22), đưa vào combo (F32), thu hồi thêm (F13), hoặc đề xuất tiêu hủy mới (F39). Terminal state, immutable.
Tránh sai lệch dữ liệu sau tiêu hủy; toàn vẹn chuỗi truy xuất
BR-F09-12
(v1.2) destroyed_quantity của lô là cộng dồn qua các lần F39 EXECUTED (BATCH_PARTIAL hoặc SGTIN_LEVEL). Khi destroyed_quantity = actual_quantity (toàn bộ đã hủy): tự động set status = DESTROYED, destroyed_at = NOW().
Tính toán chính xác lifecycle batch
16. Constraints / Assumptions
16.1. Ràng buộc
PostgreSQL ≥ 14, File storage MinIO/S3.
API RESTful, JSON response, JWT Bearer Token.
Timestamp TIMESTAMPTZ (UTC), hiển thị Asia/Ho_Chi_Minh.
Job scheduler (cron) cho kiểm tra hết hạn: chạy 00:00 hàng ngày.
Mã lô sequence quản lý bằng PostgreSQL SEQUENCE per enterprise per day.
16.2. Giả định
Bảng enterprises, users, products, production_areas đã tồn tại.
Sản phẩm (products) được quản lý bởi module riêng hoặc master data.
QR code được cấp bởi module TXNG-F16 sau khi lô đã được tạo.
Hệ thống có background job runner (Bull, Agenda, hoặc pg_cron) cho scheduled tasks.
17. Phụ lục
LOT-{TYPE}-{YYYYMMDD}-{SEQ}
Ví dụ:
- LOT-CROP-20260315-001 (Lô trồng trọt, ngày 15/03/2026, số thứ tự 001)
- LOT-LIVE-20260315-001 (Lô chăn nuôi)
- LOT-AQUA-20260315-001 (Lô thủy sản)
- LOT-PROC-20260315-001 (Lô chế biến)
TYPE mapping:
- CROP → CROP
- LIVESTOCK → LIVE
- AQUACULTURE → AQUA
- PROCESSED → PROC
17.2. Danh mục tiêu chuẩn (applied_standards)
Mã
Tên
VIETGAP
VietGAP
GLOBALGAP
GlobalGAP
ORGANIC
Hữu cơ (Organic)
HACCP
HACCP
ISO22000
ISO 22000
GMP
GMP
17.3. Glossary
Thuật ngữ
Giải thích
Batch/Lot
Lô sản xuất – nhóm sản phẩm cùng quy trình SX, cùng thời điểm
GTIN
Global Trade Item Number – Mã sản phẩm toàn cầu (GS1)
SSCC
Serial Shipping Container Code – Mã container vận chuyển (GS1)
Production Plan
Kế hoạch sản xuất – định hướng SL, thời gian SX
Stock Quantity
Số lượng tồn kho hiện tại của lô
Recall
Thu hồi sản phẩm do vấn đề chất lượng/an toàn
Traceability
Khả năng truy xuất lịch sử sản phẩm trong chuỗi cung ứng