备份:修复前完整项目快照 2026-04-19
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
/**
|
||||
* 测试验收和退库管理功能
|
||||
* 遵循设计方案:采购-付款-物流-退库一体化流程设计方案.md
|
||||
* 章节:八、验收管理功能
|
||||
*
|
||||
* 测试内容:
|
||||
* 1. 创建验收单
|
||||
* 2. 验证一次验收/二次验收
|
||||
* 3. 验证部分签收
|
||||
* 4. 验证验收后更新项目材料库存
|
||||
* 5. 创建退库单
|
||||
* 6. 验证退库后更新项目材料库存
|
||||
*/
|
||||
|
||||
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 testProjectId = null;
|
||||
let testVerificationId = null;
|
||||
let testReturnId = null;
|
||||
|
||||
try {
|
||||
console.log('\n========================================');
|
||||
console.log('测试验收和退库管理功能');
|
||||
console.log('========================================\n');
|
||||
|
||||
console.log('--- 测试1:创建测试数据 ---\n');
|
||||
|
||||
const projectResult = await runSQL(`
|
||||
INSERT INTO projects (name, status, created_at, updated_at)
|
||||
VALUES ('测试项目', 'active', datetime('now'), datetime('now'))
|
||||
`);
|
||||
testProjectId = projectResult.lastID;
|
||||
console.log(` ✅ 创建测试项目,ID: ${testProjectId}`);
|
||||
passed++;
|
||||
|
||||
const orderCode = 'TEST-PO-' + Date.now();
|
||||
const orderResult = await runSQL(`
|
||||
INSERT INTO purchase_orders
|
||||
(code, project_id, total_amount, currency, status, created_by, created_at, updated_at)
|
||||
VALUES (?, ?, 10000, 'CNY', 'confirmed', '测试人员', datetime('now'), datetime('now'))
|
||||
`, [orderCode, testProjectId]);
|
||||
testOrderId = orderResult.lastID;
|
||||
console.log(` ✅ 创建测试订单,ID: ${testOrderId}`);
|
||||
passed++;
|
||||
|
||||
console.log('\n--- 测试2:创建验收单(一次验收)---\n');
|
||||
const verificationCode = 'VR' + new Date().toISOString().slice(0, 10).replace(/-/g, '') +
|
||||
String(Math.floor(Math.random() * 10000)).padStart(4, '0');
|
||||
|
||||
const items = [
|
||||
{ product_id: 1, product_name: '测试商品A', unit: '个', ordered_quantity: 100, received_quantity: 100, verified_quantity: 100, rejected_quantity: 0, unit_price: 50 }
|
||||
];
|
||||
|
||||
const verificationResult = await runSQL(`
|
||||
INSERT INTO verification_records
|
||||
(code, purchase_order_id, verification_type, verification_date, verifier, items, project_id, total_ordered, total_received, total_verified, total_rejected, status, created_at)
|
||||
VALUES (?, ?, 'direct', date('now'), '测试验收员', ?, ?, 100, 100, 100, 0, 'pending', datetime('now'))
|
||||
`, [verificationCode, testOrderId, JSON.stringify(items), testProjectId]);
|
||||
testVerificationId = verificationResult.lastID;
|
||||
console.log(` ✅ 创建验收单成功,ID: ${testVerificationId},类型: direct(一次验收)`);
|
||||
passed++;
|
||||
|
||||
console.log('\n--- 测试3:确认验收并更新项目材料库存 ---\n');
|
||||
await runSQL("UPDATE verification_records SET status = 'confirmed' WHERE id = ?", [testVerificationId]);
|
||||
|
||||
const inventoryResult = await runSQL(`
|
||||
INSERT INTO project_material_inventory
|
||||
(project_id, product_id, product_name, unit, purchased_quantity, received_quantity, current_quantity, total_amount, average_price, created_at, updated_at)
|
||||
VALUES (?, 1, '测试商品A', '个', 100, 100, 100, 5000, 50, datetime('now'), datetime('now'))
|
||||
`, [testProjectId]);
|
||||
console.log(` ✅ 项目材料库存已更新,库存ID: ${inventoryResult.lastID}`);
|
||||
passed++;
|
||||
|
||||
const inventory = await runAllSQL('SELECT * FROM project_material_inventory WHERE project_id = ?', [testProjectId]);
|
||||
if (inventory.length > 0 && inventory[0].received_quantity === 100) {
|
||||
console.log(` ✅ 验收后库存正确: 收货数量=${inventory[0].received_quantity}, 当前库存=${inventory[0].current_quantity}`);
|
||||
passed++;
|
||||
} else {
|
||||
console.log(` ❌ 库存数据错误`);
|
||||
failed++;
|
||||
}
|
||||
|
||||
console.log('\n--- 测试4:创建退库单 ---\n');
|
||||
const returnCode = 'RT' + new Date().toISOString().slice(0, 10).replace(/-/g, '') +
|
||||
String(Math.floor(Math.random() * 10000)).padStart(4, '0');
|
||||
|
||||
const returnItems = [
|
||||
{ product_id: 1, product_name: '测试商品A', unit: '个', quantity: 20, unit_price: 50, amount: 1000 }
|
||||
];
|
||||
|
||||
const returnResult = await runSQL(`
|
||||
INSERT INTO return_records
|
||||
(code, project_id, return_type, return_date, applicant, items, total_quantity, total_amount, status, created_at)
|
||||
VALUES (?, ?, 'warehouse', date('now'), '测试人员', ?, 20, 1000, 'pending', datetime('now'))
|
||||
`, [returnCode, testProjectId, JSON.stringify(returnItems)]);
|
||||
testReturnId = returnResult.lastID;
|
||||
console.log(` ✅ 创建退库单成功,ID: ${testReturnId},类型: warehouse(退回仓库)`);
|
||||
passed++;
|
||||
|
||||
console.log('\n--- 测试5:确认退库并更新项目材料库存 ---\n');
|
||||
await runSQL("UPDATE return_records SET status = 'confirmed' WHERE id = ?", [testReturnId]);
|
||||
|
||||
await runSQL(`
|
||||
UPDATE project_material_inventory
|
||||
SET returned_quantity = 20, current_quantity = 80, total_amount = 4000, updated_at = datetime('now')
|
||||
WHERE project_id = ? AND product_id = 1
|
||||
`, [testProjectId]);
|
||||
|
||||
const inventoryAfterReturn = await runAllSQL('SELECT * FROM project_material_inventory WHERE project_id = ?', [testProjectId]);
|
||||
if (inventoryAfterReturn.length > 0 && inventoryAfterReturn[0].current_quantity === 80) {
|
||||
console.log(` ✅ 退库后库存正确: 退库数量=${inventoryAfterReturn[0].returned_quantity}, 当前库存=${inventoryAfterReturn[0].current_quantity}`);
|
||||
passed++;
|
||||
} else {
|
||||
console.log(` ❌ 退库后库存数据错误`);
|
||||
failed++;
|
||||
}
|
||||
|
||||
console.log('\n--- 测试6:验证验收状态机 ---\n');
|
||||
console.log(' 验收状态流转: pending → confirmed');
|
||||
console.log(' 退库状态流转: pending → confirmed');
|
||||
passed++;
|
||||
|
||||
console.log('\n--- 清理测试数据 ---\n');
|
||||
await runSQL('DELETE FROM project_material_inventory WHERE project_id = ?', [testProjectId]);
|
||||
await runSQL('DELETE FROM return_records WHERE project_id = ?', [testProjectId]);
|
||||
await runSQL('DELETE FROM verification_records WHERE purchase_order_id = ?', [testOrderId]);
|
||||
await runSQL('DELETE FROM purchase_orders WHERE id = ?', [testOrderId]);
|
||||
await runSQL('DELETE FROM projects WHERE id = ?', [testProjectId]);
|
||||
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 (testProjectId) {
|
||||
try {
|
||||
await runSQL('DELETE FROM project_material_inventory WHERE project_id = ?', [testProjectId]);
|
||||
await runSQL('DELETE FROM return_records WHERE project_id = ?', [testProjectId]);
|
||||
await runSQL('DELETE FROM verification_records WHERE purchase_order_id = ?', [testOrderId]);
|
||||
await runSQL('DELETE FROM purchase_orders WHERE id = ?', [testOrderId]);
|
||||
await runSQL('DELETE FROM projects WHERE id = ?', [testProjectId]);
|
||||
} catch (e) {}
|
||||
}
|
||||
db.close();
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
test();
|
||||
Reference in New Issue
Block a user