PRD: Sổ biến động
| Module | Kho | PRD ID | PRD-LDG-001 |
| Trạng thái | Chưa tạo item | FEAT | LDG |
| Epic | — | Plane | — |
| Ngày | 2026-07-13 | Phiên bản | v1.0 |
| Gói | @nx/inventory | URD | LDG |
| Surface | BackendClient · Chủ/QL | ||
| Phụ trách | Phát Nguyễn | ||
Sổ biến động là gì
Một chi nhánh (Merchant) có thể có nhiều kho (InventoryLocation), và mỗi mặt hàng tại mỗi kho mang một con số tồn. Bảng tồn chỉ cho biết hôm nay còn bao nhiêu.
Sổ biến động (Inventory Ledger) là cuốn sổ ghi vì sao ra con số đó. Mỗi lần tồn tăng hay giảm, hệ thống ghi thêm một dòng: tồn trước bao nhiêu, đổi bao nhiêu, còn lại bao nhiêu, vì lý do gì, do chứng từ nào. Sổ chỉ được thêm dòng, không bao giờ bị xóa hay ghi đè.
Bốn chỉ số trong tồn kho
Trích từ Kho & mức tồn để khỏi phải mở PRD khác. Mỗi mặt hàng ở mỗi kho mang bốn con số:
| Con số | Hệ thống gọi | Nghĩa |
|---|---|---|
| Thực có | on-hand | Hàng đang nằm trong kho |
| Đang giữ | reserved | Đã hứa cho một chứng từ khác, không bán cho ai được nữa |
| Khả dụng | available | Phần còn bán được |
| Đang về | incoming | Đã rời kho gửi, chưa tới kho nhận |
Bất biến, đúng ở mọi thời điểm:
Khả dụng = Thực có - Đang giữSổ biến động ghi lại từng lần các con số đó đổi.
Vì sao một bảng tồn là không đủ
Bảng tồn không trả lời được câu hỏi hay gặp nhất khi số liệu lệch: hôm qua còn 20, sao nay còn 12, ai lấy đi 8. Không có chỗ trả lời câu đó thì mỗi lần lệch số là một lần cãi nhau giữa thu ngân, nhân viên kho và chủ quán, và cách duy nhất để hòa là đếm lại từ đầu.
Sổ cũng là nơi neo lại bối cảnh của một lần biến động. Merchant nhập hàng theo thùng nhưng tồn lưu theo lon; giá vốn tháng này khác tháng sau. Dòng sổ chỉ ghi số lượng trần thì một năm sau không ai còn biết "5" là 5 thùng hay 5 lon, và lô hàng đó đáng bao nhiêu tiền.
Một lon nước, từ giỏ hàng tới sổ
Coca tại Quầy bar, thực có 20. Khách mua 2 lon.
| Việc xảy ra | Dòng sổ ghi ra | Trước | Đổi | Sau |
|---|---|---|---|---|
| Thu ngân bấm 2 lon vào đơn | Giữ tồn giỏ hàng | 20 | 0 | 20 |
| Khách thanh toán, đơn hoàn tất | Bán hàng trừ kho | 20 | -2 | 18 |
| Hệ thống gửi lại thông báo thanh toán | không dòng nào | 18 | 0 | 18 |
| Nhập thêm 1 thùng (1 thùng = 24 lon) | Nhập mua hàng | 18 | +24 | 42 |
| Merchant đổi hệ số thùng từ 24 sang 20 | không dòng nào | - | - | 42 |
- Bấm món vào giỏ không làm thực có đổi. Cái đổi là đang giữ và khả dụng.
- Thông báo thanh toán gửi lại lần hai không trừ kho lần hai. Cùng một chứng từ và cùng một mục kho chỉ ghi được đúng một dòng sổ.
- Dòng nhập hàng chụp lại đơn vị thùng và hệ số 24 ngay lúc phát sinh. Đổi hệ số về sau không viết lại dòng cũ: mở ra vẫn đọc đúng 1 thùng = 24 lon.
Chỗ dễ sai nhất
Chống trùng không được dựa vào việc đếm dòng sổ hiện có
Đọc xem "đã có dòng sổ nào cho chứng từ này chưa" rồi mới ghi là một cách chống trùng rất mong manh: xóa một dòng sổ là mở đường cho lần trừ kho thứ hai.
Khóa chống trùng là bộ ba chứng từ nguồn + lý do + mục kho, ép ở tầng cơ sở dữ liệu. Xóa hay sửa một dòng sổ cũng không mở lại đường cho lần trừ kho thứ hai.
Hệ quả: ghi sai thì ghi thêm một dòng điều chỉnh, không sửa dòng cũ. Người đọc sổ thấy cả cái sai lẫn cái sửa, nên luôn giải thích được vì sao tồn ra con số hôm nay.
1. Mục tiêu & Loại trừ
Mục tiêu
- Ghi một dòng sổ cho mọi thay đổi tồn kho do nghiệp vụ gây ra: nhập mua hàng, bán hàng, giữ tồn, nhả tồn, tiêu hao nguyên liệu, chuyển kho, kiểm kê, hủy hàng, khởi tạo tồn.
- Mỗi dòng mang đủ bộ ba con số trước/đổi/sau, một lý do lấy từ danh mục cố định, và một chứng từ nguồn truy ngược được.
- Chụp lại đơn vị tính, hệ số quy đổi và giá vốn tại thời điểm phát sinh trên chính dòng sổ.
- Chống ghi trùng: cùng một chứng từ và cùng một dòng tồn chỉ để lại đúng một dòng sổ, dù chứng từ bị xử lý lại bao nhiêu lần.
- Sửa sai bằng dòng điều chỉnh mới, giữ nguyên dòng cũ trong lịch sử.
- Cho merchant xem lại toàn bộ lịch sử biến động của một mặt hàng tại một kho, có lọc.
- Cho đội vận hành một đường sửa/xóa trực tiếp dòng sổ khi phải cứu dữ liệu, tách bạch khỏi giao diện merchant.
Loại trừ
- Việc thực thi biến động tồn: ghi tồn khi phiếu kho hoàn tất thuộc
TKT, giữ và nhả tồn thuộcRSV, cân bằng kho thuộcCNT. Sổ biến động chỉ nhận và lưu lại kết quả của các nghiệp vụ đó. - Cách tính giá vốn bình quân gia quyền và giá định mức - thuộc
VAL. Sổ chỉ chụp lại con số giá tại thời điểm biến động. - Sổ kế toán thuế của hộ kinh doanh. Đó là một cuốn sổ khác, ở module khác.
- Báo cáo tổng hợp hao hụt, báo cáo lãi lỗ theo mặt hàng - các báo cáo đó đọc từ sổ, nhưng bản thân chúng nằm ngoài phạm vi này.
2. Thước đo thành công
| Thước đo | Mục tiêu / tín hiệu |
|---|---|
| Độ phủ ghi sổ | Mọi thay đổi tồn kho đều có một dòng sổ tương ứng; không lần đổi tồn nào không giải thích được |
| Dựng lại được tồn | Cộng dồn toàn bộ dòng sổ của một mục kho ra đúng con số thực có đang hiển thị trên bảng tồn |
| Chống trừ kho hai lần | Không còn ca trừ kho lặp khi chứng từ bị xử lý lại; số lần lệch tồn do ghi trùng giảm về 0 |
| Tự tra được lịch sử | Merchant tự mở màn Lịch sử biến động để giải thích một lần lệch số, thay vì hỏi đội hỗ trợ |
| Can thiệp thủ công | Số lần đội vận hành phải dùng cửa thoát để sửa/xóa dòng sổ giảm dần theo thời gian |
3. Persona & Tình huống
| Persona | Mục tiêu trong tính năng này |
|---|---|
| Chủ merchant | Tra ngược một lần lệch tồn: hôm nay còn 12 thay vì 20, xem sổ để biết 8 đơn vị đi đâu |
| Nhân viên kho | Kiểm tra một phiếu nhập đã thật sự cộng vào tồn chưa, cộng đúng bao nhiêu, theo đơn vị nào |
| Kế toán quán | Đọc lại giá vốn của một lần xuất hàng đã qua, đúng như lúc nó xảy ra |
| Đội vận hành | Sửa hoặc xóa một dòng sổ hỏng sau sự cố dữ liệu, khi dòng điều chỉnh thông thường không cứu được |
Kịch bản cốt lõi: một nghiệp vụ bất kỳ làm tồn thay đổi (bán một lon, nhận một phiếu nhập, cân bằng một phiếu kiểm kê) → hệ thống ghi ngay một dòng sổ kèm trước/đổi/sau, lý do, chứng từ, đơn vị, hệ số, giá vốn → hôm sau chủ quán thấy tồn lệch, mở màn Lịch sử biến động của mặt hàng đó tại kho đó, lọc theo khoảng thời gian → thấy đủ từng dòng, bấm vào chứng từ để nhảy thẳng sang đơn hàng hoặc phiếu kho đứng sau.
4. User Stories
| # | Là một | Tôi muốn | Để |
|---|---|---|---|
| 01 | chủ merchant | xem lại từng lần tồn của một mặt hàng thay đổi | biết chính xác hàng đi đâu mà không phải đếm lại kho |
| 02 | chủ merchant | mỗi dòng biến động chỉ thẳng về chứng từ đứng sau nó | bấm một cái là ra đơn hàng hoặc phiếu kho gây ra biến động đó |
| 03 | nhân viên kho | thấy tồn trước và tồn sau của mỗi lần đổi | đối chiếu với sổ tay của mình mà không phải tự cộng trừ |
| 04 | kế toán quán | dòng sổ giữ lại đơn vị, hệ số quy đổi và giá vốn của đúng lúc đó | đọc lại số cũ không bị lệch vì cấu hình đã đổi về sau |
| 05 | chủ merchant | một chứng từ dù bị xử lý lại nhiều lần cũng chỉ trừ kho một lần | tồn không tự nhiên hụt |
| 06 | nhân viên kho | sửa một lần ghi nhầm bằng một dòng điều chỉnh mới | lịch sử vẫn thấy cả cái sai lẫn cái sửa |
| 07 | đội vận hành | sửa hoặc xóa thẳng một dòng sổ hỏng sau sự cố | cứu dữ liệu cho merchant mà không phải đụng vào giao diện của họ |
5. Yêu cầu chức năng
| # | Yêu cầu | Trạng thái | URD ref |
|---|---|---|---|
FR-001 | Mọi thay đổi tồn kho do nghiệp vụ gây ra đều ghi thêm một dòng mới vào sổ biến động. • Áp cho toàn bộ nghiệp vụ chạm tồn: nhập mua hàng, bán hàng, giữ tồn, nhả tồn, tiêu hao nguyên liệu, chuyển kho, kiểm kê, hủy hàng, khởi tạo tồn lần đầu. • Sổ chỉ được thêm dòng: không nghiệp vụ nào xóa hay ghi đè một dòng đã có. • Một dòng sổ gắn với đúng một mục kho - một mặt hàng, tại một kho, theo một lô nếu mặt hàng có theo dõi lô. | 🔶 | URD-LDG-001 |
FR-002 | Mỗi dòng sổ ghi đủ bộ ba con số của lần biến động đó. • Tồn trước khi đổi. • Số lượng thay đổi, mang dấu: cộng khi hàng vào, trừ khi hàng ra. • Tồn sau khi đổi, luôn bằng tồn trước cộng số lượng thay đổi. | 🔶 | URD-LDG-002 |
FR-003 | Mỗi dòng sổ mang một lý do lấy từ danh mục cố định, không gõ tự do. • Nhóm mua hàng: Nhập mua hàng, Trả nhà cung cấp. • Nhóm bán hàng: Giữ tồn giỏ hàng, Nhả giữ tồn giỏ hàng, Bán hàng trừ kho, Bán vượt tồn bị chặn, Khách trả hàng. • Nhóm nguyên liệu và sản xuất: Giữ nguyên liệu, Tiêu hao nguyên liệu, Sản xuất tiêu hao, Sản xuất nhập thành phẩm. • Nhóm kho: Giữ tồn phiếu chuyển kho, Nhả giữ tồn phiếu chuyển kho, Chuyển kho xuất, Chuyển kho nhận, Kiểm kê điều chỉnh, Sửa sai, Hàng hỏng, Hàng mất, Hàng hết hạn. • Nhóm khởi tạo: Khởi tạo tồn sản phẩm, Khởi tạo tồn nguyên vật liệu. | 🔶 | URD-LDG-003 |
FR-004 | Mỗi dòng sổ tham chiếu về đúng một chứng từ nguồn, ghi bằng hai phần: loại chứng từ và mã chứng từ. • Các loại chứng từ nhận được: đơn mua hàng, đơn bán hàng, phiếu bếp, phiếu kho, lệnh sản xuất, và điều chỉnh tay khi merchant sửa thẳng số tồn. • Bấm vào mã chứng từ trên màn Lịch sử biến động mở thẳng chứng từ đó. | 🔶 | URD-LDG-004 |
FR-005 | Mỗi dòng sổ chụp lại bối cảnh đơn vị và giá tại đúng thời điểm phát sinh. • Đơn vị tính người lập chứng từ đã dùng, ví dụ nhập theo thùng. • Hệ số quy đổi ra đơn vị gốc đã dùng lúc đó, ví dụ 1 thùng bằng 24 lon. • Giá vốn một đơn vị tại thời điểm đó. • Các con số này giữ nguyên trên dòng sổ kể cả khi merchant đổi đơn vị, đổi hệ số hay giá vốn trôi đi sau này. | 🔶 | URD-LDG-005 |
FR-006 | Mỗi dòng sổ giữ thêm bối cảnh hàng hóa và nơi chốn của lần biến động. • Kho gửi và kho nhận - dòng chuyển kho có cả hai, dòng nhập chỉ có kho nhận, dòng xuất chỉ có kho gửi. • Mã lô, hạn dùng và mã serial nếu mặt hàng có theo dõi lô hoặc serial. • Người thao tác và thời điểm phát sinh. • Một ô ghi chú tự do, là tùy chọn. | 🔶 | URD-LDG-010 · URD-LSE-002 |
FR-007 | Nhập hàng với giá khác giá định mức đang cấu hình thì phần chênh lệch được ghi ngay trên dòng sổ của lần nhập đó. • Chênh lệch là con số quan sát được: lần nhập này mua đắt hơn hay rẻ hơn định mức bao nhiêu. • Không sinh bút toán kế toán và không đẩy qua module Tài chính. | 🚧 | URD-LDG-005 · URD-VAL-008 |
FR-008 | Cùng một chứng từ, dù bị xử lý lại nhiều lần, chỉ để lại đúng một dòng sổ cho mỗi dòng tồn liên quan. • Khóa chống trùng là bộ ba: chứng từ nguồn, lý do, và mục kho bị tác động. • Xử lý lại một chứng từ đã ghi sổ thì kho không bị cộng hay trừ lần thứ hai, và không sinh dòng sổ thứ hai. • Việc chống trùng không dựa vào việc đếm dòng sổ hiện có, nên xóa hay sửa một dòng sổ cũng không mở lại đường cho lần trừ kho thứ hai. | 🚧 | URD-LDG-006 |
FR-009 | Sửa sai là ghi thêm một dòng điều chỉnh mới, không đụng vào dòng cũ. • Dòng điều chỉnh mang lý do Sửa sai và trỏ về chứng từ gốc, để người đọc nối được cái sai với cái sửa. • Dòng ghi sai vẫn nằm nguyên trong lịch sử. • Không nghiệp vụ nào của merchant - bán, nhập, chuyển, kiểm kê - có đường sửa hay xóa một dòng sổ. | 🔶 | URD-LDG-001 |
FR-010 | Sổ biến động là nguồn sự thật của tồn kho; bảng tồn là bản tổng hợp để đọc nhanh. • Cộng dồn toàn bộ dòng sổ của một mục kho ra đúng số thực có đang hiển thị trên bảng tồn. • Hai bên lệch nhau thì sổ là bên đúng, và bảng tồn được dựng lại theo sổ. | 🔶 | URD-LDG-007 |
FR-011 | Merchant mở màn Lịch sử biến động để xem toàn bộ dòng sổ của một mặt hàng tại một kho, mới nhất lên đầu. • Mỗi dòng hiển thị: thời điểm, lý do, chứng từ nguồn, tồn trước, số lượng thay đổi, tồn sau, đơn vị, giá vốn tại thời điểm đó, người thao tác. • Mặt hàng có theo dõi lô hiển thị thêm cột mã lô và hạn dùng. | 🚧 | URD-LDG-008 |
FR-012 | Màn Lịch sử biến động lọc được để tìm nhanh một lần biến động. • Lọc theo khoảng thời gian. • Lọc theo lý do, chọn nhiều lý do cùng lúc. • Lọc theo loại chứng từ hoặc gõ thẳng mã chứng từ. • Lọc theo kho khi mặt hàng có mặt ở nhiều kho. | 🚧 | URD-LDG-008 |
FR-013 | Màn Lịch sử biến động mở được từ màn chi tiết mục kho, giữ nguyên mặt hàng và kho đang xem, không bắt merchant chọn lại. | 🚧 | URD-LDG-008 |
FR-014 | Đội vận hành sửa hoặc xóa trực tiếp một dòng sổ khi cần cứu dữ liệu sau sự cố. • Đây là công cụ nội bộ dùng ngoài giao diện merchant. • Chỉ dùng khi dòng điều chỉnh thông thường không xử lý được, ví dụ dòng sổ bị hỏng dữ liệu nặng. • Đường sửa/xóa dòng sổ khóa cho riêng đội vận hành: một vai trò của merchant, kể cả vai trò có toàn quyền trên kho, không chạm được vào dòng sổ. • Thao tác này làm trên màn hình vận hành ở Back Office. | 🔶 | URD-LDG-009 |
FR-015 | Sổ biến động là dữ liệu riêng của từng merchant. Merchant chỉ đọc được dòng sổ của chính mình, và mọi bộ lọc đều nằm trong phạm vi đó. | 🔶 | URD-LDG-011 |
5.1 Tiêu chí nghiệm thu
- Nhập 5 đơn vị vào một mặt hàng đang tồn 10 theo một phiếu nhập kho → mở Lịch sử biến động của mặt hàng đó → thấy một dòng mới: trước 10, đổi +5, sau 15, lý do Nhập mua hàng, chứng từ là mã phiếu nhập vừa lập.
- Bán 2 lon một mặt hàng tại quầy → mở Lịch sử biến động → thấy dòng Giữ tồn giỏ hàng khi thu ngân bấm món, rồi dòng Bán hàng trừ kho khi đơn thanh toán xong, mỗi dòng đủ trước/đổi/sau.
- Nhập hàng bằng đơn vị thùng, mặt hàng khai 1 thùng bằng 24 lon → xem dòng sổ vừa sinh ra → dòng ghi đơn vị là thùng, hệ số quy đổi 24, và số lượng thay đổi quy về đơn vị gốc là 24 lon cho mỗi thùng.
- Đổi hệ số quy đổi của mặt hàng đó từ 24 sang 20, rồi mở lại dòng sổ cũ → dòng cũ vẫn hiển thị hệ số 24 và số lượng cũ, không bị tính lại theo hệ số mới.
- Xem một dòng bán hàng đã xảy ra tháng trước, sau đó giá vốn của mặt hàng đã thay đổi → dòng sổ cũ vẫn hiển thị giá vốn của đúng lúc bán, không đổi theo giá vốn hiện tại.
- Một mặt hàng đang dùng giá định mức 20.000đ, nhập một lô với giá thật 22.000đ → dòng sổ của lần nhập đó hiển thị phần chênh lệch mua đắt hơn định mức, và không có bút toán kế toán nào được sinh ra.
- Thanh toán một đơn hàng, hệ thống gửi lại thông báo thanh toán thành công lần thứ hai → không có dòng sổ thứ hai nào được ghi cho cùng dòng hàng đó, và tồn kho không bị trừ hai lần.
- Xóa một dòng sổ bằng cửa thoát vận hành rồi để hệ thống xử lý lại đúng chứng từ đó → tồn kho vẫn không bị trừ lần thứ hai.
- Một dòng sổ ghi nhầm số lượng → ghi một dòng điều chỉnh mới với lý do Sửa sai, trỏ về chứng từ gốc → mở Lịch sử biến động thấy đủ cả hai dòng, dòng ghi sai vẫn còn nguyên.
- Cộng dồn số lượng thay đổi của toàn bộ dòng sổ của một mục kho → kết quả bằng đúng số thực có đang hiển thị trên màn tồn kho của mục kho đó.
- Mở màn chi tiết một mục kho rồi bấm Xem lịch sử biến động → màn Lịch sử biến động mở ra đã lọc sẵn đúng mặt hàng và đúng kho đang xem, mới nhất lên đầu.
- Trên màn Lịch sử biến động, lọc lý do là Kiểm kê điều chỉnh trong khoảng một tháng → chỉ các dòng kiểm kê trong tháng đó hiện ra, các dòng bán hàng và nhập hàng bị ẩn.
- Bấm vào mã chứng từ của một dòng sổ → hệ thống mở thẳng chứng từ đó, ví dụ đơn bán hàng hoặc phiếu nhập kho tương ứng.
- Mặt hàng có theo dõi lô, xuất 3 đơn vị từ lô B → dòng sổ hiển thị thêm mã lô B và hạn dùng của lô đó.
- Chuyển 5 đơn vị từ kho A sang kho B → các dòng sổ của lần chuyển đó ghi cả kho gửi là kho A và kho nhận là kho B, kèm tên người thao tác và thời điểm phát sinh.
- Nhập 5 đơn vị vào kho A bằng một phiếu nhập → dòng sổ chỉ mang kho nhận là kho A, không có kho gửi; dòng xuất hàng thì ngược lại, chỉ mang kho gửi.
- Người lập phiếu gõ một ghi chú vào phiếu điều chỉnh → mở dòng sổ tương ứng thấy đúng ghi chú đó; để trống ghi chú thì dòng sổ vẫn ghi được bình thường.
- Lập một phiếu chuyển kho và đưa vào trạng thái Chờ chuyển → dòng sổ ghi một lần giữ tồn trên kho gửi với lý do Giữ tồn phiếu chuyển kho; hủy phiếu chuyển đó → dòng sổ ghi thêm một lần nhả với lý do Nhả giữ tồn phiếu chuyển kho.
- Một dòng sổ bị hỏng dữ liệu nặng sau sự cố → đội vận hành sửa hoặc xóa dòng đó qua công cụ nội bộ → merchant mở giao diện của mình không thấy nút sửa hay nút xóa nào trên dòng sổ.
- Đăng nhập bằng một vai trò của merchant có toàn quyền trên kho rồi gọi thẳng đường sửa/xóa dòng sổ → hệ thống từ chối, vì đường đó chỉ mở cho đội vận hành.
- Đăng nhập bằng tài khoản của merchant B rồi mở Lịch sử biến động → chỉ thấy dòng sổ của merchant B, không thấy bất kỳ dòng nào của merchant A.
6. Yêu cầu phi chức năng
| Khía cạnh | Yêu cầu |
|---|---|
| Chỉ-thêm | Không đường nghiệp vụ nào sửa hay xóa một dòng sổ đã ghi; chỉ cửa thoát vận hành nội bộ có quyền đó |
| Chống ghi trùng | Bộ ba chứng từ nguồn + lý do + mục kho là khóa duy nhất được ép ở tầng cơ sở dữ liệu, không dựa vào việc đếm dòng sổ hiện có trước khi ghi |
| Nguyên tử | Việc ghi dòng sổ và việc đổi số tồn xảy ra trong cùng một lần lưu - không có trạng thái tồn đã đổi mà sổ chưa ghi, hay ngược lại |
| Chính xác dưới tải đồng thời | Nhiều thao tác chạm cùng một mục kho cùng lúc vẫn ghi ra bộ ba trước/đổi/sau đúng cho từng dòng, không dựa trên một số tồn đọc từ trước rồi mới ghi |
| Phân quyền theo merchant | Mọi dòng sổ giới hạn trong merchant của chính người dùng; đọc yêu cầu xác thực |
| Hiệu năng | Màn Lịch sử biến động phân trang, và mở nhanh cả khi một mục kho đã có hàng trăm nghìn dòng sổ |
| Độ chính xác số học | Số lượng và giá vốn trên dòng sổ dùng độ chính xác 4 chữ số thập phân |
| i18n | Nhãn lý do và nhãn loại chứng từ hiển thị song ngữ |
7. UX & Luồng
Màn Lịch sử biến động nằm ở trang Client, mở từ màn chi tiết mục kho. Đội vận hành thao tác cửa thoát sửa/xóa dòng sổ bằng công cụ nội bộ, không nằm trong giao diện merchant.
8. Dữ liệu & Miền nghiệp vụ
| Khái niệm | Vai trò |
|---|---|
| Dòng sổ biến động | Một lần tồn của một mục kho thay đổi - đơn vị ghi nhỏ nhất của sổ, chỉ thêm, không sửa không xóa |
| Bộ ba trước/đổi/sau | Tồn trước, số lượng thay đổi mang dấu, tồn sau - ba con số làm nên tính kiểm tra được của một dòng |
| Lý do | Vì sao tồn đổi, chọn từ một danh mục cố định, không gõ tự do |
| Chứng từ nguồn | Loại chứng từ và mã chứng từ đứng sau lần biến động - đơn mua, đơn bán, phiếu bếp, phiếu kho, lệnh sản xuất, điều chỉnh tay |
| Bối cảnh tại thời điểm | Đơn vị tính, hệ số quy đổi, giá vốn, lô, hạn dùng, serial - chụp lại và không đổi về sau |
| Khóa chống trùng | Bộ ba chứng từ nguồn + lý do + mục kho - đảm bảo một chứng từ chỉ ghi sổ một lần cho mỗi mục kho |
| Dòng điều chỉnh | Một dòng sổ mới ghi để sửa một dòng sai trước đó, trỏ về cùng chứng từ gốc |
| Cửa thoát vận hành | Đường sửa/xóa trực tiếp dòng sổ dành cho đội vận hành, ngoài giao diện merchant |
Chỉ ở mức khái niệm - schema và bất biến đầy đủ nằm trong inventory domain model.
9. Phụ thuộc & Giả định
Phụ thuộc vào
| # | Feature | Phụ thuộc điều gì |
|---|---|---|
| 01 | STK Mục kho & mức tồn | mỗi dòng sổ gắn với đúng một mục kho, và tồn trước/tồn sau đọc theo mục kho đó. |
| 02 | UOM Đơn vị tính & quy đổi | hệ số quy đổi chụp trên dòng sổ lấy từ engine quy đổi lúc lập chứng từ. |
| 03 | VAL Giá vốn | giá vốn tại thời điểm và phần chênh lệch so với giá định mức đều lấy từ đây. |
| 04 | TKT Phiếu kho · PO Đơn mua hàng · CNT Kiểm kê · TRF Chuyển kho, và luồng bán hàng | đây là các nguồn sinh ra dòng sổ. |
| 05 | LSE Lô, hạn dùng & chiến lược xuất | mã lô, hạn dùng và serial chụp trên dòng sổ. |
Giả định
| # | Giả định | Sai thì sao |
|---|---|---|
| 01 | Mọi nghiệp vụ chạm tồn đều đi qua một chứng từ có mã, kể cả việc merchant sửa thẳng số tồn trên màn quản trị - lần sửa đó được coi là một chứng từ điều chỉnh tay. | Một biến động không có chứng từ thì không có khóa chống trùng, không truy ngược được, và dòng sổ đó không giải thích được cho ai. |
| 02 | Một chứng từ có thể bị xử lý lại nhiều lần, nên chống trùng là mặc định, không phải trường hợp ngoại lệ. | Coi việc xử lý lại là ngoại lệ thì mỗi lần gửi lại thông báo thanh toán là một lần trừ kho thừa, và tồn hụt dần mà không ai giải thích được. |
| 03 | Merchant chấp nhận đọc sổ để giải thích lệch số, thay vì trông chờ hệ thống tự vá số cho khớp. | Hệ thống tự vá số thì phần lệch bị chôn đi, nguyên nhân thật không bao giờ lộ ra, và cùng một lỗi lặp lại mãi. |
10. Kế hoạch phát hành & Tiêu chí
| Khía cạnh | Kế hoạch |
|---|---|
| Phase | Phase 2 - xem danh mục feature URD |
| Rollout | Mọi merchant; không feature flag. Màn Lịch sử biến động mở cho vai trò chủ merchant và quản lý |
| Migration | Dòng sổ đã có được giữ nguyên. Bổ sung khóa chống trùng cần một bước dọn dữ liệu: gom các dòng trùng bộ ba chứng từ + lý do + mục kho, giữ dòng sớm nhất, trước khi ép khóa |
| Tiêu chí phát hành | Cộng dồn sổ ra đúng tồn trên các mục kho lấy mẫu; xử lý lại một chứng từ không sinh dòng thứ hai; màn Lịch sử biến động mở được từ chi tiết mục kho và lọc đúng theo lý do, chứng từ, khoảng thời gian |
| Theo dõi | Số ca tồn lệch không giải thích được, số lần chống trùng chặn một lần ghi lặp, lượt mở màn Lịch sử biến động, số lần đội vận hành phải dùng cửa thoát |
Tham chiếu
- URD: Sổ biến động · Cách hệ thống nghĩ về tồn kho
- Liên quan: Mục kho & mức tồn · Giá vốn · Đơn vị tính & quy đổi · Phiếu kho · Kiểm kê
- Module: Kho - URD
- Developer: @nx/inventory · domain model
Rủi ro & Câu hỏi mở
| # | Rủi ro / câu hỏi | Giảm thiểu / trạng thái |
|---|---|---|
| 01 | Chống trùng dựa vào việc đếm dòng sổ hiện có trước khi ghi thì rất mong manh - xóa một dòng sổ là mở đường cho lần trừ kho thứ hai | Khóa duy nhất ép ở tầng cơ sở dữ liệu trên bộ ba chứng từ + lý do + mục kho (FR-008), không dựa vào việc đếm dòng |
| 02 | Cửa thoát vận hành cho phép sửa/xóa dòng sổ, mà sổ lại là nguồn sự thật của tồn kho | Cửa thoát nằm ngoài giao diện merchant, chỉ đội vận hành dùng khi cứu dữ liệu (FR-014); khóa chống trùng ở tầng dữ liệu vẫn giữ dù dòng sổ bị xóa (FR-008) |
| 03 | Bộ ba trước/đổi/sau đọc từ một số tồn lấy trước khi ghi có thể ghi sai khi nhiều thao tác chạm cùng một mục kho cùng lúc, dù số tồn cuối cùng vẫn đúng | Bộ ba được lấy ngay tại lần ghi tồn, không lấy từ một số đọc trước đó (§6, dòng "Chính xác dưới tải đồng thời") |
| 04 | Sổ phình rất nhanh với merchant bán nhiều - mỗi lon bán ra là hai dòng (giữ và trừ) | Màn Lịch sử biến động phân trang và luôn lọc theo mặt hàng + kho; ngưỡng lưu trữ dài hạn cho sổ cũ để mở |
| 05 | Merchant nhầm màn Lịch sử biến động với sổ kế toán thuế của hộ kinh doanh, vì cả hai đều gọi là "sổ" | Đặt màn này trong nhóm Kho và gọi đúng tên Lịch sử biến động, không gọi tắt là "sổ" trên điều hướng |
| 06 | Danh mục lý do dài, merchant khó lọc | Nhóm lý do theo nghiệp vụ trên bộ lọc (mua hàng, bán hàng, nguyên liệu, kho, khởi tạo) thay vì đổ một danh sách phẳng (FR-003, FR-012) |
Câu hỏi thường gặp
| # | Câu hỏi | Trả lời |
|---|---|---|
| 01 | Sổ biến động khác gì bảng tồn? | Bảng tồn cho biết hôm nay còn bao nhiêu - một con số. Sổ biến động cho biết vì sao ra con số đó - từng lần đổi một, kèm lý do và chứng từ. Bảng tồn dựng lại được từ sổ; sổ thì không dựng lại được từ bảng tồn. Khi hai bên lệch nhau, sổ là bên đúng. |
| 02 | Vì sao không cho sửa một dòng sổ ghi sai? | Vì sửa dòng cũ là xóa mất dấu vết của cái sai, và người đọc sổ về sau không còn hiểu chuyện gì đã xảy ra. Sửa sai là ghi thêm một dòng điều chỉnh mới trỏ về cùng chứng từ; sổ giữ cả cái sai lẫn cái sửa. |
| 03 | Vậy tại sao đội vận hành lại xóa được? | Có những dòng hỏng nặng vì sự cố hệ thống, không cứu được bằng một dòng điều chỉnh. Cửa thoát đó là công cụ nội bộ dùng để cứu dữ liệu. Merchant mở giao diện của mình không thấy nút sửa hay xóa nào trên dòng sổ. |
| 04 | Một đơn hàng bán một lon thì sinh ra mấy dòng sổ? | Hai. Một dòng khi thu ngân bấm món vào giỏ, lý do Giữ tồn giỏ hàng, thực có chưa đổi nhưng khả dụng giảm. Một dòng nữa khi đơn thanh toán xong, lý do Bán hàng trừ kho, hàng rời kệ thật. |
| 05 | Nếu hệ thống gửi lại thông báo thanh toán thì kho có bị trừ hai lần không? | Không. Cùng một chứng từ và cùng một mục kho chỉ ghi được đúng một dòng sổ, và ràng buộc đó được ép ở tầng dữ liệu, không bằng cách đếm xem đã có dòng nào chưa rồi mới ghi. |
| 06 | Đọc lại một dòng sổ từ năm ngoái có bị lệch vì cấu hình đã đổi không? | Không. Đơn vị, hệ số quy đổi và giá vốn được chụp ngay trên dòng sổ tại thời điểm phát sinh, nên chúng đứng yên dù merchant đổi đơn vị hay giá vốn trôi đi sau đó. |
| 07 | Màn Lịch sử biến động có phải sổ kế toán thuế không? | Không. Đây là sổ của kho, ghi hàng vào hàng ra. Sổ kế toán thuế của hộ kinh doanh là một cuốn khác, nằm ở module khác. |