const { buildTravelOrderPaymentJournalPayload, buildTravelOrderPaymentJournalDedupeKey, buildTravelOrderPaymentJournalPreview, } = require("../../../src/services/integrations/erpJournal"); describe("erpJournal travel helpers", () => { it("builds payment journal payload with travel dimensions", () => { const payload = buildTravelOrderPaymentJournalPayload({ travelOrder: { id: "order-1", source: "ctrip", external_order_no: "EXT-001", employee_id: "employee-1", department_id: "dept-1", travel_request_id: "travel-1", amount: "500.00", currency: "CNY", payment_voucher_no: "BANK-001", payment_date: new Date("2026-03-10T00:00:00.000Z"), payment_channel: "bank_transfer", paid_at: new Date("2026-03-10T09:00:00.000Z"), created_at: new Date("2026-03-10T08:00:00.000Z"), updated_at: new Date("2026-03-10T09:00:00.000Z"), travel_request: { id: "travel-1", request_no: "CL-20260310-0001", applicant_employee_id: "employee-1", submitter_id: null, legal_entity: { code: "HY" }, cost_center: { code: "CC001" }, budget_pool: { code: "POOL-1" }, }, }, }); expect(payload).toEqual( expect.objectContaining({ journalType: "travel_order_payment", sourceEventName: "travel_order.paid", entityType: "travel_order", entityId: "order-1", documentNo: "EXT-001", paymentVoucherNo: "BANK-001", paymentDate: "2026-03-10", paymentChannel: "bank_transfer", dimensions: expect.objectContaining({ legalEntityCode: "HY", costCenterCode: "CC001", budgetPoolCode: "POOL-1", }), }), ); }); it("builds stable travel-order dedupe key", () => { expect(buildTravelOrderPaymentJournalDedupeKey("order-1")).toBe("travel_order:order-1:paid"); }); it("builds preview with current binding and outbox state", async () => { const prisma = { integrationBinding: { findUnique: vi.fn().mockResolvedValue({ id: "binding-1", provider: "erp", entity_type: "travel_order_payment_journal", local_id: "order-1", external_id: "erp-1", external_code: "EXT-001", last_synced_at: new Date("2026-03-10T10:00:00.000Z"), }), }, integrationOutbox: { findFirst: vi.fn().mockResolvedValue({ id: "outbox-1", event_type: "erp.journal.export", status: "succeeded", last_error: null, processed_at: new Date("2026-03-10T10:00:00.000Z"), updated_at: new Date("2026-03-10T10:00:00.000Z"), }), }, }; const preview = await buildTravelOrderPaymentJournalPreview(prisma, { id: "order-1", source: "ctrip", external_order_no: "EXT-001", employee_id: "employee-1", department_id: "dept-1", linked_reimbursement_id: null, travel_request_id: "travel-1", amount: "500.00", currency: "CNY", payment_voucher_no: "BANK-001", payment_date: new Date("2026-03-10T00:00:00.000Z"), payment_channel: "bank_transfer", paid_at: new Date("2026-03-10T09:00:00.000Z"), created_at: new Date("2026-03-10T08:00:00.000Z"), updated_at: new Date("2026-03-10T09:00:00.000Z"), travel_request: { id: "travel-1", request_no: "CL-20260310-0001", applicant_employee_id: "employee-1", submitter_id: null, legal_entity: { code: "HY" }, cost_center: { code: "CC001" }, budget_pool: { code: "POOL-1" }, }, }); expect(preview.exportState).toEqual( expect.objectContaining({ externalId: "erp-1", lastOutboxId: "outbox-1", lastOutboxStatus: "succeeded", }), ); expect(preview.binding).toEqual(expect.objectContaining({ localId: "order-1" })); }); });