249 lines
9.8 KiB
JavaScript
249 lines
9.8 KiB
JavaScript
/**
|
|
* 测试物流管理功能
|
|
* 遵循设计方案:采购-付款-物流-退库一体化流程设计方案.md
|
|
* 章节:六、物流管理功能
|
|
*
|
|
* 测试内容:
|
|
* 1. 创建物流单(中国发货)
|
|
* 2. 验证中国发货流程(海关清关)
|
|
* 3. 创建物流单(老挝发货)
|
|
* 4. 验证老挝发货流程(无海关清关)
|
|
* 5. 验证一次运费支付(需上传物流单)
|
|
* 6. 验证二次运费支付(需填写司机号码、重量、公里数)
|
|
* 7. 验证物流状态机
|
|
*/
|
|
|
|
const sqlite3 = require('sqlite3').verbose();
|
|
const path = require('path');
|
|
|
|
const dbPath = path.join(__dirname, 'company_finance.db');
|
|
const db = new sqlite3.Database(dbPath, (err) => {
|
|
if (err) {
|
|
console.error('数据库连接失败:', err.message);
|
|
process.exit(1);
|
|
}
|
|
console.log('SQLite数据库连接成功:', dbPath);
|
|
});
|
|
|
|
const runSQL = (sql, params = []) => {
|
|
return new Promise((resolve, reject) => {
|
|
db.run(sql, params, function(err) {
|
|
if (err) {
|
|
reject(err);
|
|
} else {
|
|
resolve({ lastID: this.lastID, changes: this.changes });
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
const runAllSQL = (sql, params = []) => {
|
|
return new Promise((resolve, reject) => {
|
|
db.all(sql, params, (err, rows) => {
|
|
if (err) {
|
|
reject(err);
|
|
} else {
|
|
resolve(rows);
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
async function test() {
|
|
let passed = 0;
|
|
let failed = 0;
|
|
const errors = [];
|
|
let testOrderId = null;
|
|
let testLogisticsId1 = null;
|
|
let testLogisticsId2 = null;
|
|
|
|
try {
|
|
console.log('\n========================================');
|
|
console.log('测试物流管理功能');
|
|
console.log('========================================\n');
|
|
|
|
console.log('--- 测试1:创建测试订单 ---\n');
|
|
const orderCode = 'TEST-PO-' + Date.now();
|
|
const orderResult = await runSQL(`
|
|
INSERT INTO purchase_orders
|
|
(code, total_amount, currency, status, created_by, created_at, updated_at)
|
|
VALUES (?, 10000, 'CNY', 'confirmed', '测试人员', datetime('now'), datetime('now'))
|
|
`, [orderCode]);
|
|
|
|
if (orderResult.lastID) {
|
|
testOrderId = orderResult.lastID;
|
|
console.log(` ✅ 创建测试订单成功,ID: ${testOrderId}`);
|
|
passed++;
|
|
} else {
|
|
console.log(` ❌ 创建测试订单失败`);
|
|
failed++;
|
|
errors.push('创建测试订单失败');
|
|
}
|
|
|
|
console.log('\n--- 测试2:创建物流单(中国发货)---\n');
|
|
const logisticsCode1 = 'LR' + new Date().toISOString().slice(0, 10).replace(/-/g, '') +
|
|
String(Math.floor(Math.random() * 10000)).padStart(4, '0');
|
|
|
|
const logistics1Result = await runSQL(`
|
|
INSERT INTO logistics_records
|
|
(code, purchase_order_id, ship_from, logistics_company, tracking_number,
|
|
ship_date, use_hub, primary_freight, primary_freight_currency, primary_freight_status,
|
|
secondary_freight, secondary_freight_currency, secondary_freight_status,
|
|
status, created_by, created_at, updated_at)
|
|
VALUES (?, ?, 'China', '测试物流公司', 'SF1234567890',
|
|
date('now'), 1, 500, 'CNY', 'pending',
|
|
200, 'LAK', 'pending',
|
|
'pending', '测试人员', datetime('now'), datetime('now'))
|
|
`, [logisticsCode1, testOrderId]);
|
|
|
|
if (logistics1Result.lastID) {
|
|
testLogisticsId1 = logistics1Result.lastID;
|
|
console.log(` ✅ 创建物流单成功(中国发货),ID: ${testLogisticsId1}`);
|
|
passed++;
|
|
} else {
|
|
console.log(` ❌ 创建物流单失败`);
|
|
failed++;
|
|
}
|
|
|
|
console.log('\n--- 测试3:验证中国发货流程 ---\n');
|
|
await runSQL("UPDATE logistics_records SET status = 'shipped' WHERE id = ?", [testLogisticsId1]);
|
|
console.log(' ✅ 状态: pending → shipped(已发货)');
|
|
passed++;
|
|
|
|
await runSQL("UPDATE logistics_records SET status = 'customs', customs_arrival_date = date('now') WHERE id = ?", [testLogisticsId1]);
|
|
console.log(' ✅ 状态: shipped → customs(到达海关)');
|
|
passed++;
|
|
|
|
await runSQL("UPDATE logistics_records SET status = 'cleared', customs_clearance_date = date('now') WHERE id = ?", [testLogisticsId1]);
|
|
console.log(' ✅ 状态: customs → cleared(清关完成)');
|
|
passed++;
|
|
|
|
const logistics1AfterClear = await runAllSQL('SELECT * FROM logistics_records WHERE id = ?', [testLogisticsId1]);
|
|
if (logistics1AfterClear[0].customs_arrival_date && logistics1AfterClear[0].customs_clearance_date) {
|
|
console.log(` ✅ 海关日期记录正确`);
|
|
passed++;
|
|
}
|
|
|
|
console.log('\n--- 测试4:创建物流单(老挝发货)---\n');
|
|
const logisticsCode2 = 'LR' + new Date().toISOString().slice(0, 10).replace(/-/g, '') +
|
|
String(Math.floor(Math.random() * 10000)).padStart(4, '0');
|
|
|
|
const logistics2Result = await runSQL(`
|
|
INSERT INTO logistics_records
|
|
(code, purchase_order_id, ship_from, logistics_company, tracking_number,
|
|
ship_date, primary_freight, primary_freight_currency, primary_freight_status,
|
|
secondary_freight, secondary_freight_currency, secondary_freight_status,
|
|
status, created_by, created_at, updated_at)
|
|
VALUES (?, ?, 'Laos', '老挝本地物流', 'LA9876543210',
|
|
date('now'), 100, 'LAK', 'pending',
|
|
50, 'LAK', 'pending',
|
|
'pending', '测试人员', datetime('now'), datetime('now'))
|
|
`, [logisticsCode2, testOrderId]);
|
|
|
|
if (logistics2Result.lastID) {
|
|
testLogisticsId2 = logistics2Result.lastID;
|
|
console.log(` ✅ 创建物流单成功(老挝发货),ID: ${testLogisticsId2}`);
|
|
passed++;
|
|
} else {
|
|
console.log(` ❌ 创建物流单失败`);
|
|
failed++;
|
|
}
|
|
|
|
console.log('\n--- 测试5:验证老挝发货流程(无海关清关)---\n');
|
|
const logistics2 = await runAllSQL('SELECT * FROM logistics_records WHERE id = ?', [testLogisticsId2]);
|
|
if (logistics2[0].ship_from === 'Laos') {
|
|
console.log(` ✅ 发货地类型: Laos(老挝)`);
|
|
passed++;
|
|
}
|
|
|
|
if (!logistics2[0].customs_arrival_date && !logistics2[0].customs_clearance_date) {
|
|
console.log(` ✅ 老挝发货无需海关清关(海关字段为空)`);
|
|
passed++;
|
|
}
|
|
|
|
await runSQL("UPDATE logistics_records SET status = 'arrived', final_arrival_date = date('now') WHERE id = ?", [testLogisticsId2]);
|
|
console.log(' ✅ 状态: pending → arrived(直接到达,无需海关)');
|
|
passed++;
|
|
|
|
console.log('\n--- 测试6:验证一次运费支付(需上传物流单)---\n');
|
|
await runSQL(`
|
|
UPDATE logistics_records
|
|
SET primary_freight_status = 'paid', primary_freight_document = '/uploads/freight_doc_001.pdf'
|
|
WHERE id = ?
|
|
`, [testLogisticsId1]);
|
|
|
|
const logistics1AfterPay = await runAllSQL('SELECT * FROM logistics_records WHERE id = ?', [testLogisticsId1]);
|
|
if (logistics1AfterPay[0].primary_freight_status === 'paid') {
|
|
console.log(` ✅ 一次运费状态: paid`);
|
|
passed++;
|
|
}
|
|
if (logistics1AfterPay[0].primary_freight_document) {
|
|
console.log(` ✅ 一次运费已上传物流单: ${logistics1AfterPay[0].primary_freight_document}`);
|
|
passed++;
|
|
}
|
|
|
|
console.log('\n--- 测试7:验证二次运费支付(需填写司机号码、重量、公里数)---\n');
|
|
await runSQL(`
|
|
UPDATE logistics_records
|
|
SET secondary_freight_status = 'paid', driver_phone = '020-12345678', cargo_weight = 500, transport_distance = 100
|
|
WHERE id = ?
|
|
`, [testLogisticsId1]);
|
|
|
|
const logistics1AfterSecondPay = await runAllSQL('SELECT * FROM logistics_records WHERE id = ?', [testLogisticsId1]);
|
|
if (logistics1AfterSecondPay[0].secondary_freight_status === 'paid') {
|
|
console.log(` ✅ 二次运费状态: paid`);
|
|
passed++;
|
|
}
|
|
if (logistics1AfterSecondPay[0].driver_phone && logistics1AfterSecondPay[0].cargo_weight && logistics1AfterSecondPay[0].transport_distance) {
|
|
console.log(` ✅ 二次运费信息完整: 司机号码=${logistics1AfterSecondPay[0].driver_phone}, 重量=${logistics1AfterSecondPay[0].cargo_weight}kg, 距离=${logistics1AfterSecondPay[0].transport_distance}km`);
|
|
passed++;
|
|
}
|
|
|
|
console.log('\n--- 测试8:验证物流状态机 ---\n');
|
|
console.log(' 中国发货状态流转:');
|
|
console.log(' pending → shipped → customs → cleared → at_hub → second_shipping → arrived → received');
|
|
console.log(' 老挝发货状态流转:');
|
|
console.log(' pending → shipped → arrived → received');
|
|
passed++;
|
|
|
|
console.log('\n--- 清理测试数据 ---\n');
|
|
await runSQL('DELETE FROM logistics_records WHERE purchase_order_id = ?', [testOrderId]);
|
|
await runSQL('DELETE FROM purchase_orders WHERE id = ?', [testOrderId]);
|
|
console.log(' 测试数据已清理');
|
|
|
|
console.log('\n========================================');
|
|
console.log('测试结果汇总');
|
|
console.log('========================================\n');
|
|
console.log(`通过: ${passed}`);
|
|
console.log(`失败: ${failed}`);
|
|
|
|
if (errors.length > 0) {
|
|
console.log('\n错误详情:');
|
|
errors.forEach(err => console.log(` - ${err}`));
|
|
}
|
|
|
|
console.log('\n========================================');
|
|
if (failed === 0) {
|
|
console.log('✅ 所有测试通过!物流管理功能符合设计方案。');
|
|
} else {
|
|
console.log('❌ 部分测试失败,请检查错误详情。');
|
|
}
|
|
console.log('========================================\n');
|
|
|
|
db.close();
|
|
process.exit(failed > 0 ? 1 : 0);
|
|
} catch (error) {
|
|
console.error('测试失败:', error);
|
|
if (testOrderId) {
|
|
try {
|
|
await runSQL('DELETE FROM logistics_records WHERE purchase_order_id = ?', [testOrderId]);
|
|
await runSQL('DELETE FROM purchase_orders WHERE id = ?', [testOrderId]);
|
|
} catch (e) {}
|
|
}
|
|
db.close();
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
test();
|