184 lines
6.7 KiB
JavaScript
184 lines
6.7 KiB
JavaScript
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);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|