PRD: Đơn mua hàng
| Module | Kho | PRD ID | PRD-PO-001 |
| Trạng thái | Đã thay thế | FEAT | PO |
| Epic | — | Plane | — |
| Ngày | 2026-07-13 | Phiên bản | v1.0 |
| Gói | @nx/inventory | URD | PO |
| Surface | Client · Chủ/QL | ||
| Phụ trách | Phát Nguyễn | ||
Đơn mua hàng là gì
Một chi nhánh (Merchant) đặt hàng của nhà cung cấp bằng một đơn mua hàng (Purchase Order) lập tại trang Client: một nhà cung cấp cho cả đơn, một kho (InventoryLocation) sẽ nhận hàng, và danh sách mặt hàng kèm số lượng, đơn giá, đơn vị mua. Nhiều chi nhánh cùng nằm trong một tổ chức (Organizer).
Đơn mua hàng là chứng từ đứng sau mỗi lần hàng từ bên ngoài vào kho. Nó cũng là nơi duy nhất giá vốn được sinh ra.
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ữHàng đã đặt nhà cung cấp nhưng chưa giao không nằm trong bốn con số này. Đang về chỉ đếm hàng đang chuyển giữa hai kho trong hệ thống.
Vì sao mỗi lần hàng vào kho phải có một tờ đơn
Không có đơn mua hàng thì mỗi lần nhập kho là một con số gõ tay, và không ai truy lại được vì sao tồn tăng, tăng với giá vốn nào.
Hàng về nhiều đợt là chuyện thường ngày. Đặt 100 thùng, nhà cung cấp giao 60 thùng sáng nay và hẹn phần còn lại tuần sau. Hệ thống bắt nhận đủ mới cho ghi nhận thì nhân viên sẽ ghi cho có: gõ đủ số rồi sửa sau, hoặc bỏ hẳn không dùng. Vì vậy đơn mua hàng nhận được từng phần, và nhận thiếu là chuyện bình thường chứ không phải một lỗi.
Một đơn mua hàng, từ đầu tới cuối
Đặt 70 thùng sữa với giá 50.000đ một thùng. Kho đang trống. Nhà cung cấp giao hai đợt, và đợt hai giao thừa 5 thùng với giá đã tăng.
| Việc xảy ra | Đã đặt | Đã nhận lũy kế | Thực có kho | Giá vốn |
|---|---|---|---|---|
| Gửi đơn cho nhà cung cấp | 70 | 0 | 0 | chưa có |
| Nhận đợt 1: 50 thùng, giá 50.000đ | 70 | 50 | 50 | 50.000đ |
| Nhận đợt 2: 25 thùng, giá 62.000đ | 70 | 75 | 75 | 54.000đ |
- Hàng vào kho tới đâu bán được tới đó. 50 thùng của đợt một bán được ngay, không phải chờ đơn hoàn tất.
- Đợt hai giao 25 thùng trong khi đơn chỉ còn thiếu 20. Phần thừa 5 thùng vẫn được ghi: hàng đã nằm trong kho thì sổ phải ghi đúng số đó.
- Giá vốn trộn lại theo tỉ trọng số lượng: (50 × 50.000 + 25 × 62.000) chia 75 bằng 54.000đ. Giá vốn chỉ đổi ở lúc nhận hàng.
- Mọi dòng hàng đã nhận đủ số đã đặt, nên đơn tự chuyển sang
Hoàn tất, không ai phải bấm gì.
Chỗ dễ sai nhất
Đơn đã Hoàn tất thì không hủy được
Hàng đã nhập đủ vào kho. Hủy đơn không kéo hàng ra khỏi kệ, nên hủy một đơn đã xong là một thao tác vô nghĩa.
Muốn trả hàng cho nhà cung cấp thì lập một phiếu trả nhà cung cấp. Sửa sai là thêm một chứng từ mới, không đổi trạng thái của một chứng từ đã đóng.
Hủy chỉ dùng cho đơn còn đang chạy: Nháp, Đã gửi, Đã nhận. Và hủy một đơn đã nhận một phần không đảo lại phần tồn đã ghi: hàng đã về kho vẫn nằm trong tồn, dòng sổ biến động giữ nguyên.
1. Mục tiêu & Loại trừ
Mục tiêu
- Lập đơn mua hàng theo một nhà cung cấp, khai dòng hàng với số lượng, đơn giá, đơn vị mua, và gửi đơn đi.
- Đề xuất sẵn giá và đơn vị mua cho từng dòng hàng từ dữ liệu của cặp nhà cung cấp - mặt hàng, để không phải gõ lại từ đầu mỗi lần đặt.
- Nhận hàng từng phần, nhiều đợt, cộng dồn vào số đã nhận lũy kế của từng dòng.
- Mỗi lần nhận ghi sổ biến động, cộng thực có của kho nhận theo đơn vị gốc, và tính lại giá vốn bình quân gia quyền.
- Ghi ngược giá và đơn vị vừa nhập về bản ghi nhà cung cấp - mặt hàng.
- Hiện cảnh báo lệch số lượng và lệch giá trên đơn mà không chặn nhận hàng.
- Neo công nợ phải trả nhà cung cấp theo số lượng đã nhận, không theo số lượng đã đặt.
Loại trừ
- Đối chiếu ba chiều với hóa đơn thật của nhà cung cấp và hạch toán chênh lệch qua module Tài chính. Đơn mua hàng chỉ ghi khoản lệch như một con số quan sát được.
- Phân bổ chi phí nhập hàng (vận chuyển, thuế nhập khẩu) vào giá vốn từng dòng.
- Ghi nhận lô, hạn dùng và serial ngay lúc nhận hàng, thuộc Lô, hạn dùng & chiến lược xuất.
- Đề nghị mua hàng tự động từ điểm đặt hàng lại, thuộc Bổ sung hàng.
- Trả hàng lại cho nhà cung cấp.
2. Thước đo thành công
| Thước đo | Mục tiêu / tín hiệu |
|---|---|
| Tỉ lệ hàng vào kho có chứng từ | Phần lớn lượng hàng nhập đi qua đơn mua hàng thay vì điều chỉnh tồn thủ công |
| Nhận nhiều đợt | Số đơn được nhận từ hai đợt trở lên tăng dần, dấu hiệu merchant dùng nhận từng phần thay vì gõ đủ số cho có |
| Độ chính xác giá vốn | Giá vốn bình quân sau mỗi lần nhận khớp với tính tay trên các đơn lấy mẫu |
| Đỡ gõ tay | Phần lớn dòng hàng giữ nguyên giá đề xuất từ dữ liệu nhà cung cấp, không phải sửa lại |
| Cảnh báo có ích | Cảnh báo lệch giá và lệch số lượng được mở ra xem, không bị bỏ qua hàng loạt |
3. Persona & Tình huống
| Persona | Mục tiêu trong tính năng này |
|---|---|
| Chủ quán / Quản lý | Đặt hàng đúng nhà cung cấp với giá đã thỏa thuận, theo dõi đơn nào đã về đủ, đơn nào còn thiếu |
| Nhân viên kho | Nhận hàng thực tế về kho, gõ đúng số đếm được trên xe hàng, không bị chặn khi nhà cung cấp giao thiếu |
| Kế toán / Chủ quán | Biết phải trả nhà cung cấp bao nhiêu tiền theo đúng lượng hàng đã thực nhận |
Kịch bản cốt lõi: chủ quán chọn nhà cung cấp và kho nhận, thêm các dòng hàng với giá được đề xuất sẵn, gửi đơn đi → nhà cung cấp giao đợt một → nhân viên kho mở đơn, gõ số thực nhận của từng dòng, bấm Nhận hàng → tồn kho tăng ngay, giá vốn được trộn lại, giá vừa nhập được ghi về dữ liệu nhà cung cấp → đơn còn thiếu hàng vẫn để mở, chờ đợt sau.
4. User Stories
| # | Là một | Tôi muốn | Để |
|---|---|---|---|
| 01 | chủ quán | chọn một nhà cung cấp rồi thêm dòng hàng mà giá đã điền sẵn | đặt hàng nhanh mà không phải nhớ giá lần trước |
| 02 | chủ quán | khóa dòng hàng lại sau khi đã gửi đơn cho nhà cung cấp | không ai sửa lén đơn đã chốt |
| 03 | nhân viên kho | gõ đúng số hàng thực đếm được trên xe, kể cả khi ít hơn số đã đặt | sổ sách khớp với hàng trên kệ |
| 04 | nhân viên kho | nhận thêm đợt hai vào cùng một đơn | không phải tạo đơn mới cho phần hàng về sau |
| 05 | chủ quán | thấy cảnh báo khi hàng về thiếu hoặc giá về khác giá đã đặt | tôi gọi lại cho nhà cung cấp thay vì bị hệ thống chặn |
| 06 | chủ quán | giá vốn tự trộn lại mỗi lần nhập giá mới | báo cáo lãi lỗ phản ánh đúng giá mua thật |
| 07 | chủ quán | công nợ phải trả tính theo hàng đã thực nhận | không trả tiền cho phần hàng chưa về |
5. Yêu cầu chức năng
| # | Yêu cầu | Trạng thái | URD ref |
|---|---|---|---|
FR-001 | Đơn mua hàng đi qua một vòng đời có thứ tự, mỗi bước là một trạng thái hiển thị trên đơn. • Nháp - đơn đang soạn, chưa gửi cho nhà cung cấp.• Đã gửi - đơn đã chốt và gửi đi, đang chờ hàng về.• Đã nhận - đã nhận ít nhất một đợt nhưng chưa dòng nào đủ, đơn vẫn mở để nhận tiếp.• Hoàn tất - đơn tự chuyển sang bước này ngay khi mọi dòng hàng đã nhận đủ số đã đặt; ngoài ra chủ quán bấm Hoàn tất bằng tay khi hàng về thiếu mà không chờ nữa.• Đã đóng - đơn khép lại về mặt sổ sách, không thao tác gì thêm.• Đã hủy - đơn bị bỏ, không nhận hàng được nữa. | 🔶 | URD-PO-001 |
FR-002 | Đơn hủy được ở các bước trước khi hàng về đủ, nhưng không hủy được từ Hoàn tất.• Hủy được từ Nháp, Đã gửi và Đã nhận (đã nhận một phần).• Hoàn tất, Đã đóng và Đã hủy thì không hủy được. Hàng đã nhập đủ thì đơn đã xong.• Muốn trả hàng cho nhà cung cấp thì lập một phiếu trả nhà cung cấp, không phải hủy đơn cũ. Sửa sai là thêm chứng từ, không đổi trạng thái chứng từ đã đóng. • Hủy một đơn đã nhận một phần không đảo lại phần tồn đã ghi: hàng đã về kho vẫn nằm trong tồn, sổ biến động giữ nguyên. Đơn đã hủy thì nút Nhận hàng biến mất. | 🔶 | URD-PO-001 |
FR-003 | Dòng hàng chỉ thêm, sửa, xóa được khi đơn còn ở Nháp.• Đơn sang Đã gửi trở đi thì toàn bộ dòng hàng bị khóa: không đổi mặt hàng, số lượng, đơn giá hay đơn vị.• Muốn đổi nội dung đơn đã gửi thì hủy đơn và lập đơn mới. | 🔶 | URD-PO-002 |
FR-004 | Lập đơn mua hàng khai phần đầu đơn chung cho cả đơn. • Nhà cung cấp (bắt buộc, một nhà cung cấp cho cả đơn). • Kho sẽ nhận hàng (bắt buộc, mặc định là kho mặc định của chi nhánh). • Ngày đặt hàng (bắt buộc, mặc định hôm nay) và ngày dự kiến giao (tùy chọn). • Tiền tệ (mặc định VND) và điều khoản thanh toán (tùy chọn: trả khi nhận, trả trước, trả sau N ngày, cuối tháng). • Tên đơn và ghi chú là tùy chọn. Mã đơn do hệ thống sinh, duy nhất trong chi nhánh. | 🔶 | URD-PO-003 |
FR-005 | Mỗi dòng hàng của đơn khai một mặt hàng cần mua. • Mặt hàng (bắt buộc): một biến thể sản phẩm hoặc một nguyên vật liệu. • Số lượng đặt (bắt buộc, lớn hơn 0).• Đơn vị mua (bắt buộc): thùng, lốc, kg, cái. Hệ thống tự tính ra bao nhiêu đơn vị gốc, người dùng không gõ hệ số quy đổi. • Đơn giá theo đơn vị mua (bắt buộc). Thuế và giảm giá của dòng là tùy chọn. • Thành tiền của dòng do hệ thống tính, không cho gõ tay. | 🔶 | URD-PO-003 |
FR-006 | Chọn mặt hàng vào một đơn đã có nhà cung cấp thì form tự điền dữ liệu mua hàng của cặp nhà cung cấp - mặt hàng đó. • Đơn giá và đơn vị mua lấy từ giá lần nhập gần nhất đã lưu. • Số lượng đặt tối thiểu và quy cách đóng gói hiện lên, để chủ quán biết mình đang đặt dưới mức tối thiểu hay không. • Mọi giá trị được đề xuất đều sửa lại được trước khi lưu dòng hàng. • Cặp nhà cung cấp - mặt hàng chưa có dữ liệu thì các ô để trống cho chủ quán tự điền. | 🚧 | URD-PO-004 |
FR-007 | Nhận hàng cho phép nhận từng phần, nhiều đợt cho cùng một đơn. • Mỗi lần nhận, người dùng gõ số thực nhận của từng dòng trong đợt đó. Không bắt buộc nhận hết mọi dòng. • Số vừa nhận được cộng dồn vào số đã nhận lũy kế của dòng hàng. • Nhận thừa so với số đã đặt vẫn được ghi, giống chuyển kho. Nhà cung cấp giao thừa thì hàng đã nằm trong kho; chặn ở form chỉ làm thủ kho không ghi được sự thật. • Phần vượt hiện rõ trên màn chi tiết đơn, để người lập biết mà đối chiếu. | 🔶 | URD-PO-005 |
FR-008 | Mỗi lần nhận hàng ghi thẳng vào tồn kho của kho nhận. • Thực có của mặt hàng tại kho nhận cộng đúng số vừa nhận, quy đổi về đơn vị gốc. • Hàng vào kho là bán được ngay, không chờ đơn hoàn tất. • Một dòng sổ biến động được ghi cho mỗi mặt hàng, mang lý do nhập mua hàng và trỏ về đúng đơn mua hàng nguồn. | 🔶 | URD-PO-006 · URD-LDG-001 |
FR-009 | Nhận hàng tính lại giá vốn bình quân gia quyền của mặt hàng. • Giá vốn mới bằng giá trị tồn cũ cộng giá trị lô vừa nhập, chia cho tổng số lượng sau khi nhận. • Giá vốn là một con số cho cả chi nhánh, không tách theo từng kho. • Tồn trước khi nhận đang bằng 0 hoặc âm thì giá vừa nhập thay thế hoàn toàn giá vốn cũ. | 🚧 | URD-PO-008 · URD-VAL-005 |
FR-010 | Nhận hàng ghi ngược giá vừa nhập về bản ghi nhà cung cấp - mặt hàng. • Đơn giá, đơn vị tính, thời điểm đặt và thời điểm nhận của lần nhập này được lưu thành giá lần nhập gần nhất. • Lần lập đơn sau cho cùng cặp nhà cung cấp - mặt hàng sẽ đề xuất đúng con số vừa ghi. | 🔶 | URD-PO-007 · URD-VEN-004 |
FR-011 | Màn đơn mua hàng hiện cảnh báo khi số lượng hoặc giá thực nhận lệch với đơn đã đặt, và không chặn thao tác nhận. • Lệch số lượng: số đã nhận lũy kế khác số đã đặt của dòng hàng, hiện ngay trên dòng đó kèm số còn thiếu hoặc số vượt. • Lệch giá: đơn giá trên đơn khác giá thực nhận, hiện chênh lệch trên mỗi đơn vị. • Cảnh báo là thông tin để chủ quán gọi lại cho nhà cung cấp, không phải một lỗi phải xử lý xong mới đi tiếp được. | 🚧 | URD-PO-009 |
FR-012 | Nhận thiếu so với số đã đặt không chặn gì và không ép đóng đơn. • Đơn vẫn để mở sau khi nhận thiếu. Nhà cung cấp giao tiếp thì cộng dồn vào số đã nhận lũy kế. • Hệ thống không tự sinh một chứng từ "thiếu hàng" riêng cho phần chưa nhận đủ. • Phần thiếu vĩnh viễn, khi nhà cung cấp không giao nữa, không xử lý bằng cách sửa lại đơn cũ. Merchant lập một phiếu kiểm kê để đưa tồn về đúng thực tế. | 🚧 | URD-PO-013 |
FR-013 | Công nợ phải trả nhà cung cấp của đơn tính theo số lượng đã nhận lũy kế. • Số tiền phải trả neo theo số đã nhận lũy kế của từng dòng hàng, không neo theo số đã đặt. • Phần hàng chưa về chưa phát sinh khoản phải trả. Nhận thêm đợt sau thì công nợ của đơn cộng thêm đúng phần vừa nhận. | 🚧 | URD-PO-010 |
FR-014 | Hóa đơn nhà cung cấp về sau ngày nhận hàng mà ghi giá khác chỉ được ghi thành khoản lệch trên đơn. • Khoản lệch hiện trên đơn như một cảnh báo giá. • Giá vốn của các lần xuất kho đã xảy ra trước đó giữ nguyên, không tính lại. | 🚧 | URD-PO-011 · URD-VAL-010 |
FR-015 | Merchant thao tác toàn bộ vòng đời đơn mua hàng trên giao diện Client. • Màn danh sách đơn có cột mã đơn, nhà cung cấp, kho nhận, ngày đặt, ngày dự kiến giao, tổng tiền, trạng thái. Lọc được theo trạng thái và nhà cung cấp. • Màn chi tiết đơn hiện từng dòng hàng kèm ba con số: đã đặt, đã nhận lũy kế, còn lại. • Nút Nhận hàng mở form gõ số thực nhận của đợt này, chỉ hiện khi đơn đang ở trạng thái cho phép nhận. | 🚧 | URD-PO-001 · URD-PO-005 |
FR-016 | Đơn mua hàng là dữ liệu riêng của từng chi nhánh (Merchant). • Mọi đơn và dòng hàng chỉ hiện trong chi nhánh của chính người dùng. • Xóa là xóa mềm, khôi phục được. | 🔶 | URD-PO-012 |
5.1 Tiêu chí nghiệm thu
- Tạo một đơn mua hàng mới, chọn nhà cung cấp và kho nhận, thêm hai dòng hàng, lưu lại → đơn ở trạng thái
Nháp, có mã đơn duy nhất, tổng tiền bằng tổng thành tiền hai dòng. - Ở trạng thái
Nhápsửa số lượng một dòng và xóa dòng còn lại → cả hai thao tác thành công, tổng tiền cập nhật theo. - Gửi đơn đi rồi mở lại màn chi tiết → trạng thái là
Đã gửi, các ô của dòng hàng không sửa được nữa, không còn nút thêm dòng. - Đơn đang ở
Đã gửivà chưa nhận đợt nào, bấm Hủy → đơn chuyển sangĐã hủy, nút Nhận hàng biến mất. - Đơn đã nhận một phần (60/100 đơn vị), bấm Hủy → đơn chuyển sang
Đã hủy; 60 đơn vị đã nhận vẫn nằm trong tồn kho và dòng sổ biến động của đợt nhận đó không bị đảo. - Đơn đã ở
Hoàn tất, mở màn chi tiết → không còn nút Hủy; muốn trả hàng thì lập một phiếu trả nhà cung cấp. - Đơn đã ở
Đã đóng, mở màn chi tiết → không còn nút Hủy. - Chọn một mặt hàng đã từng mua của nhà cung cấp đang chọn → ô đơn giá và ô đơn vị mua tự điền theo giá lần nhập gần nhất, số lượng đặt tối thiểu hiện bên cạnh; sửa tay đơn giá rồi lưu → dòng hàng giữ đúng giá vừa sửa.
- Chọn một mặt hàng chưa từng mua của nhà cung cấp đó → ô đơn giá và ô đơn vị mua để trống, không báo lỗi.
- Đơn đặt 100 đơn vị, nhận đợt một 60 đơn vị → dòng hàng hiện đã đặt 100, đã nhận 60, còn lại 40; đơn chuyển sang
Đã nhậnvà vẫn mở. - Nhận tiếp đợt hai 40 đơn vị cho cùng đơn đó → đã nhận lũy kế là 100, còn lại 0; mọi dòng hàng đã nhận đủ nên đơn tự chuyển sang
Hoàn tất, không cần bấm gì thêm. - Đơn đã ở
Hoàn tất, dù tự chuyển vì nhận đủ hay chủ quán bấm Hoàn tất khi nhận thiếu, mở màn chi tiết → không còn nút Nhận hàng. - Từ
Hoàn tấtbấm Đóng đơn → đơn chuyển sangĐã đóng; mọi thao tác nhận hàng, sửa đơn và hủy đơn đều tắt, đơn chỉ còn xem lại được. - Đơn đặt 70 đơn vị, đã nhận 50, ở form nhận hàng gõ số thực nhận 25 cho đợt này → hệ thống cho ghi, đã nhận lũy kế thành 75, phần vượt 5 đơn vị hiện rõ trên màn chi tiết đơn.
- Nhận 60 thùng của một mặt hàng khai 1 thùng bằng 24 lon → tồn thực có của mặt hàng tại kho nhận tăng 1.440 lon; mở sổ biến động của mặt hàng thấy một dòng mới mang lý do nhập mua hàng và trỏ về đúng mã đơn mua hàng.
- Ngay sau khi nhận, bán mặt hàng đó tại POS → bán được ngay, không phải chờ đơn mua hàng hoàn tất.
- Mặt hàng đang có 100 đơn vị với giá vốn 10.000đ, nhận thêm 100 đơn vị giá 12.000đ → giá vốn bình quân của mặt hàng thành 11.000đ.
- Mặt hàng đang có tồn 0, nhận 50 đơn vị giá 12.000đ → giá vốn bình quân thành 12.000đ, không có lỗi chia cho 0.
- Nhận hàng cho một cặp nhà cung cấp - mặt hàng với đơn giá 55.000đ → mở lại dữ liệu nhà cung cấp của mặt hàng đó thấy giá lần nhập gần nhất là 55.000đ kèm thời điểm nhận mới; lập đơn mới cho cùng cặp đó → ô đơn giá tự điền 55.000đ.
- Đơn đặt 100 đơn vị giá 50.000đ, nhận thực tế 95 đơn vị với giá 52.000đ → thao tác nhận thành công; màn đơn hiện cảnh báo thiếu 5 đơn vị và cảnh báo giá cao hơn 2.000đ mỗi đơn vị.
- Đơn đã nhận 95/100 đơn vị, mở phần công nợ phải trả của đơn → số tiền tính theo 95 đơn vị đã nhận, không theo 100 đơn vị đã đặt.
- Nhà cung cấp báo không giao nốt phần còn thiếu → đơn vẫn ở trạng thái
Đã nhận, hệ thống không tự đóng đơn và không sinh chứng từ "thiếu hàng" nào; merchant lập một phiếu kiểm kê để đưa tồn về đúng thực tế. - Hóa đơn nhà cung cấp về sau ghi giá cao hơn giá lúc nhận → màn đơn hiện cảnh báo lệch giá; mở lại các đơn hàng đã bán trước đó → giá vốn ghi trên các đơn đó không đổi.
- Mở màn danh sách đơn mua hàng, lọc theo trạng thái
Đã nhận→ chỉ các đơn đã nhận ít nhất một đợt hiện ra, mỗi dòng thấy nhà cung cấp, kho nhận và tổng tiền. - Xóa một đơn mua hàng → đơn biến mất khỏi danh sách nhưng vẫn khôi phục lại được; đăng nhập bằng một chi nhánh khác → không thấy đơn đó.
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 | Một lần nhận hàng chỉ cộng tồn đúng một lần; cùng một đợt nhận bị gửi lại nhiều lần vẫn chỉ ghi một dòng sổ và cộng một lần tồn |
| Toàn vẹn số liệu | Số đã nhận lũy kế và tồn kho được cộng bằng một phép cập nhật nguyên tử; hai người nhận hàng cùng lúc trên hai máy không làm lệch số |
| Truy vết | Mỗi lần nhận hàng để lại một dòng sổ biến động trỏ về mã đơn mua hàng và mã dòng hàng, đọc lại được sau nhiều tháng |
| Snapshot thời điểm | Dòng sổ ghi lại đơn vị tính, hệ số quy đổi và giá vốn tại đúng thời điểm nhận; đơn vị hay giá đổi về sau không làm sai lịch sử |
| Phân quyền theo merchant | Mọi đơn và dòng hàng giới hạn trong chi nhánh của chính người dùng, xóa mềm và khôi phục được |
| Độ chính xác | Tiền và số lượng tính với độ chính xác 4 chữ số thập phân |
| i18n | Nhãn trạng thái và nhãn hiển thị là song ngữ |
7. UX & Luồng
Toàn bộ màn hình đơn mua hàng nằm ở trang Client, hướng tới chủ quán và nhân viên kho. Đơn mua hàng không có màn hình ở Back Office.
8. Dữ liệu & Miền nghiệp vụ
| Khái niệm | Vai trò |
|---|---|
| Đơn mua hàng | Chứng từ đặt hàng: một nhà cung cấp, một kho nhận, ngày đặt, ngày dự kiến giao, tiền tệ, điều khoản thanh toán, trạng thái |
| Dòng hàng của đơn | Một mặt hàng cần mua: số lượng đặt, đơn giá, đơn vị mua, thuế, giảm giá, số đã nhận lũy kế |
| Nhà cung cấp | Bên bán hàng cho chi nhánh, chọn một lần cho cả đơn |
| Bản ghi nhà cung cấp - mặt hàng | Dữ liệu mua hàng của một cặp nhà cung cấp và mặt hàng: giá lần nhập gần nhất, số lượng đặt tối thiểu, thời gian giao dự kiến, quy cách đóng gói |
| Đợt nhận hàng | Một lần hàng thực về: số thực nhận của từng dòng, cộng dồn vào số đã nhận lũy kế |
| Dòng sổ biến động | Bản ghi chỉ-thêm cho mỗi lần tồn đổi, mang lý do nhập mua hàng và trỏ về đơn nguồn |
| Định giá tồn kho | Giá vốn bình quân của mặt hàng, được trộn lại mỗi lần nhận hàng |
| Cảnh báo đối chiếu | Con số quan sát được trên đơn: lệch số lượng đặt so với nhận, lệch giá đặt so với giá thực nhận |
Chỉ ở mức khái niệm - mô hình dữ liệu đầ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 | VEN Nhà cung cấp | đơn chọn một nhà cung cấp, và dòng hàng lấy giá đề xuất từ bản ghi nhà cung cấp - mặt hàng. |
| 02 | LOC Địa điểm kho | đơn khai kho sẽ nhận hàng; mỗi chi nhánh luôn có sẵn một kho mặc định. |
| 03 | UOM Đơn vị tính & quy đổi | hệ thống tự tính từ đơn vị mua ra đơn vị gốc, người dùng không gõ hệ số. |
| 04 | STK Mục kho & mức tồn | nhận hàng cộng thực có tại kho nhận. |
| 05 | LDG Sổ biến động | mỗi lần nhận ghi một dòng sổ. |
| 06 | VAL Giá vốn | nhận hàng là sự kiện duy nhất làm đổi giá vốn bình quân. |
| 07 | CNT Kiểm kê | nơi merchant xử lý phần hàng thiếu vĩnh viễn. |
Giả định
| # | Giả định | Sai thì sao |
|---|---|---|
| 01 | Một đơn mua hàng chỉ mua của một nhà cung cấp và chỉ giao về một kho. | Một đơn chạm nhiều nhà cung cấp hoặc nhiều kho nhận thì công nợ và giá vốn không còn quy về một nguồn duy nhất, và mô hình đầu đơn trong bản này không đủ chỗ khai. |
| 02 | Nhà cung cấp giao thiếu là chuyện bình thường, không phải lỗi cần chặn. | Chặn nhận thiếu thì thủ kho gõ đủ số cho có rồi sửa sau, và tồn kho lệch hàng thật ngay từ lần nhập đầu tiên. |
| 03 | Merchant chấp nhận giá vốn là một con số cho cả chi nhánh, không tách theo từng kho. | Merchant nhập hàng phân tán ở nhiều kho với giá khác nhau sẽ thấy lãi gộp sai theo từng kho; lối thoát là cấu hình tách giá vốn theo địa điểm ở Giá vốn, và đó là một quyết định một chiều. |
| 04 | Hóa đơn giấy của nhà cung cấp về sau ngày nhận hàng, và có thể ghi giá khác giá lúc nhận. | Hóa đơn về trước lúc nhận thì cảnh báo lệch giá không có gì để so, và giá vốn vẫn phải chốt theo giá lúc nhận chứ không theo giá trên hóa đơn. |
10. Kế hoạch phát hành & Tiêu chí
| Khía cạnh | Kế hoạch |
|---|---|
| Phase | P2 (Kho) - xem danh mục feature URD |
| Rollout | Mọi merchant; không feature flag |
| Migration | Không có dữ liệu cũ phải chuyển; đơn mua hàng là chứng từ mới phát sinh từ ngày mở tính năng |
| Tiêu chí phát hành | Lập đơn, gửi, nhận hai đợt, và hủy đơn đều làm được trọn vẹn trên giao diện Client; tồn kho và giá vốn sau nhận hàng khớp tính tay trên các đơn lấy mẫu; nhận thiếu và nhận thừa đều không chặn thao tác nào |
| Theo dõi | Số đơn được nhận nhiều đợt, tỉ lệ dòng hàng giữ nguyên giá đề xuất, sai lệch giữa giá vốn hệ thống và giá vốn tính tay |
Tham chiếu
- URD: Đơn mua hàng · Nhà cung cấp · Giá vốn · Sổ biến động
- Liên quan: Kiểm kê · Đơn vị tính & quy đổi · Mục kho & mức tồn
- 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 | Cùng một đợt nhận hàng bị bấm hai lần hoặc bị xử lý lại, làm cộng tồn hai lần | Ràng buộc duy nhất trên khóa nghiệp vụ của dòng sổ biến động; một đợt nhận chỉ ghi được một dòng cho mỗi mặt hàng |
| 02 | Đơn nhận thiếu để mở mãi làm danh sách đơn ngày càng dài | Đơn nhận đủ tự chuyển sang Hoàn tất nên không treo; đơn nhận thiếu thì cảnh báo lệch số lượng cho thấy đơn nào còn dở, và chủ quán bấm Hoàn tất khi không chờ nữa |
| 03 | Chủ quán không hiểu vì sao phần thiếu phải xử lý bằng kiểm kê thay vì sửa lại đơn | Màn đơn giải thích ngay tại cảnh báo lệch số lượng, kèm lối tắt sang lập phiếu kiểm kê |
| 04 | Nhận hàng cho mặt hàng đang có tồn âm làm giá vốn bình quân ra số vô nghĩa | Tồn trước khi nhận bằng 0 hoặc âm thì giá vừa nhập thay thế hoàn toàn giá cũ (FR-009) |
| 05 | Nhận thừa so với số đã đặt làm tồn kho phồng lên không lý do | Cho phép ghi đúng số thực nhận (FR-007); phần vượt hiện rõ trên màn chi tiết đơn kèm cảnh báo lệch số lượng (FR-011), và được đối chiếu bằng kiểm kê |
| 06 | Chi phí vận chuyển và thuế nhập khẩu chưa được phân bổ vào giá vốn, làm giá vốn thấp hơn thực tế với hàng nhập khẩu | Mở: quyết định có đưa phân bổ chi phí nhập hàng vào một increment sau hay không |
| 07 | Ghi nhận lô và hạn dùng ngay tại form nhận hàng là nơi tự nhiên nhất, nhưng đang thuộc phạm vi feature khác | Mở: nối form nhận hàng với việc khai lô và hạn dùng khi LSE sẵn sàng |
Câu hỏi thường gặp
| # | Câu hỏi | Trả lời |
|---|---|---|
| 01 | Nhà cung cấp giao thiếu thì tôi phải làm gì? | Không phải làm gì cả. Gõ đúng số hàng thực nhận, đơn để mở. Hôm sau họ giao nốt thì mở lại đơn đó nhận thêm, số đã nhận cộng dồn lên. |
| 02 | Nếu họ không giao nốt nữa thì phần thiếu treo mãi trên đơn? | Đơn vẫn còn mở, và cảnh báo lệch số lượng cho bạn thấy đơn nào chưa về đủ. Bấm Hoàn tất để khép đơn khi bạn không chờ nữa. Tồn kho thì đưa về đúng thực tế bằng một phiếu kiểm kê, không sửa lại đơn cũ. |
| 03 | Khi nào đơn tự chuyển sang Hoàn tất? | Ngay lúc đợt nhận cuối cùng làm mọi dòng hàng đã nhận đủ số đã đặt. Bạn không phải bấm gì. Chỉ khi hàng về thiếu mà bạn không chờ nữa thì mới cần bấm Hoàn tất bằng tay. |
| 04 | Tôi có nhận được nhiều hơn số đã đặt không? | Được. Nhà cung cấp giao thừa thì hàng đã nằm trong kho, và sổ phải ghi đúng số đó. Phần vượt hiện rõ trên màn chi tiết đơn kèm cảnh báo lệch số lượng, để bạn gọi lại cho nhà cung cấp. |
| 05 | Đơn đã nhận một phần rồi thì còn hủy được không? | Được, nếu đơn chưa Hoàn tất. Hủy không kéo hàng ra khỏi kho: phần đã nhận vẫn nằm trong tồn và sổ biến động giữ nguyên. Đơn đã Hoàn tất thì không hủy được - hàng đã nhập đủ, muốn trả hàng thì lập phiếu trả nhà cung cấp. |
| 06 | Hàng vừa nhận về đã bán được ngay chưa? | Bán được ngay. Nhận tới đâu, thực có tăng tới đó, không phải chờ đơn hoàn tất. |
| 07 | Vì sao tôi không sửa được dòng hàng sau khi đã gửi đơn? | Vì đơn đã gửi là một cam kết với nhà cung cấp. Muốn đổi thì hủy đơn và lập đơn mới. |
| 08 | Giá vốn của tôi đổi lúc nào? | Chỉ lúc nhận hàng. Mỗi lần hàng về với giá mới, hệ thống trộn giá đó vào giá vốn cũ theo tỉ trọng số lượng. Chuyển hàng giữa hai kho không làm đổi giá vốn. |
| 09 | Nhận hàng với giá khác giá đã đặt thì có bị chặn không? | Không. Hệ thống ghi nhận giá thực nhận và hiện một cảnh báo lệch giá trên đơn để bạn gọi lại cho nhà cung cấp. |
| 10 | Hóa đơn của nhà cung cấp về sau ghi giá khác thì giá vốn có tính lại không? | Không tính lại các lần xuất kho đã xảy ra. Khoản lệch chỉ được ghi trên đơn mua hàng như một con số quan sát được. |