Files
ln-bi/src/modules/assets/analysis-export.test.ts
T

54 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from 'node:assert/strict';
import test from 'node:test';
import { statisticsExportRows, vehicleExportRows } from './analysis-export';
import type { VehicleListItem } from './types';
test('statistics export retains all ordered groups and repeats parent labels for spreadsheet filtering', () => {
const groups = Array.from({ length: 105 }, (_, i) => ({ values: ['华东', `城市${i}`], count: 1, extra: { 待交车: 0, 异动: Number(i === 104) } }));
const rows = statisticsExportRows(['区域', '城市'], groups, 105);
assert.equal(rows.length, 105);
assert.deepEqual(rows[104], { 区域: '华东', 城市: '城市104', '数量(台)': 1, 待交车: 0, 异动: 1, '占比(%)': 1 });
assert.equal(rows.reduce((n, row) => n + Number(row['数量(台)']), 0), 105);
assert.deepEqual(statisticsExportRows([], [{ values: [], count: 3 }], 3, '车次'), [{ 统计范围: '当前筛选结果', '数量(车次)': 3, '占比(%)': 100 }]);
});
test('vehicle exports preserve full records, server masking and pending/movement fields without treating missing time as zero', () => {
const vehicles = Array.from({ length: 45 }, (_, id) => ({ id, plateNumber: `车-${id}`, vin: '001234', status: 'Inventory', operationStatus: '3', customerName: '测试***公司' } as VehicleListItem));
vehicles[0].pendingDelivery = { contractNo: '001-CONTRACT', customerName: '待交***公司' };
vehicles[44].abnormalMove = { id: 'move', type: '维修', status: '待结束', work: '更换配件', elapsedDays: null } as NonNullable<VehicleListItem['abnormalMove']>;
const rows = vehicleExportRows(vehicles);
assert.equal(rows.length, 45);
assert.equal(rows[0].VIN, '001234');
assert.equal(rows[0].客户, '测试***公司');
assert.equal(rows[0].待交车合同, '001-CONTRACT');
assert.equal(rows[44].异动类型, '维修');
assert.equal(rows[44]['已异动时长(天)'], null);
assert.equal(rows[44].实际完成时间, '未完成');
assert.equal(rows[0].状态, '在库');
assert.equal(rows[0].运营状态, '可运营');
});
test('one Excel workbook contains statistics and all details in two named sheets', async () => {
const { createAnalysisWorkbook } = await import('./analysis-export');
const XLSX = await import('xlsx');
const statistics = statisticsExportRows(['区域'], [{ values: ['华东'], count: 105 }], 105);
const details = Array.from({ length: 105 }, (_, i) => ({ VIN: `000${i}`, 合同: i === 104 ? 'LAST-CONTRACT' : 'CONTRACT', 项目名称: '项目甲' }));
const workbook = await createAnalysisWorkbook(statistics, details);
const saved = XLSX.read(XLSX.write(workbook, { type: 'buffer', bookType: 'xlsx' }), { type: 'buffer' });
assert.deepEqual(saved.SheetNames, ['统计表', '详情表']);
assert.deepEqual(XLSX.utils.sheet_to_json(saved.Sheets['统计表']), statistics);
assert.deepEqual(XLSX.utils.sheet_to_json(saved.Sheets['详情表']), details);
const empty = await createAnalysisWorkbook([], []);
assert.deepEqual(empty.SheetNames, ['统计表', '详情表']);
});
test('inventory export uses assigned operations managers and a dash when unset', () => {
const vehicles = ['张三、李四', null, ' '].map(opsManagers => ({
opsManagers, customerManager: '业务负责人', customerName: '客户', status: 'Inventory',
} as VehicleListItem));
const rows = vehicleExportRows(vehicles, true);
assert.deepEqual(rows.map(row => row.运维负责人), ['张三、李四', '-', '-']);
assert.ok(rows.every(row => !('业务负责人' in row) && !('客户' in row)));
assert.equal(vehicleExportRows(vehicles)[0].业务负责人, '业务负责人');
});