PRD: Báo cáo ca (X/Z)
| Module | Báo cáo (CORE-11) | PRD ID | PRD-SHF-001 |
| Status | In-progress | Owner | Reports squad |
| Date | 2026-04-22 | Version | v0.1 |
| Packages | @nx/sale · @nx/core · @nx/finance | URD | SHF |
TL;DR
Cho phép thu ngân xem tổng doanh số của ca và đối soát ngăn kéo tiền mặt ngay tại quầy: một báo cáo X cho snapshot giữa ca trực tiếp, lặp lại được, và một báo cáo Z cho con số đóng ca cuối cùng, đã khóa. Mỗi báo cáo ghép phần đối soát tiền mặt (quỹ đầu ca, doanh thu tiền mặt, thu/chi tiền mặt, dự kiến so với thực tế, chênh lệch) với một bản tổng hợp doanh số, để mỗi ca đóng dựa trên một con số kiểm chứng được thay vì phỏng đoán.
1. Context & Problem
Thu ngân POS vận hành ca dựa trên một PosSession đang mở. Hiện tại một session theo dõi các biến động tiền mặt nhưng không tạo ra báo cáo nào, nên không có cách nào để xem tổng của ca hay đối soát ngăn kéo ngay tại quầy: thu ngân không thấy được tiền mặt dự kiến so với thực tế, không kéo được bản tóm tắt giữa ca, và không có snapshot đã khóa để bàn giao khi đóng ca. Thiếu điều đó, việc bàn giao ca phải dựa vào đếm tay và chủ cửa hàng không có bản ghi kiểm toán được về số tiền mỗi ca thu vào - một điểm nghẽn cho vận hành minh bạch tiền mặt ở quy mô HKD/SME mà KICKO hướng tới.
Phần tăng trưởng này cung cấp hai báo cáo mà thu ngân kỳ vọng trên một session đang mở - báo cáo X tạm thời và báo cáo Z đóng ca - được hậu thuẫn bởi một snapshot đóng ca được lưu trữ, dựng trên vòng đời session POS và cơ chế theo dõi biến động tiền mặt đã có sẵn.
2. Goals & Non-Goals
Goals
- Một báo cáo X (tạm thời): snapshot trong ca trực tiếp tạo từ session đang mở, lặp lại được bao nhiêu lần tùy ý.
- Một báo cáo Z (đóng ca): báo cáo đóng ca cuối cùng, đọc một lần duy nhất cho mỗi session và được hậu thuẫn bởi một snapshot
PosSessionReportlưu trữ. - Đối soát tiền mặt: quỹ đầu ca, doanh thu tiền mặt, thu/chi tiền mặt, tiền mặt dự kiến so với thực tế đã đếm, và chênh lệch, kèm một số đếm kiểm lại khi đóng ca trên session.
- Một bản tổng hợp doanh số trên báo cáo: tổng, chiết khấu, thuế, thực thu, và số lượng đơn.
- Phân tách theo merchant + sale channel và liệt kê session có phân trang.
Non-Goals
- Báo cáo doanh số ngày / sản phẩm / danh mục - thuộc về feature
SLS(URD-SLS). - Lãi lỗ, định giá kho, phân tích khách hàng, xuất file, và báo cáo theo lịch -
ADV, Planned (URD-ADV). - Phân rã theo phương thức thanh toán và theo danh mục trên báo cáo ca (mức Should URD-SHF-005..006).
- Ca nhiều nhân viên và bước xác thực PIN khi truy cập báo cáo.
3. Success Metrics
| Metric | Mục tiêu / tín hiệu |
|---|---|
| Mức phủ đối soát | 100% session đã đóng tạo ra đúng một báo cáo Z |
| Độ chính xác tiền mặt | Chênh lệch = tiền mặt đã đếm − (quỹ đầu ca + doanh thu tiền mặt − chi tiền mặt); hiển thị ở mỗi lần đóng ca |
| Tính dùng được giữa ca | Báo cáo X lặp lại được giữa ca mà không làm thay đổi session |
| Tính đúng của phân tách | Không trả về con số xuyên merchant trên bất kỳ báo cáo nào |
4. Personas & Use Cases
| Persona | Mục tiêu trong feature này |
|---|---|
| Thu ngân | Kéo báo cáo X giữa ca; đóng ca để tạo báo cáo Z với phần đối soát tiền mặt đã đếm |
| Quản lý | Xem lại báo cáo Z của bất kỳ ca nào thuộc merchant của mình |
| Chủ cửa hàng | Xem đối soát ca trên các merchant của mình |
Kịch bản chính: mở một session POS → kéo báo cáo X giữa ca (lặp lại được) → khi đóng ca, đếm tiền mặt thực tế → hệ thống tính dự kiến so với thực tế và khóa một snapshot báo cáo Z, một báo cáo cho mỗi session.
5. User Stories
- Là một thu ngân, tôi muốn kéo báo cáo X từ session đang mở của mình, để kiểm tra tổng tiền mặt và doanh số tạm thời mà không phải đóng ca.
- Là một thu ngân, tôi muốn báo cáo X lặp lại được, để kiểm tra lại tổng số khi ca diễn ra.
- Là một thu ngân, tôi muốn đóng session với số đếm tiền mặt kiểm lại, để báo cáo Z hiển thị dự kiến so với thực tế và chênh lệch.
- Là một quản lý, tôi muốn đúng một báo cáo Z đã khóa cho mỗi session, để con số đóng ca không bị trôi.
- Là một chủ cửa hàng, tôi muốn báo cáo ca được phân tách theo merchant của mình, để không lẫn con số của merchant khác.
6. Functional Requirements
| # | Yêu cầu | URD ref |
|---|---|---|
| FR-1 | Báo cáo X (tạm thời): tạo snapshot trực tiếp từ session đang mở qua POST …/x-report; lặp lại được, không làm thay đổi session | URD-SHF-001 |
| FR-2 | Báo cáo Z (đóng ca): báo cáo đóng ca tổng hợp, đọc một lần duy nhất cho mỗi session qua GET …/z-report, được hậu thuẫn bởi snapshot PosSessionReport lưu trữ | URD-SHF-002 |
| FR-3 | Đối soát tiền mặt: quỹ đầu ca, doanh thu tiền mặt, thu/chi tiền mặt, tiền mặt dự kiến so với thực tế đã đếm, chênh lệch, cộng số đếm kiểm lại khi đóng ca trên session | URD-SHF-003 |
| FR-4 | Bản tổng hợp doanh số trên báo cáo: tổng, chiết khấu, thuế, thực thu, số lượng đơn | URD-SHF-004 |
| FR-5 | Báo cáo phân tách theo merchant và sale channel; liệt kê session có phân trang và bộ lọc | URD-SHF-001..002 |
| FR-6 | Authorization subject PosSession.getXReport / PosSession.getZReport (action READ) kiểm soát hai route báo cáo | URD-SHF-001..002 |
Toàn văn yêu cầu và tiêu chí nghiệm thu nằm trong URD Báo cáo. PRD này tham chiếu tới chúng thay vì lặp lại. Phân rã theo phương thức thanh toán và theo danh mục (URD-SHF-005..006, Should) nằm ngoài phần tăng trưởng này -
SHFvẫn ở trạng thái In-progress.
7. Non-Functional Requirements
| Mảng | Yêu cầu |
|---|---|
| Toàn vẹn dữ liệu | Báo cáo Z là một snapshot kết thúc, một cho mỗi session; một khi đã khóa khi đóng ca thì không đổi |
| Chỉ đọc | Báo cáo tổng hợp trên các biến động tiền mặt và đơn đã hoàn tất; báo cáo X không bao giờ làm thay đổi session |
| Tenancy & authz | Mọi thao tác phân tách theo merchant (x-merchant-id) và sale channel; các route báo cáo được kiểm soát bởi subject READ PosSession.getXReport / getZReport |
| Độ chính xác | Phép tính tiền mặt và tiền tệ dùng float(value, 4) |
| Hiệu năng / quy mô | Liệt kê session có phân trang; tổng hợp báo cáo chạy trên các biến động của một session duy nhất |
| i18n | Nhãn/trạng thái hướng người dùng song ngữ ({ en, vi }) |
8. UX & Flows
Màn hình chính (trong apps/client): màn hình ca/session, hành động báo cáo X, kiểm lại tiền mặt khi đóng ca, và màn hình báo cáo Z. Các báo cáo được phục vụ bởi shift controller của @nx/sale.
9. Data & Domain
| Entity | Vai trò |
|---|---|
PosSession | Ca đang mở - vòng đời (mở/đóng), theo dõi biến động tiền mặt, số đếm kiểm lại khi đóng ca |
PosSessionReport | Snapshot đóng ca (Z) lưu trữ - đối soát tiền mặt + tổng hợp doanh số, một cho mỗi session |
FinanceTransaction | Các biến động tiền mặt được báo cáo tổng hợp lại; tham chiếu session (pos_session_id) chủ ý không giữ ở đây |
Chỉ mang tính khái niệm - schema đầy đủ và bất biến nằm trong domain model của sale.
10. Dependencies & Assumptions
Phụ thuộc vào
- Vòng đời session POS & theo dõi biến động tiền mặt (shift service của
@nx/sale) - báo cáo X/Z tổng hợp một session đang mở hoặc vừa đóng. - Đơn đã hoàn tất (Đơn hàng) - bản tổng hợp doanh số tổng hợp các đơn đã hoàn tất trong session.
- Biến động tiền mặt / thanh toán (
@nx/finance) - thu/chi tiền mặt và doanh thu tiền mặt cấp dữ liệu cho phần đối soát. - Sale schema của
@nx/core- chứa các bảngPosSession/PosSessionReport.
Giả định
- Thu ngân mở một session với quỹ đầu ca trước khi giao dịch.
- Mỗi session đóng đúng một lần, tạo ra đúng một báo cáo Z.
11. Risks & Open Questions
| Rủi ro / câu hỏi | Giảm thiểu / trạng thái |
|---|---|
| Đối soát tiền mặt lệch với sổ cái finance | Báo cáo tổng hợp các biến động tiền mặt trực tiếp; pos_session_id đã được gỡ khỏi FinanceTransaction để báo cáo - chứ không phải sổ cái - sở hữu góc nhìn session |
| Báo cáo Z trùng cho một session | Báo cáo Z được đọc một lần duy nhất cho mỗi session dựa trên một snapshot lưu trữ; mang tính kết thúc theo thiết kế |
| Một số merchant kỳ vọng phân rã theo phương thức thanh toán / danh mục | Nằm ngoài phần tăng trưởng này (URD-SHF-005..006); SHF vẫn In-progress cho tới khi giao |
| Ca nhiều nhân viên và bước xác thực PIN khi truy cập báo cáo | Nằm ngoài phạm vi ở đây; theo dõi riêng |
12. Release Plan & Launch Criteria
| Khía cạnh | Kế hoạch |
|---|---|
| Phase | P2 - xem danh mục feature trong URD |
| Rollout | Tất cả merchant; không có feature flag |
| Migration | Thêm bảng PosSession / PosSessionReport; gỡ pos_session_id khỏi FinanceTransaction |
| Tiêu chí ra mắt | Báo cáo X lặp lại được trên session đang mở; đúng một báo cáo Z cho mỗi session đã đóng; đối soát tiền mặt và tổng hợp doanh số được kiểm chứng so với tiền mặt đã đếm |
| Giám sát | Số báo cáo Z trên mỗi session đã đóng (kỳ vọng 1:1), phân bố chênh lệch đối soát, tỉ lệ lỗi yêu cầu báo cáo |
13. FAQ
Báo cáo X và báo cáo Z khác nhau thế nào? Báo cáo X là snapshot giữa ca tạm thời, lặp lại được, kéo khi session còn mở; báo cáo Z là báo cáo đóng ca cuối cùng, tạo một lần cho mỗi session và đã khóa.
Kéo báo cáo X có thay đổi gì không? Không - nó chỉ đọc và lặp lại được; không làm thay đổi session hay bản ghi finance.
Một session có thể có nhiều hơn một báo cáo Z không? Không - đúng một báo cáo Z được tạo cho mỗi session khi đóng ca, được hậu thuẫn bởi một snapshot lưu trữ.
Vì sao session không được tham chiếu trên finance transaction? Báo cáo tổng hợp các biến động tiền mặt trực tiếp, nên tham chiếu session (pos_session_id) không được giữ trên FinanceTransaction; báo cáo sở hữu góc nhìn session.
Báo cáo ca có gồm phân rã theo phương thức thanh toán hay danh mục không? Không trong phần tăng trưởng này - đó là mức Should (URD-SHF-005..006) và vẫn còn để mở.
References
- URD: Báo cáo → Shift Reports - yêu cầu (mảng SHF)
- Liên quan: Sales Reports · Access & Scoping · Advanced Analytics
- Module: Báo cáo - tổng quan + truy vết
- Developer: @nx/sale - shift service, domain model của POS session