PRD: Phiếu kho
| Module | Kho | PRD ID | PRD-TKT-001 |
| Trạng thái | Đã thay thế | FEAT | TKT |
| Epic | — | Plane | — |
| Ngày | 2026-07-14 | Phiên bản | v1.0 |
| Gói | @nx/inventory | URD | TKT |
| Surface | Client · Chủ/QL | ||
| Phụ trách | Phát Nguyễn | ||
Phiếu kho là gì
Phiếu kho (Inventory Ticket) là chứng từ đứng sau mỗi lần tồn thay đổi ngoài đường bán hàng: hàng vào, hàng ra, hoặc số tồn cần sửa. Người lập chọn đúng một trong chín loại - yêu cầu mua hàng, nhập kho, chuyển kho, xuất dùng nội bộ, điều chỉnh, kiểm kê, trả nhà cung cấp, trả từ khách, hủy/tiêu hủy.
Một chi nhánh (Merchant) lập phiếu tại trang Client, cho một hoặc hai kho (InventoryLocation) tùy loại phiếu. Một việc chuyển hàng có thể chạm hai chi nhánh cùng nằm trong một tổ chức (Organizer).
Đây là khung chung. Chuyển kho và kiểm kê là hai loại phiếu nằm trong chính khung này, không phải hai cơ chế riêng.
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ữMột phiếu được duyệt thì phần hàng đã hứa nằm ở đang giữ. Chỉ khi phiếu con hoàn tất, thực có mới thay đổi.
Vì sao mọi lần tồn đổi đều phải có một tờ chứng từ
Tồn kho không được phép tự nhảy số. Mỗi lần con số thay đổi, phải có một tờ chứng từ đứng sau nó, có người lập và có người duyệt. Đó là cách merchant giải thích được vì sao hôm nay còn 60 thùng chứ không phải 100.
Không có chứng từ thì mọi thay đổi tồn ngoài đường bán hàng chỉ còn cách sửa thẳng vào bảng tồn: mở màn Tồn kho, gõ đè số lượng, và không còn dấu vết nào cho biết ai sửa, sửa vì lý do gì. Nhập một chuyến hàng, hủy một thùng sữa hỏng, trả hàng lỗi cho nhà cung cấp: tất cả trông giống nhau trong hệ thống, chỉ là một con số bị gõ đè.
Một phiếu nhập kho, từ đầu tới cuối
Kho đang có 500 thùng. Nhập thêm 100 thùng. Đây là chỗ luật quan trọng nhất của khung phiếu lộ ra: tồn không nhúc nhích cho tới bước cuối cùng.
| Việc xảy ra | Trạng thái phiếu | Thực có kho |
|---|---|---|
| Soạn phiếu nhập 100 thùng | Nháp | 500 |
| Gửi duyệt | Đã gửi | 500 |
| Chủ quán duyệt | Đã duyệt | 500 |
| Thủ kho bắt đầu nhận hàng | Đang thực hiện | 500 |
| Ghi thực nhận 100, bấm hoàn tất | Hoàn tất | 600 |
- Duyệt là đồng ý cho làm, không phải là đã làm xong. Hàng chưa vào kệ mà tồn đã tăng thì con số trên màn Tồn kho không còn là số thật.
- Chỉ ở bước hoàn tất, tồn mới đổi và sổ biến động mới ghi một dòng mang lý do và mã phiếu.
- Chữ hiển thị đổi theo loại phiếu. Phiếu chuyển kho gọi Đã duyệt là Chờ chuyển, Đang thực hiện là Đang chuyển, Hoàn tất là Đã nhận. Bên dưới vẫn là một bộ trạng thái duy nhất.
- Một việc chuyển hàng lớn thì phiếu cha ghi ý định, còn các phiếu con ghi từng chuyến xuất và từng lần nhập. Trạng thái phiếu cha suy ra từ các phiếu con.
Chỗ dễ sai nhất
Phiếu đã hoàn tất là chốt: không sửa, không xóa
Bấm hoàn tất nhầm, ghi 60 thành 50, chọn sai lý do - không có nút Sửa và không có nút Xóa, kể cả khi phiếu cha bị đóng hoặc bị hủy về sau.
Cách duy nhất để đưa số về đúng là lập một phiếu bù mới: một chuyến xuất bù, một lần nhận bù, hoặc một phiếu điều chỉnh. Sửa sai là ghi thêm một tờ, không phải xé tờ cũ.
Nhờ luật này, lịch sử tồn kho không bao giờ bị viết lại sau lưng. Và hàng đã rời kho mà không tới nơi cũng không im lặng biến mất: người lập bấm Đóng phiếu, và việc đóng phiếu sinh ra một phiếu điều chỉnh ghi đúng phần thất thoát kèm lý do.
1. Mục tiêu & Loại trừ
Mục tiêu
- Cho merchant một sổ phiếu kho tại trang Client: lập phiếu, xem danh sách, mở chi tiết, gửi duyệt, duyệt, thực hiện, hoàn tất, đóng, hủy.
- Định nghĩa một vòng đời duy nhất cho cả chín loại phiếu, và nói rõ loại nào đi phần nào của vòng đời đó.
- Cho phép mỗi loại phiếu đổi chữ hiển thị theo nghiệp vụ của nó mà không phát sinh thêm bộ trạng thái thứ hai.
- Ép luật "tồn chỉ đổi khi phiếu hoàn tất" thành hành vi thật của hệ thống, không phải một quy ước.
- Dựng quan hệ một phiếu cha - nhiều phiếu xuất - nhiều phiếu nhập, để việc thực hiện từng đợt và việc hai chi nhánh cùng tham gia là chuyện bình thường.
- Tách rạch ròi đóng phiếu (có hàng mất, sinh phiếu điều chỉnh) khỏi hủy phiếu (không có hàng nào mất).
- Bảo đảm khung phiếu chỉ ghi thêm: phiếu con đã hoàn tất không sửa, không xóa.
Loại trừ
- Luật riêng của chuyển kho: bốn con số ở hai đầu, hàng đang trên đường, bảng luật hủy và đóng phiếu chi tiết (thuộc TRF).
- Luật riêng của kiểm kê: chụp mốc số sổ, đếm song song với bán hàng, áp chênh lệch (thuộc CNT).
- Cấu trúc và luật của đơn mua hàng: giá, số lượng đặt tối thiểu, đối chiếu với nhà cung cấp (thuộc PO).
- Cách tính giá vốn khi nhập hàng (thuộc VAL) và cách chọn lô lúc xuất (thuộc LSE).
- Việc trừ tồn của đường bán hàng: bán hàng giữ trước trừ sau, không đi qua phiếu kho.
2. Thước đo thành công
| Thước đo | Mục tiêu / tín hiệu |
|---|---|
| Truy vết được nguồn gốc thay đổi tồn | Mọi biến động tồn ngoài bán hàng đều chỉ về được một phiếu kho có người lập |
| Bỏ thói quen gõ đè số tồn | Số lần merchant sửa thẳng số lượng trên màn Tồn kho giảm dần về gần 0 sau khi sổ phiếu mở |
| Đúng số, không trùng số | Tổng số lượng ghi vào sổ biến động khớp đúng với tổng số thực nhận và thực xuất trên các phiếu đã hoàn tất |
| Hàng mất luôn có chứng từ | Mọi phần hàng đã xuất mà không tới nơi đều có một phiếu điều chỉnh ghi thất thoát, không có hàng biến mất im lặng |
| Phiếu không mắc kẹt | Tỉ lệ phiếu nằm quá lâu ở Đã gửi hoặc Đang thực hiện giảm dần |
3. Persona & Tình huống
| Persona | Mục tiêu trong tính năng này |
|---|---|
| Owner | Duyệt phiếu, đóng phiếu khi hàng không về đủ, thấy được ai nhập gì, ai hủy gì, và vì sao tồn đổi |
| Manager / Thủ kho | Lập phiếu, ghi số thực nhận thực xuất từng đợt, bấm hoàn tất khi hàng đã vào kệ |
| System | Suy trạng thái phiếu cha từ các phiếu con, ghi sổ biến động đúng một lần khi phiếu con hoàn tất, sinh phiếu điều chỉnh khi phiếu cha bị đóng |
Kịch bản cốt lõi: thủ kho lập một phiếu chuyển 100 thùng từ Merchant A - Kho mặc định sang Merchant B - Kho mặc định → gửi duyệt → chủ quán duyệt, phiếu hiện "Chờ chuyển" và kho gửi giữ 100 thùng → xe chạy hai chuyến, thủ kho bên gửi ghi hai phiếu xuất 60 rồi 40 → bên nhận nhận hai lần, ghi 60 rồi 38 → còn 2 thùng không bao giờ tới, người lập bấm đóng phiếu, hệ thống sinh một phiếu điều chỉnh ghi 2 thùng thất thoát kèm lý do.
4. User Stories
| # | Là một | Tôi muốn | Để |
|---|---|---|---|
| 01 | thủ kho | lập một phiếu kho ghi rõ loại việc, hai đầu kho và danh sách hàng | mỗi lần tồn đổi đều có một tờ chứng từ thay vì một con số bị gõ đè |
| 02 | chủ merchant | duyệt phiếu trước khi nó được thực hiện | không ai sửa được tồn kho sau lưng tôi |
| 03 | chủ merchant | chắc chắn rằng phiếu mới soạn hay mới duyệt không đụng tới tồn | con số trên màn Tồn kho luôn là số thật đang có trên kệ |
| 04 | thủ kho | ghi số thực xuất và thực nhận đúng như hàng thật, kể cả khi nó lệch số kế hoạch | sổ sách phản ánh đúng chuyện đã xảy ra |
| 05 | thủ kho | xuất hàng làm nhiều chuyến trên cùng một phiếu | không phải lập ba tờ phiếu rời rạc cho một việc |
| 06 | chủ merchant | bấm đóng phiếu khi biết chắc hàng không về nữa | phần hàng mất được ghi thành thất thoát có lý do thay vì treo mãi |
| 07 | chủ merchant | hủy một phiếu lập nhầm khi hàng chưa đi | phần tồn đang giữ được trả lại ngay cho việc bán hàng |
| 08 | chủ merchant | biết chắc không ai sửa được một phiếu đã hoàn tất | lịch sử tồn kho của tôi không bị viết lại sau lưng |
5. Yêu cầu chức năng
| # | Yêu cầu | Trạng thái | URD ref |
|---|---|---|---|
FR-001 | Phiếu kho là chứng từ cho một lần hàng vào, hàng ra hoặc sửa số tồn, và người lập chọn đúng một trong chín loại lúc tạo phiếu. • Yêu cầu mua hàng - đề nghị mua thêm, không động tới tồn. • Nhập kho - hàng từ ngoài về một kho. • Chuyển kho - hàng đi từ một kho sang một kho khác. • Xuất dùng nội bộ - hàng rời kho để dùng cho việc nội bộ, không bán. • Điều chỉnh - sửa số tồn về đúng thực tế, kèm lý do. • Kiểm kê - đếm hàng thật và áp phần chênh lệch. • Trả nhà cung cấp - hàng đi ngược về nhà cung cấp. • Trả từ khách - hàng khách trả lại, nhập ngược vào kho. • Hủy/tiêu hủy - hàng hỏng, hết hạn, bỏ đi. • Loại phiếu chốt lúc tạo, không đổi được về sau. | 🔶 | URD-TKT-001 |
FR-002 | Chín loại phiếu dùng chung đúng một vòng đời, và người dùng chỉ bấm được nút của bước kế tiếp. • Nháp - phiếu đang soạn, sửa thoải mái. • Đã gửi - phiếu đã gửi đi chờ duyệt, nội dung khóa lại. • Đã duyệt - người có quyền đã đồng ý, phiếu sẵn sàng thực hiện. • Đang thực hiện - hàng đang được nhập, xuất hoặc đếm thật. • Hoàn tất - việc đã xong. • Hủy được từ bất kỳ bước nào chưa hoàn tất. Không nhảy cóc bước. | 🚧 | URD-TKT-002 |
FR-003 | Mỗi loại phiếu chỉ đi phần vòng đời nó cần, và không loại nào phát sinh thêm bước mới. • Phiếu điều chỉnh: Nháp → Hoàn tất. Màn hình không hiện nút Gửi duyệt và nút Duyệt. • Phiếu kiểm kê: Nháp → Đang thực hiện → Hoàn tất, không có bước duyệt riêng. • Phiếu chuyển kho: đi đủ cả năm bước. | 🚧 | URD-TKT-003 |
FR-004 | Nhãn trạng thái hiển thị theo từng loại phiếu, dù bên dưới vẫn là một bộ trạng thái duy nhất. • Phiếu chuyển kho hiện Đã duyệt thành Chờ chuyển, Đang thực hiện thành Đang chuyển, Hoàn tất thành Đã nhận. • Phiếu kiểm kê hiện Đang thực hiện thành Đang đếm, Hoàn tất thành Đã áp. • Bộ lọc trạng thái trên sổ phiếu dùng đúng chữ của loại phiếu đang lọc. | 🚧 | URD-TKT-004 |
FR-005 | Tồn kho chỉ thay đổi khi phiếu sang Hoàn tất. • Soạn phiếu, gửi phiếu, duyệt phiếu, bắt đầu thực hiện đều không cộng hay trừ một đơn vị tồn nào. • Mở màn Tồn kho lúc phiếu đang ở Đã duyệt vẫn thấy đúng con số cũ. | 🚧 | URD-TKT-005 |
FR-006 | Phiếu cha mang ý định, và trạng thái của nó được suy ra từ các phiếu con. • Phiếu cha ghi hai đầu của việc chuyển hàng - chi nhánh nào, kho nào - cùng danh sách hàng và số lượng kế hoạch. • Một phiếu cha nhận nhiều phiếu xuất và nhiều phiếu nhập, không bị bó vào đúng một cặp. • Màn chi tiết phiếu cha không có nút hay ô nào cho phép tự đặt trạng thái. | 🚧 | URD-TKT-006 |
FR-007 | Phiếu con là chứng từ thực thi và thuộc về chi nhánh của chính đầu mà nó đứng. • Phiếu xuất thuộc merchant gửi; phiếu nhập thuộc merchant nhận. • Phiếu con chỉ có hai bước Nháp và Hoàn tất, vì việc duyệt đã xong ở phiếu cha. • Hoàn tất một phiếu con chỉ ghi tồn phần của chính nó, không đụng tới phần các phiếu con khác chưa làm. | 🚧 | URD-TKT-007 |
FR-008 | Khung phiếu kho chỉ ghi thêm, không ghi đè. • Phiếu con đã hoàn tất không có nút Sửa và không có nút Xóa, kể cả khi phiếu cha bị đóng hoặc bị hủy về sau. • Sửa sai là lập một phiếu bù mới: một chuyến xuất bù, một lần nhận bù, hoặc một phiếu điều chỉnh. Phiếu cũ để nguyên như đã ghi. | 🚧 | URD-TKT-008 |
FR-009 | Phiếu mang một bộ thông tin đầu phiếu, khai lúc tạo và sửa được khi phiếu còn ở Nháp. • Mã phiếu - hệ thống tự sinh, không trùng, dùng để tra cứu và nhắc tới phiếu ở nơi khác. • Kho gửi và kho nhận - mỗi bên chọn một chi nhánh và một kho. Loại phiếu nào cần bên nào thì hiện ô đó: phiếu nhập kho chỉ có kho nhận, phiếu hủy chỉ có kho gửi. • Đối tác - nhà cung cấp hoặc khách hàng, chỉ hiện với các loại phiếu có đối tác. • Lý do - chọn từ danh sách có sẵn, bắt buộc với phiếu điều chỉnh và phiếu hủy/tiêu hủy. • Ghi chú tự do là tùy chọn. | 🔶 | URD-TKT-009 |
FR-010 | Mỗi dòng hàng trên phiếu khai mặt hàng, đơn vị và số lượng, và mang trạng thái riêng của dòng đó. • Mặt hàng - một biến thể sản phẩm hoặc một nguyên vật liệu. • Đơn vị tính - chọn từ đơn vị của chính mặt hàng đó. Hệ thống tự quy đổi về đơn vị gốc, người dùng không điền hệ số. • Số lượng kế hoạch khai lúc lập phiếu; số lượng thực tế ghi lúc thực hiện. • Lô và hạn dùng hiện với mặt hàng có quản lô. Đơn giá hiện với phiếu nhập kho và phiếu trả nhà cung cấp. • Trạng thái dòng - chờ xử lý, đang xử lý, hoàn tất, hủy - nên một phiếu có dòng đã xong và dòng chưa xong cùng lúc. | 🔶 | URD-TKT-010 |
FR-011 | Khi một phiếu sang Hoàn tất, mỗi dòng hàng ghi đúng một dòng sổ biến động. • Dòng sổ ghi rõ số trước, số thay đổi, số sau, lý do và mã phiếu nguồn. • Phiếu bị xử lý lại không sinh thêm dòng sổ thứ hai cho cùng một dòng hàng, và tồn không bị cộng trừ hai lần. | 🚧 | URD-TKT-011 |
FR-012 | Số thực tế khác số kế hoạch không chặn phiếu hoàn tất. • Xuất ít hơn kế hoạch, xuất nhiều hơn kế hoạch, nhận ít hơn số đã xuất, nhận nhiều hơn số đã xuất: cả bốn đều được phép. • Phiếu hoàn tất theo đúng số thực tế và tồn cộng trừ theo số thực tế, không ép khớp về số kế hoạch. | 🚧 | URD-TKT-012 |
FR-013 | Người lập bấm Đóng phiếu khi hàng đã đi mà không về đủ, và việc đóng phiếu sinh một phiếu điều chỉnh ghi phần thất thoát. • Nút Đóng phiếu chỉ hiện trên phiếu cha, và chỉ khi tổng đã xuất lớn hơn tổng đã nhận. • Hệ thống hỏi lại số lượng sẽ ghi thất thoát và bắt chọn một lý do trước khi đóng. • Phiếu điều chỉnh sinh ra mang đúng số thất thoát, lý do đã chọn và mã phiếu cha. Phiếu đã đóng không mở lại được. | 🚧 | URD-TKT-013 |
FR-014 | Hủy phiếu và đóng phiếu là hai việc khác nhau, và giao diện nói rõ sự khác nhau đó. • Hủy phiếu chỉ dừng phần kế hoạch chưa bao giờ được thực hiện: nhả phần đang giữ, không có hàng nào mất, không sinh phiếu điều chỉnh. • Đóng phiếu xử lý phần hàng đã rời kho mà không tới nơi: phần đó là thất thoát và luôn sinh một phiếu điều chỉnh. • Hủy một phiếu cha khi vẫn còn hàng đang trên đường thì hệ thống báo rõ số hàng đó sẽ được ghi thất thoát, và chỉ hủy sau khi người dùng xác nhận. | 🚧 | URD-TKT-014 |
FR-015 | Sổ phiếu kho tại trang Client liệt kê phiếu của chi nhánh, mới nhất lên đầu. • Mỗi dòng hiện mã phiếu, loại phiếu, kho liên quan, trạng thái, người lập và ngày tạo. • Lọc được theo loại phiếu, theo trạng thái, theo kho và theo khoảng ngày. • Tìm theo mã phiếu. | 🚧 | URD-TKT-015 |
FR-016 | Chi tiết phiếu ghi lại dấu vết từng bước chuyển trạng thái. • Mỗi bước lưu thời điểm và người bấm nút: lúc gửi, lúc duyệt, lúc bắt đầu thực hiện, lúc hoàn tất, lúc đóng, lúc hủy. • Dấu vết này hiện ngay trên màn chi tiết phiếu, không phải tìm ở chỗ khác. | 🚧 | URD-TKT-016 |
FR-017 | Phiếu kho là dữ liệu riêng của từng chi nhánh (Merchant). • Người dùng chỉ thấy và thao tác được trên phiếu của chi nhánh mình đang làm việc. • Một việc chuyển hàng chạm hai chi nhánh thì mỗi bên chỉ thấy phiếu con của chính mình, không thấy chứng từ của bên kia. | 🔶 | URD-TKT-017 |
FR-018 | Người lập phiếu thấy một dòng duy nhất trong danh sách, không phải học thêm khái niệm nào. • Dòng đó nói đủ việc: chuyển bao nhiêu, từ đâu tới đâu, đang ở bước nào. • Các phiếu con nằm bên trong màn chi tiết như một dòng thời gian của những gì đã làm: xuất chuyến nào, ngày nào, bao nhiêu; nhận lần nào, bao nhiêu. | 🚧 | URD-TKT-018 |
5.1 Tiêu chí nghiệm thu
- Mở sổ phiếu kho tại trang Client, bấm tạo phiếu → chọn được đúng chín loại phiếu trong danh sách, không hơn không kém.
- Tạo một phiếu, lưu xong rồi mở lại → ô loại phiếu bị khóa, không đổi sang loại khác được.
- Mở một phiếu Nháp bất kỳ → chỉ thấy nút của bước kế tiếp, không thấy nút Hoàn tất.
- Lập một phiếu nhập kho, gửi duyệt và duyệt, rồi thử bấm lùi về Nháp → không có nút nào cho phép lùi bước.
- Lập một phiếu điều chỉnh → màn hình chỉ có nút Hoàn tất, không có nút Gửi duyệt và không có nút Duyệt.
- Lập một phiếu kiểm kê → màn hình có nút Bắt đầu đếm rồi tới nút Áp kết quả, không có bước duyệt riêng.
- Lập một phiếu chuyển kho → màn hình có đủ năm bước và nút Hủy.
- Duyệt một phiếu chuyển kho rồi mở sổ phiếu → phiếu hiện chữ "Chờ chuyển"; xuất hàng xong mở lại → phiếu hiện chữ "Đang chuyển".
- Lọc sổ phiếu theo loại Chuyển kho → ô chọn trạng thái đưa ra đúng bộ chữ Chờ chuyển, Đang chuyển, Đã nhận.
- Lập một phiếu nhập kho 100 thùng, gửi và duyệt → mở màn Tồn kho của kho đó → con số tồn không đổi.
- Trên chính phiếu đó, bắt đầu thực hiện, ghi thực nhận 100, bấm hoàn tất → tồn của kho tăng đúng 100 thùng.
- Mở chi tiết một phiếu cha bất kỳ → không có ô hay nút nào cho phép tự đặt trạng thái phiếu cha.
- Lập một phiếu chuyển 100 thùng, xuất chuyến đầu 60 thùng → phiếu cha tự chuyển sang "Đang chuyển" mà không ai bấm nút trạng thái trên phiếu cha.
- Cùng phiếu đó, xuất tiếp chuyến thứ hai 40 thùng và nhận về ba lần → phiếu cha nhận đủ hai phiếu xuất và ba phiếu nhập, không bị chặn vì "đã có một cặp phiếu con".
- Đăng nhập bằng tài khoản của merchant gửi, mở phiếu xuất → sửa và hoàn tất được; mở phiếu nhập của merchant nhận → không thấy phiếu đó trong danh sách của mình.
- Hoàn tất phiếu xuất chuyến đầu 60 thùng → tồn kho gửi giảm đúng 60, phần 40 thùng của chuyến sau chưa được ghi sổ.
- Mở một phiếu con đã hoàn tất → mọi ô nhập bị khóa, không có nút Sửa và không có nút Xóa.
- Ghi nhầm 60 thành 50 trên một phiếu xuất đã hoàn tất → cách duy nhất để đưa số về đúng là lập một phiếu điều chỉnh mới; phiếu xuất cũ giữ nguyên như đã ghi.
- Tạo phiếu xong → mã phiếu tự sinh và hiện ngay trên đầu phiếu; tạo phiếu thứ hai → mã khác phiếu thứ nhất.
- Tạo một phiếu nhập kho → form chỉ hỏi kho nhận (chi nhánh và kho); đổi sang phiếu hủy/tiêu hủy → form chỉ hỏi kho gửi.
- Tạo một phiếu chuyển kho → form hỏi đủ bốn thứ: merchant gửi, kho gửi, merchant nhận, kho nhận.
- Tạo một phiếu điều chỉnh, để trống ô lý do rồi bấm hoàn tất → hệ thống chặn và báo phải chọn lý do.
- Thêm một dòng hàng, chọn đơn vị "thùng" cho mặt hàng đang lưu tồn theo "lon" → không có ô nào bắt điền hệ số quy đổi; hoàn tất phiếu → tồn tăng theo số lon tương ứng.
- Thêm một dòng hàng cho mặt hàng có quản lô → form hiện ô lô và hạn dùng; chọn mặt hàng không quản lô → hai ô đó biến mất.
- Lập một phiếu có hai dòng hàng, hoàn tất một dòng và hủy dòng còn lại → mỗi dòng hiện đúng trạng thái riêng của nó.
- Mở sổ biến động của mặt hàng vừa nhập → thấy đúng một dòng nhập, ghi số trước, số thay đổi 100, số sau, lý do và mã phiếu vừa hoàn tất.
- Bấm hoàn tất lần nữa trên phiếu đã hoàn tất → hệ thống không ghi thêm dòng sổ nào và tồn không tăng thêm 100 lần thứ hai.
- Lập phiếu chuyển 100 thùng rồi xuất 110 thùng → hệ thống cho ghi, phiếu xuất hoàn tất với 110, không có thông báo chặn nào.
- Kho nhận nhận 115 thùng trong khi tổng đã xuất là 110 → hệ thống cho ghi, phiếu nhập hoàn tất với 115.
- Phiếu chuyển 100 thùng đã xuất 60 và mới nhận 38, người lập bấm Đóng phiếu → hệ thống hỏi lại số thất thoát 22 và bắt chọn lý do; xác nhận xong, một phiếu điều chỉnh 22 thùng được sinh ra kèm lý do và mã phiếu cha.
- Mở lại phiếu vừa đóng → không có nút mở lại phiếu.
- Phiếu chuyển 100 thùng vừa được duyệt, chưa xuất lần nào, bấm Hủy → phần 100 thùng đang giữ tại kho gửi được nhả hết, và không có phiếu điều chỉnh nào được sinh ra.
- Phiếu chuyển đã xuất 60 và mới nhận 38, bấm Hủy → hệ thống báo rõ 22 thùng đang trên đường sẽ được ghi thất thoát và bắt xác nhận trước khi hủy.
- Vào sổ phiếu kho, lọc theo loại "Hủy/tiêu hủy" và trạng thái "Hoàn tất" → danh sách chỉ còn phiếu hủy đã hoàn tất.
- Gõ mã phiếu vào ô tìm kiếm → đúng phiếu đó hiện ra.
- Mở chi tiết một phiếu đã đi hết vòng đời → thấy thời điểm và tên người bấm ở từng bước gửi, duyệt, thực hiện, hoàn tất.
- Người lập một phiếu chuyển mở sổ phiếu → thấy đúng một dòng cho việc chuyển đó, ví dụ "Chuyển 20 lon, Merchant A - Kho mặc định sang Merchant B - Kho mặc định, đang chuyển".
- Mở chi tiết dòng đó → các phiếu xuất và phiếu nhập hiện thành một dòng thời gian bên trong: xuất ngày nào bao nhiêu, nhận ngày nào bao nhiêu.
- Đổi sang một merchant khác rồi mở sổ phiếu kho → không thấy phiếu của merchant trước.
6. Yêu cầu phi chức năng
| Khía cạnh | Yêu cầu |
|---|---|
| Toàn vẹn tồn kho | Hoàn tất một phiếu con là một lần ghi trọn vẹn: hoặc cả phiếu ghi tồn và ghi sổ thành công, hoặc không có gì được ghi; không có trạng thái nửa vời |
| Chống ghi trùng | Mỗi dòng hàng có một khóa nghiệp vụ duy nhất trên dòng sổ biến động, được ép ở tầng cơ sở dữ liệu; hai lần bấm hoàn tất cùng lúc chỉ ghi ra một dòng sổ |
| Chỉ ghi thêm | Không có đường nào trong nghiệp vụ sửa hoặc xóa một phiếu con đã hoàn tất; mọi hiệu chỉnh đều là một bản ghi mới |
| Chống nhảy cóc trạng thái | Việc chuyển trạng thái phải so khớp với trạng thái hiện tại của phiếu; hai người cùng bấm một lúc thì chỉ một người thành công, người kia nhận báo phiếu đã đổi trạng thái |
| Suy trạng thái phiếu cha | Trạng thái phiếu cha luôn tính lại từ tập phiếu con tại thời điểm đọc, nên không bao giờ lệch với thực tế các phiếu con |
| Phân quyền theo merchant | Mỗi phiếu con giới hạn trong chi nhánh sở hữu nó; một phiếu cha chạm hai chi nhánh thì mỗi bên chỉ đọc và ghi được phần của mình |
| Truy vết | Mỗi bước chuyển trạng thái lưu thời điểm và người thao tác, không sửa lại được |
| i18n | Nhãn loại phiếu, nhãn trạng thái theo từng loại phiếu, và danh sách lý do hiển thị song ngữ |
7. UX & Luồng
Vòng đời chung của một phiếu kho, và chỗ tồn kho thật sự thay đổi:
Một phiếu cha, nhiều phiếu con, và trạng thái cha suy ra từ con:
Sổ phiếu kho nằm trong trang Client, ở nhóm menu Kho, cạnh màn Tồn kho và màn Địa điểm kho. Người lập phiếu chỉ thấy một dòng cho một việc. Các phiếu con hiện bên trong màn chi tiết như một dòng thời gian, và người dùng không phải học thêm khái niệm nào để đọc được nó.
8. Dữ liệu & Miền nghiệp vụ
| Khái niệm | Vai trò |
|---|---|
| Phiếu kho (cha) | Tờ lệnh mang ý định của một lần hàng vào, ra hoặc sửa số; trạng thái suy ra từ các phiếu con |
| Phiếu xuất (con) | Chứng từ một lần hàng rời kho, thuộc merchant gửi; hoàn tất thì tồn kho gửi giảm |
| Phiếu nhập (con) | Chứng từ một lần hàng vào kho, thuộc merchant nhận; hoàn tất thì tồn kho nhận tăng |
| Loại phiếu | Một trong chín loại: yêu cầu mua hàng, nhập kho, chuyển kho, xuất dùng nội bộ, điều chỉnh, kiểm kê, trả nhà cung cấp, trả từ khách, hủy/tiêu hủy |
| Trạng thái phiếu | Nháp, Đã gửi, Đã duyệt, Đang thực hiện, Hoàn tất, Đã hủy, Đã đóng - hiển thị bằng chữ riêng của từng loại phiếu |
| Dòng hàng | Một mặt hàng trên phiếu, kèm đơn vị, số kế hoạch, số thực tế, lô, hạn dùng và trạng thái riêng |
| Đóng phiếu | Thao tác của người lập, chốt phần hàng đã xuất mà không tới nơi và sinh một phiếu điều chỉnh ghi thất thoát |
| Hủy phiếu | Thao tác dừng phần kế hoạch chưa thực hiện, nhả phần đang giữ, không sinh phiếu điều chỉnh |
| Lý do | Nhãn giải thích vì sao tồn đổi, đi theo phiếu xuống dòng sổ biến động |
| Đối tác | Nhà cung cấp hoặc khách hàng gắn với phiếu, tùy loại phiếu |
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 | LOC Địa điểm kho | mỗi đầu của phiếu chỉ tới một kho đang hoạt động. |
| 02 | STK Mục kho & mức tồn | nơi con số tồn thật sự được cộng trừ khi phiếu con hoàn tất. |
| 03 | RSV Giữ tồn | phần hàng đã duyệt nhưng chưa xuất được giữ tại kho gửi theo đúng cơ chế giữ tồn chung. |
| 04 | LDG Sổ biến động | nơi mỗi dòng hàng hoàn tất để lại một dòng ghi. |
| 05 | UOM Đơn vị tính & quy đổi | dòng hàng khai theo đơn vị mua hoặc bán, hệ thống quy về đơn vị gốc. |
| 06 | LSE Lô, hạn dùng | dòng hàng của mặt hàng có quản lô mang thêm lô và hạn dùng. |
| 07 | VEN Nhà cung cấp và khách hàng | đối tác trên phiếu nhập kho, phiếu trả nhà cung cấp, phiếu trả từ khách. |
Giả định
| # | Giả định | Sai thì sao |
|---|---|---|
| 01 | Merchant chấp nhận một bước duyệt trước khi tồn đổi. Ở merchant nhỏ, người lập và người duyệt có thể là cùng một người. | Merchant thấy bước duyệt là rườm rà thì họ quay về gõ đè số tồn trên màn Tồn kho, và toàn bộ giá trị truy vết của khung phiếu mất trắng. |
| 02 | Số thực tế lệch số kế hoạch là chuyện bình thường của nghề, không phải lỗi cần chặn. | Chặn phần lệch thì thủ kho ghi số kế hoạch cho có, và sổ kho phản ánh chuyện lẽ ra phải xảy ra chứ không phải chuyện đã xảy ra. |
| 03 | Phần hàng đã xuất mà không tới nơi là mất thật, và người lập là người biết rõ nhất khi nào nên chốt phần đó. | Không ai chốt thì phiếu treo mãi với hàng đang trên đường; chốt quá sớm khi hàng chỉ chậm thì ghi thất thoát oan và hàng về sau thành hàng thừa không rõ nguồn gốc. |
| 04 | Hai chi nhánh chuyển hàng cho nhau đều nằm trong cùng một tổ chức (Organizer), nên hai bên tin nhau ở mức nghiệp vụ. | Chuyển ra ngoài organizer thì cần duyệt hai phía và kiểm soát chặt hơn hẳn; mô hình phiếu cha - phiếu con trong bản này không đủ. |
10. Kế hoạch phát hành & Tiêu chí
| Khía cạnh | Kế hoạch |
|---|---|
| Phase | P2 (Kho - khung chứng từ) - xem danh mục feature URD |
| Rollout | Mọi merchant; sổ phiếu kho mở cùng lúc với màn Tồn kho hiện có |
| Migration | Không có dữ liệu phiếu cũ để chuyển; tồn hiện tại giữ nguyên làm số mở đầu, mọi thay đổi từ đây đi qua phiếu |
| Tiêu chí phát hành | Lập được đủ chín loại phiếu từ trang Client; mỗi loại đi đúng phần vòng đời của nó với đúng chữ hiển thị; tồn chỉ đổi ở bước hoàn tất; một phiếu cha chạy được nhiều phiếu xuất và nhiều phiếu nhập; đóng phiếu sinh đúng một phiếu điều chỉnh; phiếu con đã hoàn tất không sửa được |
| Theo dõi | Số phiếu lập theo loại, số phiếu bị hủy, số phiếu bị đóng và tổng số lượng thất thoát, thời gian trung bình từ lúc gửi tới lúc duyệt, số lần sửa thẳng tồn trên màn Tồn kho |
Tham chiếu
- URD: Phiếu kho
- Liên quan: Chuyển kho · Kiểm kê · Sổ biến động · Mục kho & mức tồn · Giữ tồn & chặn bán quá tay · Đơn mua hàng
- 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 | Hai người cùng bấm hoàn tất một phiếu, tồn bị cộng hai lần | Khóa nghiệp vụ duy nhất trên dòng sổ biến động, ép ở tầng cơ sở dữ liệu, cộng với việc chuyển trạng thái phải so khớp trạng thái hiện tại (FR-011, §6) |
| 02 | Người lập không bấm đóng phiếu, hàng thất lạc treo mãi ở "đang về" | Mở: cần cảnh báo cho phiếu còn hàng đang trên đường quá số ngày cấu hình được |
| 03 | Người dùng nhầm nút Hủy với nút Đóng và làm mất dấu phần thất thoát | Hai nút nói rõ hậu quả trước khi thực hiện; hủy phiếu còn hàng đang trên đường thì hệ thống bắt xác nhận phần sẽ ghi thất thoát (FR-014) |
| 04 | Ai được duyệt và ai được đóng một phiếu chạm hai merchant | Đã chốt: người thuộc merchant gửi, người thuộc merchant nhận, và cấp quản lý trở lên của merchant trụ sở chính đều làm được. Để mở có chủ đích, không siết ở bản này. |
| 05 | Merchant nhỏ thấy vòng đời năm bước là rườm rà, quay về gõ đè số tồn | Loại phiếu đơn giản đã bỏ bớt bước sẵn: phiếu điều chỉnh chỉ có Nháp và Hoàn tất (FR-003) |
| 06 | Người dùng lập nhầm loại phiếu và không sửa được loại | Loại phiếu chốt lúc tạo; sửa bằng cách hủy phiếu nháp và lập lại (FR-001, FR-014) |
Câu hỏi thường gặp
| # | Câu hỏi | Trả lời |
|---|---|---|
| 01 | Tại sao tồn không đổi ngay khi tôi duyệt phiếu? | Vì duyệt là đồng ý cho làm, không phải là đã làm xong. Hàng chưa vào kệ mà tồn đã tăng thì con số trên màn Tồn kho không còn là số thật. Chỉ khi bấm hoàn tất, nghĩa là hàng đã thật sự vào hoặc ra, tồn mới đổi. |
| 02 | Chín loại phiếu mà chỉ một vòng đời thì có rườm rà không? | Không, vì mỗi loại chỉ đi phần vòng đời nó cần. Phiếu điều chỉnh chỉ có hai bước: soạn rồi hoàn tất. Phiếu kiểm kê bỏ bước duyệt. Chỉ phiếu chuyển kho mới đi đủ năm bước, vì đó là loại việc thật sự cần một người đồng ý trước khi hàng rời kho. |
| 03 | Sao phiếu chuyển kho lại hiện chữ "Chờ chuyển" thay vì "Đã duyệt"? | Vì nói chuyện với thủ kho bằng chữ của nghề thì dễ hiểu hơn. Bên dưới nó vẫn là bước Đã duyệt của vòng đời chung: cùng một trạng thái, chỉ đổi chữ cho đúng ngữ cảnh. Hệ thống không có bộ trạng thái thứ hai. |
| 04 | Phiếu cha và phiếu con là gì, tôi có phải quan tâm không? | Không. Bạn thấy một dòng cho một việc, ví dụ "Chuyển 20 lon, Kho A sang Kho B, đang chuyển". Mở ra thì bên trong là dòng thời gian: xuất chuyến nào bao nhiêu, nhận lần nào bao nhiêu. Bạn không phải học thêm chữ nào để đọc được nó. |
| 05 | Xuất nhiều hơn số đã ghi trên phiếu thì có bị chặn không? | Không. Ghi đúng số hàng thật sự rời kho, hệ thống cho qua. Nhận nhiều hơn số đã xuất cũng vậy. Số trên phiếu là kế hoạch, còn hàng thì là hàng. Sổ sách phải phản ánh chuyện đã xảy ra, không phải chuyện lẽ ra phải xảy ra. |
| 06 | Hàng đi mà không tới thì tôi làm gì? | Bấm Đóng phiếu. Hệ thống hỏi lại phần thiếu là bao nhiêu, bắt bạn chọn một lý do, rồi tự sinh một phiếu điều chỉnh ghi đúng phần thất thoát đó. Hàng mất được ghi thành mất, có chứng từ, không treo lơ lửng. |
| 07 | Đóng phiếu và hủy phiếu khác nhau chỗ nào? | Hủy là dừng phần chưa bao giờ làm: hàng vẫn nằm trên kệ, chỉ cần nhả phần đang giữ ra, không có gì mất và không sinh phiếu điều chỉnh. Đóng là chốt phần đã làm mà không tới nơi: hàng đã rời kho và không quay lại, nên nó là thất thoát và phải có một phiếu điều chỉnh ghi lại. |
| 08 | Tôi bấm hoàn tất nhầm thì sao? | Phiếu đã hoàn tất không sửa được và không xóa được. Muốn đưa số về đúng thì lập một phiếu điều chỉnh mới, ghi rõ lý do. Sửa sai là ghi thêm một tờ, không phải xé tờ cũ. Nhờ vậy lịch sử tồn kho không bao giờ bị viết lại. |