99 lines
2.9 KiB
TypeScript
99 lines
2.9 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { buildDailyReport } from './daily-report.js';
|
|
import type { MonitoringData, TargetSummary, TargetVehicle } from './types.js';
|
|
|
|
function target(id: number, completed: number, goal: number): TargetSummary {
|
|
return {
|
|
id,
|
|
targetName: `目标${id}`,
|
|
vehicleCount: 2,
|
|
cumulativeTotal: completed,
|
|
currentYearCompleted: completed,
|
|
currentYearTarget: goal,
|
|
yearQualifiedCount: 0,
|
|
halfQualifiedCount: 0,
|
|
} as TargetSummary;
|
|
}
|
|
|
|
function vehicle(plateNumber: string, todayMileage: number, dailyRequiredMileage: number): TargetVehicle {
|
|
return {
|
|
plateNumber,
|
|
todayMileage,
|
|
totalMileage: 1000,
|
|
completionRate: 0.5,
|
|
isQualified: false,
|
|
currentYearIsQualified: false,
|
|
dailyRequiredMileage,
|
|
rentStatus: '租赁',
|
|
department: '业务一部',
|
|
customer: '客户甲',
|
|
isOnline: true,
|
|
};
|
|
}
|
|
|
|
const monitoring = {
|
|
stats: { totalToday: 0, totalAll: 0, vehicleCount: 10, yesterdayTotal: 0 },
|
|
updatedAt: '2026-08-07T10:00:00+08:00',
|
|
} as MonitoringData;
|
|
|
|
test('builds a weighted, additive daily report', () => {
|
|
const first = target(1, 50, 100);
|
|
const second = target(2, 100, 300);
|
|
const report = buildDailyReport(
|
|
[first, second],
|
|
[
|
|
{ target: first, vehicles: [vehicle('粤A1', 120, 100), vehicle('粤A2', 0, 100)] },
|
|
{ target: second, vehicles: [vehicle('粤A3', 50, 100)] },
|
|
],
|
|
monitoring,
|
|
[{ date: '08-06', mileage: 500 }],
|
|
'2026-08-07',
|
|
);
|
|
|
|
assert.equal(report.totalToday, 170);
|
|
assert.equal(report.dailyNeed, 300);
|
|
assert.equal(report.shortfall, 150);
|
|
assert.equal(report.activeCount, 2);
|
|
assert.equal(report.zeroCount, 1);
|
|
assert.equal(report.completionRate, 37.5);
|
|
assert.equal(report.models[0].shortfall, 100);
|
|
assert.deepEqual(report.trend, [{ date: '08-06', value: 500 }]);
|
|
});
|
|
|
|
test('deduplicates vehicles assigned to multiple targets', () => {
|
|
const first = target(1, 50, 100);
|
|
const second = target(2, 100, 300);
|
|
const report = buildDailyReport(
|
|
[first, second],
|
|
[
|
|
{ target: first, vehicles: [vehicle('粤A1', 80, 100)] },
|
|
{ target: second, vehicles: [vehicle('粤A1', 80, 100)] },
|
|
],
|
|
monitoring,
|
|
[],
|
|
'2026-08-07',
|
|
);
|
|
|
|
assert.equal(report.assessmentVehicleCount, 1);
|
|
assert.equal(report.duplicateAssignmentCount, 1);
|
|
assert.equal(report.totalToday, 80);
|
|
});
|
|
|
|
test('falls back to the target daily need when vehicle tasks are missing', () => {
|
|
const item = target(5, 100, 300);
|
|
item.dailyTarget = 250;
|
|
const report = buildDailyReport(
|
|
[item],
|
|
[{ target: item, vehicles: [vehicle('粤A1', 100, 0), vehicle('粤A2', 50, 0)] }],
|
|
monitoring,
|
|
[],
|
|
'2026-08-07',
|
|
);
|
|
|
|
assert.equal(report.dailyNeed, 250);
|
|
assert.equal(report.shortfall, 100);
|
|
assert.equal(report.missingDailyTaskCount, 2);
|
|
assert.equal(report.models[0].missingDailyTaskCount, 2);
|
|
});
|