81 行
2.5 KiB
JavaScript
81 行
2.5 KiB
JavaScript
const {
|
|
buildReimbursementJournalDedupeKey,
|
|
buildReimbursementJournalPayload,
|
|
enqueueReimbursementJournalExport,
|
|
} = require('../../../src/services/integrations/erpJournal');
|
|
|
|
describe('ERP Journal Service', () => {
|
|
afterEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it('prefers owner legal entity code and keeps cost center null', () => {
|
|
const payload = buildReimbursementJournalPayload({
|
|
reimbursement: {
|
|
id: 'rb-1',
|
|
form_number: 'BX-001',
|
|
owner_id: 'owner-1',
|
|
submitter_id: 'submitter-1',
|
|
department_id: 'dept-1',
|
|
total_amount: { toString: () => '88.80' },
|
|
payment_date: '2026-03-08T00:00:00.000Z',
|
|
paid_at: '2026-03-08T12:00:00.000Z',
|
|
owner: { legal_entity: { code: 'OWNER_LE' } },
|
|
submitter: { legal_entity: { code: 'SUBMITTER_LE' } },
|
|
},
|
|
});
|
|
|
|
expect(payload.dimensions.legalEntityCode).toBe('OWNER_LE');
|
|
expect(payload.dimensions.costCenterCode).toBeNull();
|
|
expect(payload.currencyCode).toBe('CNY');
|
|
});
|
|
|
|
it('falls back to submitter legal entity code', () => {
|
|
const payload = buildReimbursementJournalPayload({
|
|
reimbursement: {
|
|
id: 'rb-1',
|
|
form_number: 'BX-001',
|
|
owner: { legal_entity: null },
|
|
submitter: { legal_entity: { code: 'SUBMITTER_LE' } },
|
|
},
|
|
});
|
|
|
|
expect(payload.dimensions.legalEntityCode).toBe('SUBMITTER_LE');
|
|
});
|
|
|
|
it('builds dedupe key and enqueues standard export event', async () => {
|
|
const prisma = {
|
|
integrationOutbox: {
|
|
findUnique: vi.fn().mockResolvedValue(null),
|
|
create: vi.fn().mockResolvedValue({ id: 'outbox-1', status: 'pending' }),
|
|
},
|
|
};
|
|
const config = { integrationOutboxMaxAttempts: 5 };
|
|
const reimbursement = {
|
|
id: 'rb-1',
|
|
form_number: 'BX-001',
|
|
owner_id: 'owner-1',
|
|
submitter_id: 'submitter-1',
|
|
department_id: 'dept-1',
|
|
};
|
|
|
|
const result = await enqueueReimbursementJournalExport(prisma, config, {
|
|
reimbursement,
|
|
actorId: 'actor-1',
|
|
});
|
|
|
|
expect(buildReimbursementJournalDedupeKey('rb-1')).toBe('reimbursement:rb-1:paid');
|
|
expect(prisma.integrationOutbox.findUnique).toHaveBeenCalledWith({
|
|
where: {
|
|
event_type_dedupe_key: {
|
|
event_type: 'erp.journal.export',
|
|
dedupe_key: 'reimbursement:rb-1:paid',
|
|
},
|
|
},
|
|
select: { id: true, status: true, payload: true },
|
|
});
|
|
expect(prisma.integrationOutbox.create).toHaveBeenCalled();
|
|
expect(result.eventType).toBe('erp.journal.export');
|
|
});
|
|
});
|