Skip to content

PRD: Tách, gộp & hoàn tác đơn hàng

ModuleBán hàngPRD IDPRD-ORD-002
Trạng tháiSẵn sàng devFEATORD
EpicPlaneBANA-1518
Ngày2026-06-15Phiên bảnv1.0
Gói@nx/saleURDORD
SurfaceSale · POS
Phụ tráchPhát Nguyễn

TL;DR

Thu ngân có thể tách một draft thành nhiều draft mới (phân bổ mục và số lượng cho từng đơn, kể cả tách dòng theo phần), gộp nhiều draft thành một (huỷ các đơn nguồn), hoặc hoàn tác một lần gộp để mọi mục trở về đúng đơn cũ - tất cả trong một giao dịch nguyên tử. Combo luôn di chuyển nguyên khối, giữ chỗ bàn/ghế đi theo mục, và lineage transfer-history append-only cho phép đảo ngược mọi lần gộp.

Ghi chú phạm vi: Các thao tác mang theo giữ chỗ bàn/ghế (allocation usage) của đơn - clone khi tách, move khi gộp, cancel khi hoàn tác. Giữ chỗ tồn kho (stock reservation) không được xử lý riêng; được bảo toàn ngầm vì mục chỉ di chuyển trong cùng merchant và location. Re-pricing khác theo thao tác: tách chạy lại pricing engine cho các đơn mới và đơn giữ lại; gộp và hoàn tác tính lại tổng từ giá dòng đã khoá.

1. Bối cảnh & Vấn đề

Một đơn nháp (ORD) đã đóng cả vai trò giỏ lẫn đơn đã chốt, nhưng một quầy phục vụ thực tế liên tục tái định hình các đơn nháp: hai người bạn ngồi chung giờ muốn hai hoá đơn riêng; ba tab mở nhầm nên gộp lại một; một lần gộp vội phải được huỷ. Riêng vòng đời đơn không cho cách nào để di chuyển mục giữa các đơn nháp - thu ngân sẽ phải huỷ rồi nhập lại, mất giá, liên kết khách hàng, và giữ chỗ bàn/ghế.

Không có cơ chế tái cấu trúc chính thức, quầy phải từ chối các yêu cầu thường ngày này hoặc dựng lại đơn thủ công - làm rớt giữ chỗ bàn/ghế, định giá sai combo, và không để lại dấu vết nào về những gì đã di chuyển. PRD này lấp khoảng trống đó: các thao tác tách / gộp / hoàn tác khai báo di chuyển mục (và giữ chỗ bàn/ghế của chúng) nguyên tử, giữ combo nguyên vẹn, và ghi lineage có thể đảo ngược để mọi lần gộp đều có thể đi ngược lại.

2. Mục tiêu & Ngoài phạm vi

Mục tiêu

  • Tách một đơn nháp thành N đơn nháp mới bằng cách phân bổ mục và số lượng, với di chuyển nguyên số lượng và tách dòng theo một phần số lượng.
  • Gộp một hoặc nhiều đơn nháp vào một đơn đích và huỷ các đơn nguồn đã rỗng.
  • Hoàn tác một lần gộp để mọi mục trở về đơn nguồn ban đầu, khôi phục về nháp.
  • Giữ combo nguyên tử - một dòng đầu và mọi dòng con luôn di chuyển cùng nhau với đầy đủ số lượng.
  • Đóng dấu một lineage transfer-history append-only trên mọi mục đã di chuyển để đường đi có thể truy vết và đảo ngược.
  • Mang giữ chỗ bàn/ghế (allocation usage) đi cùng các mục và re-price mọi đơn bị ảnh hưởng, tất cả trong một giao dịch (giữ chỗ tồn kho không được move riêng - xem ghi chú thuật ngữ ở trên).

Ngoài phạm vi

  • Tách hoá đơn thành các check trả độc lập - đó là CHK (PRD-CHK-001); PRD này tái định hình đơn hàng, không phải check thanh toán.
  • Tách hoặc gộp đơn không phải nháp - tái cấu trúc chỉ áp dụng cho DRAFT (C-02).
  • Tái cấu trúc một đơn đang có check hoạt động - bị chặn cho tới khi các check được hoàn tác.
  • Logic thanh toán, hoàn tiền, hay thay đổi tồn kho - thuộc PaymentInventory.

3. Chỉ số thành công

Chỉ sốMục tiêu / tín hiệu
Tái định hình không nhập lạiThu ngân tách, gộp, hoặc hoàn tác từ một thao tác - không huỷ-rồi-nhập-lại
Tính nguyên tửMột bước con lỗi để mọi đơn tham gia y nguyên như trước
Toàn vẹn comboKhông lần tách nào bỏ rơi dòng đầu hay dòng con combo; thành viên combo không bao giờ di chuyển một phần
Khả năng đảo ngượcMọi lần gộp đều hoàn tác được về các đơn gốc chỉ bằng lineage đã ghi
Liên tục giữ chỗGiữ chỗ bàn/ghế (allocation usage) đi theo các mục - không giữ trùng, không mất giữ (giữ chỗ tồn kho được bảo toàn ngầm, không move riêng)

4. Nhân vật & Tình huống

Nhân vậtMục tiêu trong tính năng này
Thu ngânTách một tab chung thành các hoá đơn riêng, hoặc gộp các tab nhầm, trong một bước
Quản lýHuỷ một lần gộp sai gọn gàng, với các đơn gốc được khôi phục nguyên vẹn
ChủTin rằng mọi lần tái định hình giữ đúng giá, combo, và giữ chỗ bàn/ghế

Tình huống chính: một bàn bốn người mở một đơn nháp nhưng muốn hai hoá đơn. Thu ngân tách đơn - gán hai món chính và một món khai vị dùng chung (đầy đủ số lượng) cho hoá đơn A và phần còn lại cho hoá đơn B - và hệ thống tạo hai đơn nháp mới, di chuyển các dòng (tách những dòng dùng chung theo số lượng), mang giữ chỗ bàn/ghế, re-price cả hai, và huỷ đơn gốc nay đã rỗng. Sau đó họ nhận ra nên là một hoá đơn, gộp B trở lại A, và - phát hiện lỗi thứ ba - hoàn tác lần gộp để B được khôi phục đúng như cũ.

5. User Stories

  • thu ngân, tôi tách một đơn nháp thành các đơn nháp mới bằng cách chọn mục và số lượng cho từng hoá đơn, để một tab chung thành các hoá đơn riêng trong một bước.
  • thu ngân, tôi lấy hết số lượng một dòng hoặc chỉ một phần, để có thể di chuyển cả món hoặc chỉ hai trong năm.
  • thu ngân, tôi gộp nhiều đơn nháp thành một, để các tab tách nhầm thành một hoá đơn và các tab kia đóng lại.
  • quản lý, tôi hoàn tác một lần gộp, để một lần nhập nhầm được huỷ và mọi mục trở về đơn gốc.
  • chủ, tôi muốn combo di chuyển như một khối và giữ chỗ bàn/ghế đi theo các mục, để tái định hình không bao giờ làm hỏng một bundle hay phần giữ chỗ của nó.

6. Yêu cầu chức năng

#Yêu cầuURD ref
FR-1Tách một đơn DRAFT thành N đơn DRAFT mới, mỗi đơn được phân bổ mục và số lượng cụ thể, kèm tên và khách hàng tuỳ chọn cho từng đơn mớiURD-ORD-012 · URD-ORD-017
FR-2Một dòng được gán hết số lượng sẽ di chuyển nguyên dòng; gán một phần sẽ tách dòng, để lại phần số lượng còn lại trên đơn nguồnURD-ORD-017
FR-3Dòng đầu của một combo và mọi dòng con phải di chuyển cùng nhau, đầy đủ số lượng, vào cùng một đơn đích; di chuyển combo một phần hoặc bỏ rơi sẽ bị từ chốiURD-ORD-018
FR-4Một đơn nguồn rỗng hoàn toàn sẽ bị huỷ (đánh dấu là tách toàn bộ); một đơn nguồn tách một phần được giữ lại và re-priceURD-ORD-017
FR-5Tách từ chối số lượng không dương, một mục không tồn tại, hoặc over-allocation (gán vượt số lượng khả dụng của dòng)URD-ORD-017
FR-6Gộp di chuyển mọi mục của một hoặc nhiều đơn DRAFT nguồn vào một đơn DRAFT đích và huỷ các đơn nguồn (đánh dấu đã gộp vào đơn đích)URD-ORD-013 · URD-ORD-019
FR-7Chỉ các đơn cùng merchant và cùng sale channel mới được gộpURD-ORD-019
FR-8Mọi mục đã di chuyển ghi thêm một transfer-history entry (nguồn, đích, thời điểm, số lượng) tạo nên lineage tách / gộpURD-ORD-020
FR-9Một lần gộp có thể hoàn tác khi đơn đích vẫn DRAFT và đã được gộp; các mục trở về đơn nguồn ban đầu qua lineage, và mỗi đơn nguồn được khôi phục về DRAFTURD-ORD-021
FR-10Khi hoàn tác, số lượng thêm vào một dòng sau khi gộp sẽ ở lại đơn đích; chỉ số lượng đã di chuyển ban đầu trở về đơn nguồnURD-ORD-021
FR-11Tách, gộp và hoàn tác là nguyên tử; giữ chỗ bàn/ghế (allocation usage) được clone (tách) / move (gộp) / cancel (hoàn tác) đồng bộ và các đơn bị ảnh hưởng được re-price (tách qua pricing engine; gộp/hoàn tác tính lại tổng từ giá dòng đã khoá)URD-ORD-022
FR-12Một đơn có check hoạt động không thể tách, gộp, hay hoàn tácURD-ORD-023

Toàn văn yêu cầu và tiêu chí nghiệm thu nằm trong URD Bán hàng - ORD. PRD này tham chiếu thay vì lặp lại.

7. Yêu cầu phi chức năng

Lĩnh vựcYêu cầu
Tính nguyên tửMỗi thao tác là một giao dịch tất-cả-hoặc-không - một bước con lỗi (di chuyển mục, huỷ nguồn, re-price) cuộn cả lần tái định hình về
Đồng thờiCác đơn tham gia và mục của chúng bị khoá suốt thời gian thao tác để hai thu ngân không tái định hình cùng một đơn nháp một lúc
Khả năng truy vếtLineage transfer-history là append-only - một lần di chuyển thêm một entry, một lần hoàn tác chỉ gỡ entry cuối; chỉnh sửa là trạng thái mới, không bao giờ sửa lịch sử
Liên tục giữ chỗGiữ chỗ bàn/ghế (allocation usage) đi theo các mục - clone khi tách, move khi gộp, cancel khi hoàn tác - nên không bao giờ mất hay nhân đôi; giữ chỗ tồn kho không được thao tác riêng (bảo toàn vì các mục ở trong cùng merchant/location)
Định giáMọi đơn có mục thay đổi đều được tính lại tổng; tách chạy lại pricing engine cho cả các đơn mới lẫn đơn nguồn tách một phần được giữ lại, còn gộp và hoàn tác tính lại tổng đơn từ giá dòng đã khoá sẵn
Tenancy & authzMọi thao tác giới hạn trong merchant của chính người dùng và gác bởi quyền tách / gộp / hoàn tác
i18nNhãn người dùng và lý do từ chối là song ngữ (EN + VI)

8. UX & Luồng

Tách một đơn nháp

Gộp rồi hoàn tác

Mặt thu ngân cung cấp một panel tách (gán mục và số lượng cho một hoặc nhiều hoá đơn mới, đặt tên từng cái, tuỳ chọn gắn khách hàng), một thao tác gộp (chọn nguồn và đích), và một thao tác hoàn tác trên một đơn nháp đã gộp.

9. Dữ liệu & Miền

Thực thểVai trò trong tái định hình
Đơn hàngĐơn nháp đang được tái định hình; mang các dấu mốc do mỗi thao tác đóng (timestamp tách / gộp, lý do huỷ, liên kết gốc)
Dòng đơn hàngDòng di chuyển giữa các đơn; di chuyển nguyên sẽ dời nó, di chuyển một phần sẽ tách nó thành một dòng mới
Mục transfer-historyMột bước append-only của lineage một dòng - đơn nguồn, đơn đích, thời điểm, và số lượng đã di chuyển; entry cuối báo cho hoàn tác biết đưa dòng về đâu

Chỉ mang tính khái niệm - schema và bất biến đầy đủ nằm trong domain model bán hàng. Quan hệ đơn-tới-đơn được hệ thống theo dõi, không ràng buộc cứng; toàn vẹn được thực thi bởi logic tách / gộp.

10. Phụ thuộc & Giả định

Phụ thuộc vào

  • Vòng đời đơn bán hàng (ORD) - tái cấu trúc chỉ chạy trên đơn DRAFT và tái dùng các chuyển checkout / huỷ.
  • Tách combo (URD-ORD-005) - cấu trúc dòng đầu / con mà guard nguyên tử bảo vệ.
  • Tách hoá đơn (CHK) - một đơn có check hoạt động bị chặn tái định hình cho tới khi các check được hoàn tác.
  • Giữ chỗ bàn/ghế (allocation usage) - clone / move / cancel đồng bộ với các mục (giữ chỗ tồn kho không được xử lý riêng ở đây).
  • Nền tảng core - định nghĩa đơn và dòng hàng bán, các helper trạng thái, và cấu trúc transfer-history.

Giả định

  • Thu ngân chỉ tái định hình các đơn nháp của merchant và channel của chính mình.
  • Giữ chỗ bàn/ghế (allocation usage) của đơn nguồn là phần giữ chỗ đi theo các mục.

11. Rủi ro & Câu hỏi mở

Rủi ro / câu hỏiGiảm thiểu / trạng thái
Một lỗi một phần để các đơn tái định hình dở dangMỗi thao tác là một giao dịch tất-cả-hoặc-không với khoá - mọi lỗi cuộn cả lần tái định hình về
Một lần tách bỏ rơi dòng đầu hay con comboGuard nguyên tử trước - thành viên combo phải di chuyển cùng nhau với đầy đủ số lượng, nếu không sẽ bị từ chối
Hoàn tác không biết một mục xuất phát từ đâuLineage transfer-history append-only ghi mỗi lần di chuyển; hoàn tác đọc entry cuối theo từng dòng
Số lượng đổi sau một lần gộp, rồi hoàn tácPhần dư thêm sau khi gộp ở lại đích; chỉ số lượng đã di chuyển ban đầu trở về
Hai thu ngân tái định hình cùng một đơn nháp một lúcCác đơn tham gia và mục bị khoá suốt thời gian thao tác
Giữ chỗ bàn/ghế mất hay tính trùngGiữ chỗ bàn/ghế (allocation usage) clone khi tách, move khi gộp, cancel khi hoàn tác - đồng bộ với các mục; giữ chỗ tồn kho được bảo toàn ngầm (các mục ở trong cùng merchant/location)

12. Kế hoạch phát hành & Tiêu chí ra mắt

Khía cạnhKế hoạch
PhaseP2 - năng lực reshape ORD trong danh mục tính năng URD
Triển khaiMọi merchant; không feature flag
MigrationKhông - reshape chạy trên model đơn và mục nháp sẵn có; transfer-history là một field bổ sung
Tiêu chí ra mắtTách phân bổ mục / số lượng vào các đơn nháp mới (di chuyển nguyên và một phần) và huỷ hoặc re-price đơn nguồn; gộp nhập các nguồn vào một đích và huỷ chúng; hoàn tác khôi phục các nguồn từ lineage; combo di chuyển nguyên tử; đơn có check hoạt động bị chặn; mọi thao tác nguyên tử với giữ chỗ bàn/ghế đi theo các mục
Giám sátTỉ lệ lỗi reshape theo lý do (over-allocation, combo bị bỏ rơi, check hoạt động, chưa gộp), tỉ lệ thành công hoàn tác, nhất quán giữ chỗ bàn/ghế sau reshape

13. FAQ

Cái này khác tách hoá đơn thế nào? Tách hoá đơn (CHK) chia một đơn thành các check trả độc lập cho cùng một hoá đơn. Cái này tái định hình chính các đơn - di chuyển mục giữa các đơn nháp riêng. Xem PRD-CHK-001.

Tôi tách hay gộp được một đơn đã qua nháp không? Không - reshape chỉ áp dụng DRAFT (C-02). Một khi đơn checkout, các mục của nó bị khoá.

Combo ra sao khi tôi tách? Nó di chuyển như một khối. Dòng đầu và mọi dòng con phải đi tới cùng một hoá đơn mới với đầy đủ số lượng; gán chỉ một phần combo sẽ bị từ chối trước khi lưu bất cứ gì.

Nếu tôi chỉ lấy một phần số lượng một dòng, phần còn lại ra sao? Dòng sẽ tách - số lượng đã lấy thành một dòng trên đơn mới, phần còn lại ở lại nguồn, và cả hai được re-price.

Mọi lần gộp đều huỷ được không? Có, khi đơn đích vẫn nháp và không có check hoạt động. Hoàn tác dùng lineage transfer-history của từng dòng để đưa nó về đúng đơn nó xuất phát; số lượng thêm sau khi gộp ở lại đích.

Giữ chỗ bàn/ghế sống sót qua một lần reshape không? Có - giữ chỗ bàn/ghế (allocation usage) được clone khi tách, move khi gộp, và cancel khi hoàn tác, đồng bộ với các mục, nên không bao giờ mất hay nhân đôi. Giữ chỗ tồn kho không được move riêng; chúng được bảo toàn vì các mục chỉ di chuyển giữa các đơn của cùng merchant và location.

Tài liệu liên quan

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