const request = require('supertest'); const app = require('../final-backend'); const db = require('../db-sqlite'); describe('核销申请流程测试', () => { let server; let advanceId; let verificationId1; let verificationId2; beforeAll(async () => { server = app.listen(3006); // 清理测试数据 await db.query('DELETE FROM verifications WHERE 1=1'); await db.query('DELETE FROM advances WHERE 1=1'); // 创建测试预支申请 const advanceResult = await db.query( 'INSERT INTO advances (user_id, project_id, amount, currency, reason, advance_date, advance_code, status, applicant, attachments) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [1, null, 10000, 'CNY', '测试预支', '2026-03-25', 'ADV-TEST', 'executed', '测试用户', '[]'] ); advanceId = advanceResult.lastID; // 更新预支单状态为待核销 await db.query('UPDATE advances SET status = ? WHERE id = ?', ['pending_verification', advanceId]); }); afterAll(async () => { server.close(); }); describe('预支单状态管理', () => { test('预支单初始状态应该是待核销', async () => { const result = await db.query('SELECT status FROM advances WHERE id = ?', [advanceId]); expect(result.rows[0].status).toBe('pending_verification'); }); }); describe('核销申请创建', () => { test('创建第一张核销申请(非结算)', async () => { const response = await request(server) .post('/api/verifications') .send({ verification_date: '2026-03-25', advance_id: advanceId, advance_code: 'ADV-TEST', advance_amount: 10000, currency: 'CNY', reason: '测试核销1', detail_items: [{ description: '测试费用1', amount: 6000, category: 'accommodation' }], attachments: [], applicant: '测试用户', expense_type: 'company', project_id: null, settlement: false }); expect(response.status).toBe(200); expect(response.body.success).toBe(true); verificationId1 = response.body.data.id; // 检查预支单已核销金额是否更新 const advanceResult = await db.query('SELECT total_reimbursed FROM advances WHERE id = ?', [advanceId]); expect(advanceResult.rows[0].total_reimbursed).toBe(6000); }); test('创建第二张核销申请(结算)', async () => { const response = await request(server) .post('/api/verifications') .send({ verification_date: '2026-03-25', advance_id: advanceId, advance_code: 'ADV-TEST', advance_amount: 10000, currency: 'CNY', reason: '测试核销2', detail_items: [{ description: '测试费用2', amount: 5000, category: 'food' }], attachments: [], applicant: '测试用户', expense_type: 'company', project_id: null, settlement: true, settlement_amount: -1000 }); expect(response.status).toBe(200); expect(response.body.success).toBe(true); verificationId2 = response.body.data.id; // 检查预支单已核销金额是否更新 const advanceResult = await db.query('SELECT total_reimbursed FROM advances WHERE id = ?', [advanceId]); expect(advanceResult.rows[0].total_reimbursed).toBe(11000); }); }); describe('核销申请审批和执行', () => { test('审批第一张核销申请', async () => { const response = await request(server) .post(`/api/verifications/${verificationId1}/approve`) .send({ remark: '批准' }); expect(response.status).toBe(200); expect(response.body.success).toBe(true); }); test('执行第一张核销申请(非结算)', async () => { const response = await request(server) .post(`/api/verifications/${verificationId1}/execute`) .send({ execute_method: '银行转账', voucher_no: 'VOUCHER-001' }); expect(response.status).toBe(200); expect(response.body.success).toBe(true); // 检查预支单状态应该变为部分核销 const advanceResult = await db.query('SELECT status FROM advances WHERE id = ?', [advanceId]); expect(advanceResult.rows[0].status).toBe('partial_verification'); }); test('审批第二张核销申请', async () => { const response = await request(server) .post(`/api/verifications/${verificationId2}/approve`) .send({ remark: '批准' }); expect(response.status).toBe(200); expect(response.body.success).toBe(true); }); test('执行第二张核销申请(结算)', async () => { const response = await request(server) .post(`/api/verifications/${verificationId2}/execute`) .send({ execute_method: '银行转账', voucher_no: 'VOUCHER-002' }); expect(response.status).toBe(200); expect(response.body.success).toBe(true); // 检查预支单状态应该变为已完成 const advanceResult = await db.query('SELECT status FROM advances WHERE id = ?', [advanceId]); expect(advanceResult.rows[0].status).toBe('completed'); }); }); describe('核销申请退回', () => { test('创建测试核销申请', async () => { const response = await request(server) .post('/api/verifications') .send({ verification_date: '2026-03-25', advance_id: advanceId, advance_code: 'ADV-TEST', advance_amount: 10000, currency: 'CNY', reason: '测试退回', detail_items: [{ description: '测试费用', amount: 2000, category: 'transportation' }], attachments: [], applicant: '测试用户', expense_type: 'company', project_id: null, settlement: false }); expect(response.status).toBe(200); expect(response.body.success).toBe(true); const testVerificationId = response.body.data.id; // 检查预支单已核销金额是否更新 let advanceResult = await db.query('SELECT total_reimbursed FROM advances WHERE id = ?', [advanceId]); expect(advanceResult.rows[0].total_reimbursed).toBe(13000); // 退回核销申请 const rejectResponse = await request(server) .post(`/api/verifications/${testVerificationId}/reject`) .send({ remark: '退回' }); expect(rejectResponse.status).toBe(200); expect(rejectResponse.body.success).toBe(true); // 检查预支单已核销金额是否恢复 advanceResult = await db.query('SELECT total_reimbursed FROM advances WHERE id = ?', [advanceId]); expect(advanceResult.rows[0].total_reimbursed).toBe(11000); }); }); });