import assert from 'node:assert/strict' import test from 'node:test' import { buildAdjacentProgressSteps, buildWorkbenchSummary } from '../src/utils/workbenchSummary.js' const currentUser = { name: '张三', username: 'zhangsan' } function buildStep(label, index, currentIndex) { return { label, done: index < currentIndex, active: index <= currentIndex, current: index === currentIndex, time: index === currentIndex ? '进行中' : '待处理' } } test('workbench expense progress keeps only nearby four expense steps', () => { const steps = ['创建单据', '待提交', '直属领导审批', '财务审批', '待付款', '归档入账'] .map((label, index) => buildStep(label, index, 3)) const visibleSteps = buildAdjacentProgressSteps(steps, 4) assert.deepEqual( visibleSteps.map((step) => step.label), ['直属领导审批', '财务审批', '待付款', '归档入账'] ) assert.equal(visibleSteps[1].current, true) }) test('workbench summary builds real user notifications and progress from requests', () => { const summary = buildWorkbenchSummary( [ { id: 'BX-001', claimId: 'claim-1', claimNo: 'BX-001', person: '张三', title: '差旅报销', approvalKey: 'draft', approvalStatus: '草稿', status: 'draft', amount: 1280, createdAt: '2026-06-01T10:00:00+08:00', updatedAt: '2026-06-01T10:10:00+08:00', progressSteps: [ buildStep('创建单据', 0, 1), buildStep('待提交', 1, 1), buildStep('直属领导审批', 2, 1), buildStep('财务审批', 3, 1), buildStep('待付款', 4, 1) ] }, { id: 'BX-002', claimId: 'claim-2', claimNo: 'BX-002', person: '李四', title: '他人单据', approvalKey: 'draft', amount: 800, progressSteps: [] } ], currentUser ) assert.equal(summary.todoItems.length, 1) assert.equal(summary.todoItems[0].target.id, 'claim-1') assert.equal(summary.progressItems.length, 1) assert.match(summary.progressItems[0].prompt, /单据进度/) assert.doesNotMatch(summary.progressItems[0].prompt, /费用进度/) assert.equal(summary.progressItems[0].applicantLabel, '张三') assert.deepEqual( summary.progressItems[0].steps.map((step) => step.label), ['创建单据', '待提交', '直属领导审批', '财务审批'] ) assert.equal(summary.progressItems[0].expenseTypeLabel, '差旅交通') assert.equal(summary.notifications.length, 1) assert.equal(summary.unreadNotificationCount, 1) assert.equal(summary.expenseStatsDetail.distributionRows[0].label, '差旅交通') assert.equal(summary.expenseStatsDetail.distributionRows[0].count, 1) assert.equal(summary.expenseStatsDetail.distributionRows[0].percentLabel, '100%') assert.equal(summary.expenseStatsDetail.processingRows[0].requestId, 'BX-001') assert.equal(summary.expenseStatsDetail.processingRows[0].durationLabel, '10分钟') assert.equal(summary.expenseStatsDetail.processingRows[0].stepCount, 5) assert.ok(summary.expenseStatsDetail.operationRows.some((item) => item.source === '待办')) assert.ok(summary.expenseStatsDetail.operationRows.some((item) => item.source === '进度')) assert.ok(Array.isArray(summary.reimbursementTrendRows)) assert.equal(summary.reimbursementTrendRows.length, 6) assert.equal(summary.reimbursementTrendRows.at(-1).key, '2026-06') assert.equal(summary.reimbursementTrendRows.at(-1).amount, 1280) assert.equal(summary.reimbursementTrendRows.at(-1).previousKey, '2025-06') }) test('workbench reimbursement trend compares monthly totals with last year same period', () => { const summary = buildWorkbenchSummary( [ { id: 'BX-202606', claimNo: 'BX-202606', person: currentUser.name, title: '六月报销', amount: 1280, createdAt: '2026-06-15T10:00:00+08:00' }, { id: 'BX-202605', claimNo: 'BX-202605', person: currentUser.name, title: '五月报销', amount: 860, createdAt: '2026-05-10T10:00:00+08:00' }, { id: 'BX-202506', claimNo: 'BX-202506', person: currentUser.name, title: '去年六月报销', amount: 920, createdAt: '2025-06-12T10:00:00+08:00' } ], currentUser ) assert.deepEqual( summary.reimbursementTrendRows.slice(-2).map((item) => item.label), ['5月', '6月'] ) assert.equal(summary.reimbursementTrendRows.at(-2).amount, 860) assert.equal(summary.reimbursementTrendRows.at(-2).previousAmount, 0) assert.equal(summary.reimbursementTrendRows.at(-1).amount, 1280) assert.equal(summary.reimbursementTrendRows.at(-1).previousAmount, 920) }) test('workbench progress keeps application document type for AP claims', () => { const summary = buildWorkbenchSummary( [ { id: 'AP-202606050001-ABCDEFGH', claimId: 'application-1', claimNo: 'AP-202606050001-ABCDEFGH', person: currentUser.name, title: '差旅费用', approvalKey: 'in_progress', approvalStatus: '直属领导审批', amount: 1880, createdAt: '2026-06-05T09:00:00+08:00', updatedAt: '2026-06-05T09:10:00+08:00', progressSteps: [ buildStep('创建申请', 0, 1), buildStep('直属领导审批', 1, 1), buildStep('归档', 2, 1) ] }, { id: 'REQ-APPLICATION-001', claimId: 'application-2', claimNo: 'REQ-APPLICATION-001', documentTypeCode: 'application', documentTypeLabel: '报销单', person: currentUser.name, title: '办公用品采购', approvalKey: 'in_progress', approvalStatus: '直属领导审批', amount: 2600, createdAt: '2026-06-05T09:05:00+08:00', updatedAt: '2026-06-05T09:15:00+08:00', progressSteps: [ buildStep('创建申请', 0, 1), buildStep('直属领导审批', 1, 1), buildStep('归档', 2, 1) ] } ], currentUser ) assert.deepEqual( summary.progressItems.map((item) => item.documentTypeLabel), ['申请单', '申请单'] ) }) test('workbench progress includes application rows without backend progress steps', () => { const summary = buildWorkbenchSummary( [ { id: 'AP-202606060001-NOSTEPS', claimId: 'application-without-steps', claimNo: 'AP-202606060001-NOSTEPS', documentTypeCode: 'application', person: currentUser.name, title: '上海出差申请', approvalKey: 'in_progress', approvalStatus: '直属领导审批', amount: 1880, updatedAt: '2026-06-06T09:00:00+08:00' } ], currentUser ) assert.equal(summary.progressItems.length, 1) assert.equal(summary.progressItems[0].documentTypeLabel, '申请单') assert.equal(summary.progressItems[0].applicantLabel, currentUser.name) assert.deepEqual( summary.progressItems[0].steps.map((step) => step.label), ['创建申请', '直属领导审批', '关联单据状态', '已归档'] ) assert.equal(summary.progressItems[0].steps[1].current, true) }) test('workbench progress includes application documents assigned to current approver', () => { const approverUser = { name: '李经理', username: 'manager@example.com', roleCodes: ['approver'] } const summary = buildWorkbenchSummary( [ { id: 'AP-202606060002-APPROVAL', claimId: 'application-for-approver', claimNo: 'AP-202606060002-APPROVAL', documentTypeCode: 'application', person: '张三', managerName: '李经理', title: '北京出差申请', approvalKey: 'in_progress', approvalStatus: '直属领导审批', workflowNode: '直属领导审批', amount: 2600, updatedAt: '2026-06-06T11:00:00+08:00' } ], approverUser ) assert.equal(summary.totalCount, 0) assert.equal(summary.progressItems.length, 1) assert.equal(summary.progressItems[0].documentTypeLabel, '申请单') assert.equal(summary.progressItems[0].applicantLabel, '张三') assert.equal(summary.progressItems[0].requestId, 'AP-202606060002-APPROVAL') })