Skip to content

PRD: Đơn hàng bán & giỏ hàng

ModuleĐơn hàng (CORE-07)PRD IDPRD-ORD-001
StatusShippedOwnerOrders squad
Date2025-12-31Versionv1.0
Packages@nx/saleURDORD

TL;DR

Cho phép merchant dựng một giao dịch bán dưới dạng giỏ nháp, thêm và sửa các dòng hàng, rồi đưa nó qua checkout thành một đơn hàng có thể thanh toán và đạt trạng thái cuối đã thanh toán/hoàn tất. Đây là bộ khung "giỏ → đơn hàng → thanh toán" đầu cuối đầu tiên của module Đơn hàng - mỗi đơn hàng giờ có một vòng đời được kiểm soát, giá được khoá tại thời điểm checkout, và nơi lưu thông tin thanh toán cùng giao hàng.

1. Context & Problem

Package đơn hàng khởi đầu chỉ là các controller khung (cart, cart-item, order, order-item, payment-info, shipping-info) chưa có vòng đời hoạt động: chưa có cách dựng một đơn hàng dưới dạng giỏ, thay đổi các dòng hàng, và đưa nó qua checkout đến thanh toán. Thiếu bộ khung đó, không có gì ở phía sau - thu thanh toán, phiếu bếp, phiên POS, tích điểm - có một đơn hàng để gắn vào.

Phần tăng trưởng này thiết lập vòng đời đơn hàng bán nền tảng: một entity duy nhất đóng cả vai trò giỏ (khi ở DRAFT) lẫn đơn đã chốt, với việc sửa dòng hàng khi còn nháp, một đường checkout để kiểm tra và khoá giá, và service đơn hàng điều khiển các chuyển trạng thái. Nó làm nền cho feature ORD trong URD Đơn hàng mà mọi thứ khác trong module dựa vào.

2. Goals & Non-Goals

Goals

  • Dựng một đơn hàng dưới dạng giỏ nháp và thêm/sửa/xoá dòng hàng khi còn ở DRAFT.
  • Một vòng đời được kiểm soát từ lúc tạo, qua checkout vào trạng thái xử lý, đến trạng thái cuối đã thanh toán/hoàn tất, kèm đường revert và huỷ.
  • Checkout kiểm tra giỏ (không rỗng, giá ≥ 0, số lượng ≥ 1) và khoá giá.
  • Lưu thông tin thanh toán và giao hàng gắn với đơn hàng (payment-info, shipping-info).
  • Cung cấp contract request/response cho đơn hàng và một endpoint checkout hoạt động được.

Non-Goals

  • Luồng hoàn tiền / trả hàng - là non-goal trong URD (dự kiến sau).
  • Thay đổi tồn kho - thuộc Kho hàng.
  • Tích hợp nhà cung cấp thanh toán - thuộc Thanh toán.
  • Combo fan-out, tách/gộp, gắn khách hàng, và đa tiền tệ - các tinh chỉnh sau (URD-ORD-005, URD-ORD-012..016).
  • Tách hoá đơn, phiếu bếp, station, phiên POS, đặt bàn, tích điểm - các feature F&B sau (CHK/KIT/STA/POS/RSV/PNT).

3. Success Metrics

MetricMục tiêu / tín hiệu
Độ phủ vòng đời100% giao dịch bán đi qua vòng đời đơn hàng (không tạo đơn ngoài luồng DRAFT → checkout)
Tính toàn vẹn checkoutKhông đơn nào vào PROCESSING với giỏ rỗng, giá âm, hoặc số lượng bằng 0
Ổn định giáGiá đã khoá tại checkout không trôi trước khi thanh toán
Thời gian chu kỳThời gian trung vị DRAFT → COMPLETED mỗi merchant giảm dần

4. Personas & Use Cases

PersonaMục tiêu trong feature này
Thu ngânDựng giỏ, sửa dòng hàng, checkout, và đưa đơn hàng tới thanh toán
Quản lý / ChủTin rằng mọi giao dịch bán đều theo một vòng đời đơn hàng được kiểm soát, có thể truy vết

Core scenarios: tạo giỏ nháp → thêm/sửa/xoá dòng hàng khi còn ở DRAFT → checkout (kiểm tra + khoá giá) vào PROCESSING → đạt PARTIAL khi thanh toán một phần hoặc COMPLETED khi thanh toán đủ → huỷ một đơn chưa ở trạng thái cuối hoặc revert từ PROCESSING về DRAFT.

5. User Stories

  • thu ngân, tôi muốn tạo một đơn hàng nháp và thêm dòng hàng vào nó, để dựng dần một giao dịch bán dưới dạng giỏ.
  • thu ngân, tôi muốn sửa hoặc xoá dòng hàng khi đơn còn ở DRAFT, để chỉnh giỏ trước khi chốt.
  • thu ngân, tôi muốn checkout một đơn hàng nháp, để giỏ được kiểm tra, giá được khoá, và đơn sẵn sàng thanh toán.
  • thu ngân, tôi muốn revert một đơn đã checkout về lại DRAFT, để sửa giỏ sau khi đã bắt đầu checkout.
  • thu ngân, tôi muốn ghi nhận thông tin thanh toán và giao hàng gắn với đơn hàng, để đơn mang đủ thông tin mà thanh toán cần.
  • thu ngân, tôi muốn huỷ một đơn chưa ở trạng thái cuối, để đơn nhầm không đi tiếp tới thanh toán.
  • quản lý, tôi muốn đơn đạt PARTIAL khi thanh toán một phần và COMPLETED khi thanh toán đủ, để vòng đời phản ánh đúng số đã thanh toán.

6. Functional Requirements

#Yêu cầuURD ref
FR-1Tạo một đơn hàng nháp (giỏ) kèm dòng hàngURD-ORD-001
FR-2Thêm, sửa, xoá dòng hàng chỉ khi ở DRAFTURD-ORD-002
FR-3Thêm cùng một sản phẩm sẽ gộp số lượng vào dòng đã cóURD-ORD-003
FR-4Đặt số lượng dòng hàng về 0 sẽ xoá dòng đóURD-ORD-004
FR-5Checkout: DRAFT → PROCESSING (kiểm tra dòng hàng, khoá giá)URD-ORD-006
FR-6Kiểm tra checkout: giỏ không rỗng, giá ≥ 0, số lượng ≥ 1URD-ORD-007
FR-7Revert: PROCESSING → DRAFTURD-ORD-008
FR-8Huỷ từ DRAFT, PROCESSING, hoặc PARTIAL (kèm lý do tuỳ chọn)URD-ORD-009
FR-9Thanh toán một phần → trạng thái PARTIALURD-ORD-010
FR-10Thanh toán đủ → trạng thái COMPLETEDURD-ORD-011
FR-11Lưu payment-info và shipping-info gắn với đơn hàngURD-ORD-001

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ệuDòng hàng chỉ sửa được khi ở DRAFT; checkout khoá giá nên tổng không trôi trước khi thanh toán
Toàn vẹn vòng đờiCác chuyển trạng thái bị ràng buộc theo đồ thị trạng thái đã định nghĩa; không nhảy thẳng từ DRAFT sang trạng thái đã thanh toán
Tenancy & authzMọi thao tác đều scope theo merchant và yêu cầu xác thực
Nhất quánViệc sửa giỏ và checkout là transactional; lỗi giữa chừng không để lại đơn dựng dở
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 (trong apps/client): trình dựng giỏ/đơn hàng, sửa dòng hàng, thao tác checkout, và nút huỷ/revert. Danh sách màn hình đầy đủ nằm trong luồng module Đơn hàng.

9. Data & Domain

EntityVai trò
SaleOrderChứng từ đơn hàng - đóng cả vai trò giỏ (DRAFT) lẫn đơn đã chốt; mang trạng thái và tổng tiền
OrderItemMột dòng hàng - tham chiếu sản phẩm, số lượng, giá đã khoá
PaymentInfoThông tin thanh toán lưu gắn với đơn hàng
ShippingInfoThông tin giao hàng lưu gắn với đơn hàng

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

10. Dependencies & Assumptions

Phụ thuộc vào

  • Sản phẩm (Sản phẩm) - dòng hàng tham chiếu biến thể sản phẩm.
  • Thanh toán (@nx/payment) - sự kiện thanh toán điều khiển các chuyển trạng thái PARTIAL / COMPLETED / CANCELLED.

Giả định

  • Mỗi request đều có ngữ cảnh merchant (scope theo merchant, đã xác thực).
  • Có sản phẩm tồn tại để thêm thành dòng hàng trước khi checkout.

11. Risks & Open Questions

Rủi ro / câu hỏiGiảm thiểu / trạng thái
Sửa giỏ sau checkout có thể làm sai tổng đã khoáDòng hàng chỉ sửa được khi ở DRAFT; revert về DRAFT là đường được hỗ trợ để sửa
Giá trị trạng thái vòng đời thay đổi khi package trưởng thànhCác trạng thái URD (DRAFT → PROCESSING → PARTIAL → COMPLETED / CANCELLED) là nguồn chân lý; các feature sau căn theo chúng
Phần tăng trưởng này chưa có đường hoàn/trả hàngNgoài phạm vi; thuộc một feature hoàn tiền dự kiến sau
Chưa hỗ trợ combo / tách / đa tiền tệHoãn sang các phần tăng trưởng sau (URD-ORD-005, URD-ORD-012..016)

12. Release Plan & Launch Criteria

Khía cạnhKế hoạch
PhaseP1 (nền tảng) - xem feature catalog của URD
RolloutMọi merchant; không feature flag
MigrationEntity mới; migration schema cho các bảng đơn hàng
Launch criteriaTạo giỏ → sửa dòng hàng → checkout → thanh toán được kiểm chứng đầu cuối; kiểm tra checkout từ chối giỏ rỗng / giá sai / số lượng sai; giá được khoá tại checkout
MonitoringSố lượng đơn mỗi merchant, tỷ lệ từ chối checkout, lỗi chuyển trạng thái vòng đời

13. FAQ

Có thể sửa dòng hàng sau khi checkout không? Không - dòng hàng chỉ sửa được khi ở DRAFT. Dùng revert PROCESSING → DRAFT để sửa, hoặc huỷ.

Checkout thực sự làm gì? Nó kiểm tra giỏ (không rỗng, giá ≥ 0, số lượng ≥ 1), khoá giá, và chuyển đơn DRAFT → PROCESSING để sẵn sàng thanh toán.

Khác biệt giữa PARTIAL và COMPLETED là gì? PARTIAL nghĩa là đơn còn thiếu tiền; COMPLETED nghĩa là đơn đã thanh toán đủ.

Phần tăng trưởng này có xử lý combo, tách hoá đơn, hay đa tiền tệ không? Không - đó là các feature/tinh chỉnh sau. Phần này làm nền cho vòng đời đơn hàng đơn lẻ cốt lõi.

Tồn kho được giữ chỗ hay tiêu thụ ở đâu? Không ở đây - thay đổi tồn kho thuộc Kho hàng. Feature này chỉ điều khiển vòng đời đơn hàng.

References

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