Skip to content

v1.3 — 23/03/2026

Thay đổiSectionẢnh hưởng
Thêm FR-009 vào scope + TC-FR-009 (tab container + redirect)D1, TC-FR-009QA

QA Test Plan — Báo cáo doanh số cá nhân

Ref: PRD v1.3 | Date: 2026-03-23


D1) Test Scope

FRMô tảPriority
FR-001Pivot table hiển thị đúngMust
FR-002Filter chi nhánh + chức vụ + thángMust
FR-003Dropdown loại doanh sốMust
FR-004Export ExcelMust
FR-005SQL function commissionMust
FR-006SQL function tourMust
FR-007SQL function truy thu commission (wallet)Must
FR-008Drill-down popup chi tiết ngàyMust
FR-009Hub tab container + redirect route cũMust

D2) Test Cases

TC-FR-001: Pivot table hiển thị đúng

TCMô tảInputExpectedPriority
TC-001-01Hiển thị data commission tháng 03/2026Chọn tháng 03/2026, loại CommissionBảng pivot: hàng = NV, cột = 31 ngày, giá trị = commission/ngày, cột Tổng = sumP0
TC-001-02NV không có commission trong thángNV DV999999 không có dataKhông hiển thị row NV đó (chỉ hiển thị NV có data)P0
TC-001-03Ô không có dataNV có commission ngày 1 nhưng không ngày 2Ngày 2 hiển thị 0P0
TC-001-04Format số VNDCommission = 3700000Hiển thị 3.700.000P1
TC-001-05Sort mặc địnhMở pageSắp xếp theo Mã NV ASCP1
TC-001-06Tháng 2 (28 ngày)Chọn 02/2026Bảng có 28 cột ngàyP1
TC-001-07Tháng 2 nhuận (29 ngày)Chọn 02/2028Bảng có 29 cột ngàyP2
TC-001-08Scroll horizontal> 15 cột ngày visibleSticky: Mã NV + Họ tên (trái), Tổng (phải)P1

TC-FR-002: Filter

TCMô tảInputExpectedPriority
TC-002-01Filter chi nhánhChọn branch AChỉ hiển thị NV thuộc branch AP0
TC-002-02Filter chức vụChọn job position "KTV"Chỉ hiển thị NV có chức vụ KTVP0
TC-002-03Filter thángChọn 02/2026Data thay đổi sang tháng 2, cột = 28 ngàyP0
TC-002-04Prev/next thángClick ▶ từ 03/2026Chuyển sang 04/2026, fetch lại dataP0
TC-002-05Multi-select chi nhánhChọn branch A + BHiển thị NV thuộc branch A hoặc BP1
TC-002-06Clear filterBỏ hết filter chi nhánhHiển thị tất cả NVP1
TC-002-07Thay đổi filter → auto fetchThay đổi chi nhánhTable loading → data mớiP0

TC-FR-003: Dropdown loại doanh số

TCMô tảInputExpectedPriority
TC-003-01Default là CommissionMở pageDropdown hiện "Commission tư vấn", data = commissionP0
TC-003-02Switch sang TourChọn "Tiền tour"Data thay đổi sang tour incomeP0
TC-003-03Switch giữ filterĐang filter branch A, switch TourVẫn filter branch A, data = tourP0
TC-003-04Switch đang loadingSwitch nhanh Commission → Tour → CommissionCancel request cũ, hiển thị data cuối cùngP1
TC-003-05Switch sang Truy thuChọn "Truy thu commission"Data thay đổi sang clawback, filter chức vụ bị ẩnP0
TC-003-06Truy thu giữ filter branchĐang filter branch A, switch Truy thuVẫn filter branch A, data = clawbackP0
TC-003-07Truy thu → switch lại CommissionChọn Truy thu → chọn lại CommissionFilter chức vụ hiện lại, data = commissionP1

TC-FR-004: Export Excel

TCMô tảInputExpectedPriority
TC-004-01Export có dataTable có 10 NVFile .xlsx: 10 data rows, đúng format pivotP0
TC-004-02Tên file đúng formatExport tháng 03/2026doanh-so-nv-03-2026_{timestamp}.xlsxP1
TC-004-03Header styleMở file ExcelHeader: bold, có background colorP1
TC-004-04Số format VNDMở file ExcelSố align right, format #,##0P1
TC-004-05Export khi emptyTable không có dataFile Excel chỉ có header, không có data rowsP2
TC-004-06Export khớp với viewSo sánh table vs ExcelData giống y hệtP0

TC-FR-005: SQL function commission

TCMô tảInputExpectedPriority
TC-005-01Aggregate đúng theo ngàyNV có 3 commission ngày 01/031 row: sum 3 amountsP0
TC-005-02Timezone Asia/Ho_Chi_MinhCommission paid_at = 2026-03-01 23:30:00 UTCThuộc ngày 02/03 (06:30 sáng ICT)P0
TC-005-03Filter branchbranch_ids = [branch_A_id]Chỉ trả NV branch AP0
TC-005-04Filter job positionjob_positions = ['dept_id']Chỉ trả NV department đóP0
TC-005-05Soft delete NVNV có deleted_at != NULLKhông trả NV đã xóaP0
TC-005-06Empty branch filterbranch_ids = '{}'Trả tất cả NV (không filter)P1
TC-005-07Loại trừ thanh toán bằng ví (DEC-012)NV có commission từ invoice ví DIVA (payment_method_id = 'wallet')Không tính commission từ invoice ví → total_amount giảmP0
TC-005-08Loại trừ ví khuyến mãi (DEC-012)NV có commission từ invoice ví KM (payment_method_id = 'wallet_promotion')Không tính commission từ invoice ví KMP0
TC-005-09NV chỉ có commission từ víTất cả invoices của NV đều thanh toán bằng víNV không xuất hiện trong kết quả (không có row)P1

TC-FR-006: SQL function tour

TCMô tảInputExpectedPriority
TC-006-01Aggregate đúng theo ngàyNV có 2 tour done ngày 01/031 row: sum 2 tour_moneyP0
TC-006-02Timezone Asia/Ho_Chi_MinhTour done_at = 2026-03-01 23:30:00 UTCThuộc ngày 02/03 (06:30 sáng ICT)P0
TC-006-03Chỉ task doneTask status is_done = falseKhông tínhP0
TC-006-04tour_money = 0pta.tour_money = 0Không tínhP1
TC-006-05tour_money = NULLpta.tour_money IS NULLKhông tínhP1
TC-006-06Supervisor/assigner excludedpta.supervisor = trueKhông tínhP1
TC-006-07Cùng shape với commissionSo sánh output 2 functionsCùng columns: user_id, employee_code, display_name, report_date, total_amountP0

TC-FR-007: SQL function truy thu commission (v1.1)

TCMô tảInputExpectedPriority
TC-007-01Aggregate truy thu đúng theo ngàyNV có 2 truy thu cùng ngày 20/031 row: sum 2 amountsP0
TC-007-02Timezone Asia/Ho_Chi_MinhTruy thu updated_at = 2026-03-20 23:30:00 UTCThuộc ngày 21/03 (06:30 sáng ICT)P0
TC-007-03Filter branchbranch_ids = [branch_A_id]Chỉ trả NV branch A (qua wallet_user.branch_id)P0
TC-007-04Chỉ lấy status SCó request status R (pending) và S (success)Chỉ trả status = SP0
TC-007-05Chỉ lấy refund_commissionCó behavior_id = 'transaction_commission' và 'refund_commission'Chỉ trả refund_commissionP0
TC-007-06Cùng shape với commission/tourSo sánh output 3 functionsCùng columns: user_id, employee_code, display_name, report_date, total_amountP0
TC-007-07NV không bị truy thu (approver không nhập)Hoàn tiền nhưng không nhập truy thuKhông có row cho NV đóP1
TC-007-08Amount luôn dươngKiểm tra outputtotal_amount >= 0P1

TC-FR-008: Drill-down popup chi tiết ngày (v1.1)

TCMô tảInputExpectedPriority
TC-008-01Click ô commission → mở popupClick 3.700.000 (NV Giang, 01/03)Popup mở: title "Chi tiết doanh số — Nguyễn Thị Giang — 01/03/2026", danh sách đơn hàngP0
TC-008-02Popup hiện bút toán âmNV có truy thu ngày 20/03Row "Truy thu commission" với amount âm, màu đỏP0
TC-008-03Popup merge commission + truy thuDropdown = Commission, click ô ngày có cả 2Hiện cả commission (dương) + truy thu (âm) trong 1 popupP0
TC-008-04Click ô = 0Click ô có giá trị 0Popup hiện "Không có giao dịch"P1
TC-008-05Click cột TổngClick cột Tổng của NVPopup hiện tất cả giao dịch cả thángP0
TC-008-06Popup khi dropdown = TourChọn Tiền tour, click ôPopup chỉ hiện chi tiết tour, không có truy thuP1
TC-008-07Popup khi dropdown = Truy thuChọn Truy thu, click ôPopup chỉ hiện bút toán truy thuP1
TC-008-08Mã đơn gốc trong truy thuTruy thu có order_id linkCột "Mã đơn hàng" hiện mã đơn gốc bị hoànP1
TC-008-09Mã đơn gốc NULLTruy thu không có order_idCột "Mã đơn hàng" hiện "—"P2
TC-008-10Mã giao dịch fallbacktransaction_request.code = NULLHiện transaction_request.id (UUID)P2

TC-FR-009: Hub tab container + redirect

TCMô tảInputExpectedPriority
TC-009-01Card hiển thị trên ReportsMở trang ReportsCard "Báo cáo doanh số cá nhân" hiển thị, 2 cards cũ (Doanh thu NV + Tour) không hiển thịP0
TC-009-02Default tabClick card → vào pageTab "Doanh số theo ngày" active, pivot table hiển thịP0
TC-009-03Switch tab RevenueClick tab "Doanh thu theo đơn hàng"Component EmployeeRevenueReport render đúng, có filter + chart + tableP0
TC-009-04Switch tab TourClick tab "Tiền tour"Component TourIncomeReport render đúng, có filter + chart + tableP0
TC-009-05Redirect route cũ → revenueTruy cập /r/reports/employee_revenue_report_groupRedirect → tab "Doanh thu theo đơn hàng" activeP0
TC-009-06Redirect route cũ → tourTruy cập /r/reports/tour_income_report_groupRedirect → tab "Tiền tour" activeP0
TC-009-07Query param syncURL ?tab=tourTab "Tiền tour" activeP1
TC-009-08Query param invalidURL ?tab=invalidFallback về tab "Doanh số theo ngày"P2
TC-009-09Tab switch giữ stateChọn filter ở tab Daily, switch sang Revenue, switch lại DailyFilter ở Daily vẫn giữ nguyênP1
TC-009-10Permission — chỉ có quyền 1 reportUser chỉ có quyền xem tour reportCard "Báo cáo doanh số cá nhân" vẫn hiển thịP1

D3) Seed Data

Dataset: DS-001 — Commission test data

Cách tạo: SQL Script

sql
-- Tạo commission cho NV test trong tháng 03/2026
-- NV 1: có commission nhiều ngày
-- NV 2: có commission 1 ngày
-- NV 3: không có commission (để verify không hiển thị)
-- Verify: SELECT * FROM search_employee_daily_commission('2026-03-01', '2026-03-31');

Dataset: DS-002 — Tour test data

sql
-- Tạo tour income cho NV test trong tháng 03/2026
-- NV 1: có tour done nhiều ngày
-- NV 2: có tour nhưng is_done = false (không tính)
-- NV 3: có tour nhưng supervisor = true (không tính)
-- Verify: SELECT * FROM search_employee_daily_tour_income('2026-03-01', '2026-03-31');

Dataset: DS-003 — Clawback test data (wallet) — v1.1

sql
-- Tạo truy thu commission cho NV test trong tháng 03/2026
-- NV 1: có truy thu ngày 20/03 (1 request, 2 transactions)
-- NV 2: có truy thu ngày 25/03 (1 request, order_id link đơn gốc)
-- NV 3: hoàn tiền nhưng approver KHÔNG nhập truy thu (không tạo transaction)
-- NV 4: có request nhưng status = 'R' (pending, chưa duyệt)
-- Verify: SELECT * FROM search_employee_daily_commission_clawback('2026-03-01', '2026-03-31');

D4) Traceability

FRFE ArtifactBE ArtifactTC-IDStatus
FR-001SCR-01 PivotTableTC-001-*
FR-002SCR-01 FilterBarTC-002-*
FR-003SCR-01 DropdownTC-003-*
FR-004SCR-01 ExportBtnExcelBuilderTC-004-*
FR-005search_employee_daily_commissionTC-005-*
FR-006search_employee_daily_tour_incomeTC-006-*
FR-007search_employee_daily_commission_clawbackTC-007-*
FR-008SCR-02 PopupGetClawbackDetail + search_report_employeeTC-008-*
FR-009SCR-00 Hub + RedirectTC-009-*