Skip to content

PRD: Tách và gộp check

ModuleBán hàngPRD IDPRD-CHK-001
Trạng tháiSẵn sàng devFEATCHK · BANA-1433
EpicPlaneBANA-1563
Ngày2026-04-02Phiên bảnv1.0
Gói@nx/saleURDCHK
SurfaceSale · POS
Phụ tráchPhát Nguyễn

TL;DR

Cho phép quán phục vụ tại bàn tách đơn của một bàn thành nhiều check thanh toán độc lập - mỗi check có item, số lượng riêng, thậm chí khách hàng riêng - và gộp các đơn riêng lẻ lại. Đơn tự hoàn tất khi tất cả check đã thanh toán. Nhóm khách tự trả phần của mình mà không cần nhân viên can thiệp thủ công.

Trạng thái triển khai: aggregate check, phân bổ theo từng check, tách, gộp, hoàn tác và hoàn tất theo thanh toán đều đã dựng. Hai điểm thiết kế khác với spec này trong code hiện tại: (1) các broadcast sự kiện check / gộp-đơn real-time chưa được nối (các phát sự kiện này đang bị tắt; chỉ có một cập nhật cấp đơn phát ra khi các check hoàn tất đơn); và (2) guard tách check hiện chỉ nhận đơn DRAFT, không phải đơn đã checkout (PROCESSING) như spec này giả định.

1. Context & Problem

Quán phục vụ tại bàn thường xuyên gặp bàn khách muốn trả riêng - mỗi người một phần, đôi khi theo hồ sơ khách hàng khác nhau - và cũng cần gộp các đơn được mở riêng lẻ cho cùng một nhóm. Coi đơn hàng như một đơn vị thanh toán duy nhất chặn cả hai nhu cầu: không có cách phân bổ item cụ thể giữa các nhóm thanh toán, không có cách hoàn tất đơn theo từng check, và không có cách gọn gàng để gộp đơn này vào đơn khác.

Increment này xây dựng năng lực check trên nền vòng đời đơn hàng hiện có - phân bổ item vào từng check, đối soát việc hoàn tất, cùng luồng gộp đơn để kết hợp hai đơn hàng nháp - lấp một khoảng trống lớn cho F&B và mọi tình huống hoá đơn nhiều khách mà BANA hướng tới.

2. Goals & Non-Goals

Goals

  • Tách một đơn đã checkout thành nhiều check thanh toán độc lập.
  • Phân bổ item theo từng check - gán item và số lượng cụ thể cho mỗi check, có chặn phân bổ vượt mức.
  • Một khách hàng khác cho mỗi check, để mỗi nhóm thanh toán mang liên kết khách hàng riêng.
  • Đơn hàng tự động hoàn tất khi tất cả check của nó hoàn tất, được điều khiển bởi luồng thanh toán thành công.
  • Hoàn tác việc tách khi chưa có check nào được thanh toán.
  • Gộp đơn hàng cho hai đơn PROCESSING trong cùng merchant.
  • Sự kiện check real-time (tạo / cập nhật / gộp / hoàn tác / đã trả) và một sự kiện gộp-đơn để giữ màn hình POS và bếp đồng bộ.

Non-Goals

  • Luồng hoàn tiền / trả hàng - Non-Goal của URD (Planned).
  • Tích hợp nhà cung cấp thanh toán - chỉ nối phần bàn giao qua luồng thanh toán thành công (xem Thanh toán).
  • Engine thuế / phát hành hoá đơn điện tử theo từng check.
  • Thay đổi tồn kho khi phân bổ check (xem Kho hàng).

3. Success Metrics

MetricMục tiêu / tín hiệu
Mức dùng táchTỷ lệ đơn phục vụ tại bàn dùng check khi có yêu cầu tách hoá đơn
Toàn vẹn phân bổKhông check nào được phân bổ vượt quá số lượng item còn lại của đơn
Độ chính xác hoàn tấtĐơn chỉ hoàn tất khi tất cả check của nó hoàn tất - không đóng sớm/muộn
An toàn hoàn tácHoàn tác thành công khi chưa check nào được thanh toán; không bao giờ sau khi một check đã trả
Độ trễ đồng bộPOS / bếp phản ánh sự kiện check & gộp theo real-time (mục tiêu; broadcast check/gộp riêng chưa được nối)

4. Personas & Use Cases

PersonaMục tiêu trong tính năng này
Thu ngânTách hoá đơn của một bàn thành các check, phân bổ item, thu tiền theo từng check, gộp đơn
Phục vụ / Lễ tânKết hợp các đơn mở riêng cho cùng một nhóm khách
Quản lý / ChủTin rằng một đơn đóng đúng lúc mọi check đã thanh toán xong

Kịch bản chính: đơn đã checkout được tách thành các check → phân bổ item, số lượng (và khách hàng riêng nếu cần) cho từng check → khách tự thanh toán check của mình → đơn hoàn tất khi tất cả check xong. Chưa check nào được trả thì có thể hoàn tác; hai đơn nháp cùng nhóm khách có thể gộp lại.

5. User Stories

  • Là một thu ngân, tôi muốn tách một đơn đã checkout thành nhiều check, để mỗi khách tự trả phần của mình.
  • Là một thu ngân, tôi muốn phân bổ item và số lượng cụ thể cho một check, để việc tách hoá đơn phản ánh đúng những gì mỗi khách đã dùng.
  • Là một thu ngân, tôi muốn gắn một khách hàng khác cho một check, để mỗi nhóm thanh toán giữ liên kết khách hàng riêng.
  • Là một thu ngân, tôi muốn đơn hàng tự động hoàn tất khi tất cả check đã trả, để không phải đóng đơn thủ công.
  • Là một thu ngân, tôi muốn hoàn tác việc tách khi chưa check nào được trả, để sửa một lần tách nhầm.
  • Là một phục vụ, tôi muốn gộp hai đơn cho cùng một nhóm khách, để một hoá đơn duy nhất đại diện cho cả bàn.

6. Functional Requirements

#Yêu cầuURD ref
FR-1Tách một đơn đã checkout thành nhiều check thanh toán độc lậpURD-CHK-001
FR-2Phân bổ item và số lượng cụ thể cho mỗi check, có chặn phân bổ vượt mứcURD-CHK-002
FR-3Cho phép một khách hàng khác cho mỗi checkURD-CHK-003
FR-4Đơn tự động hoàn tất khi tất cả check của nó hoàn tất, điều khiển bởi luồng thanh toán thành côngURD-CHK-004
FR-5Hoàn tác việc tách khi chưa có check nào được thanh toánURD-CHK-005
FR-6Tách một đơn thành nhiều đơn, chỉ ở DRAFTURD-ORD-012
FR-7Gộp nhiều đơn, chỉ ở DRAFT / cùng merchantURD-ORD-013
FR-8Phát sự kiện check real-time (tạo / cập nhật / gộp / hoàn tác / đã trả) và một sự kiện gộp-đơn - chưa triển khai: các phát sự kiện check/gộp đang bị tắt; hiện chỉ có một cập nhật cấp đơn phát ra khi các check hoàn tất đơnURD-CHK-001..005

Toàn văn yêu cầu và tiêu chí chấp nhận nằm trong URD Đơn hàng. PRD này tham chiếu chúng thay vì lặp lại.

7. Non-Functional Requirements

Khía cạnhYêu cầu
Toàn vẹn dữ liệuPhân bổ theo từng check không bao giờ vượt số lượng còn lại của đơn; trạng thái hoàn tất là dẫn xuất, không gán tay
Nhất quánTách, phân bổ, hoàn tác và gộp là một thao tác duy nhất (transactional) - lỗi một phần không để lại check viết dở
Tenancy & authzMọi thao tác giới hạn trong merchant của chính người dùng; gộp giới hạn trong cùng merchant; có kiểm soát theo permission
Real-timeThay đổi trạng thái check và gộp dự kiến broadcast qua cập nhật real-time để đồng bộ POS/KDS - các broadcast check/gộp riêng chưa được nối (chỉ một cập nhật cấp đơn phát ra khi đơn hoàn tất theo check)
Khả năng khôi phụcCác bản ghi có thể khôi phục, không bị xoá cứng
i18nNhãn/trạng thái hiển thị cho người dùng là song ngữ ({ en, vi })

8. UX & Flows

Màn hình chính: chi tiết đơn với thao tác tách hoá đơn, trình phân bổ theo từng check, thanh toán theo check, và gộp đơn.

9. Data & Domain

EntityVai trò
CheckMột nhóm thanh toán độc lập trong một đơn - trạng thái, khách hàng tuỳ chọn, tổng tiền
Phân bổ item theo từng checkMột phân bổ theo check của một order item - tham chiếu item + số lượng
OrderĐơn cha; hoàn tất khi tất cả check của nó hoàn tất
Sự kiện real-timeSự kiện check real-time dự kiến (tạo / cập nhật / gộp / hoàn tác / đã trả) và một sự kiện gộp-đơn - chưa được phát trong code hiện tại

Chỉ ở mức khái niệm - schema đầy đủ và bất biến trong domain model của sale.

10. Dependencies & Assumptions

Phụ thuộc vào

  • Vòng đời Sale Order (URD-ORD) - một check được tách từ một đơn đã checkout; gộp thao tác trên đơn nháp/processing.
  • Thanh toán - luồng thanh toán thành công điều khiển việc hoàn tất check và, qua đó, hoàn tất đơn.
  • Khách hàng - liên kết khách hàng tuỳ chọn theo từng check.

Giả định

  • Đơn đã được checkout (PROCESSING) trước khi tách thành các check.
  • Xác nhận thanh toán đến qua luồng thanh toán thành công để đánh dấu một check đã trả.

11. Risks & Open Questions

Rủi ro / câu hỏiGiảm thiểu / trạng thái
Phân bổ có thể vượt số lượng còn lạiChặn phân bổ vượt mức ngay tại thời điểm phân bổ
Hoàn tác sau khi một check đã trảChỉ cho hoàn tác khi chưa check nào được trả
Tranh chấp khi nhiều check trả gần như đồng thờiHoàn tất dẫn xuất từ tất-cả-check-hoàn-tất; điều khiển bởi luồng thanh toán thành công, idempotent
Tồn kho không thay đổi theo phân bổ checkNgoài phạm vi - thuộc Kho hàng
Thuế / hoá đơn điện tử theo từng checkNgoài phạm vi - thuộc Thuế & Hóa đơn

12. Release Plan & Launch Criteria

Khía cạnhKế hoạch
PhaseP2 - xem danh mục tính năng Đơn hàng (MoSCoW: Should)
RolloutMọi merchant; không có feature flag
MigrationAggregate check mới; không backfill dữ liệu
Tiêu chí ra mắtTách → phân bổ → trả-theo-từng-check → đơn tự hoàn tất được kiểm chứng đầu-cuối; hoàn tác được kiểm chứng khi chưa trả; gộp đơn được kiểm chứng cho cùng merchant/branch
Giám sátLượng tách theo merchant, tỷ lệ từ chối phân bổ vượt mức, nhất quán hoàn tất check-vs-đơn, việc giao sự kiện

13. FAQ

Khi nào một đơn có thể tách thành các check? Theo thiết kế, một check được tách từ một đơn đã checkout (PROCESSING), nhưng trong code hiện tại guard tách chỉ nhận đơn DRAFT (cần chỉnh status check cho khớp ý định). Bản thân việc tách/gộp đơn chỉ ở DRAFT.

Mỗi check có thể có khách hàng riêng không? Có - có thể gắn một khách hàng khác cho mỗi check.

Khi nào đơn hoàn tất? Tự động, khi tất cả check của nó hoàn tất - điều khiển bởi luồng thanh toán thành công, không phải đóng thủ công.

Tôi có thể hoàn tác một lần tách không? Có, bằng cách hoàn tác - nhưng chỉ khi chưa check nào được thanh toán.

Tách hoá đơn có thay đổi tồn kho hay phát hành hoá đơn theo từng check không? Không - thay đổi tồn kho thuộc Kho hàng và phát hành thuế / hoá đơn điện tử nằm ngoài phạm vi ở đây.

References

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.