feat(P19ERP1-3,P19ERP1-4): 实现ERP凭证导出与管理入口
这个提交包含在:
@@ -1,5 +1,71 @@
|
||||
import { apiRequestData } from "./http";
|
||||
|
||||
export type ErpMasterDataResourceType = "legal_entity" | "cost_center" | "supplier";
|
||||
|
||||
export type ErpGateStatus = {
|
||||
envEnabled: boolean;
|
||||
effectiveEnabled: boolean;
|
||||
effectiveReason: string;
|
||||
provider: string;
|
||||
masterDataEndpointConfigured: boolean;
|
||||
journalEndpointConfigured: boolean;
|
||||
masterDataSyncCron: string | null;
|
||||
};
|
||||
|
||||
export type ErpMasterDataSyncSummary = {
|
||||
requested: number;
|
||||
created: number;
|
||||
updated: number;
|
||||
archived: number;
|
||||
skipped: number;
|
||||
sampleSkipped: Array<{ key: string; reason: string }>;
|
||||
};
|
||||
|
||||
export type ErpMasterDataSyncItem = {
|
||||
resourceType: ErpMasterDataResourceType;
|
||||
status: string;
|
||||
lastStartedAt: string | null;
|
||||
lastFinishedAt: string | null;
|
||||
lastSuccessAt: string | null;
|
||||
lastError: string | null;
|
||||
lastResult: ErpMasterDataSyncSummary | null;
|
||||
};
|
||||
|
||||
export type ErpMasterDataStatusResponse = {
|
||||
gate: ErpGateStatus;
|
||||
items: ErpMasterDataSyncItem[];
|
||||
triggerMode?: string;
|
||||
};
|
||||
|
||||
export type ReimbursementJournalPreview = {
|
||||
journal: {
|
||||
journalType: string;
|
||||
sourceEventName: string;
|
||||
entityType: string;
|
||||
entityId: string;
|
||||
documentNo: string | null;
|
||||
currencyCode: string;
|
||||
totalAmount: string | null;
|
||||
occurredAt: string | null;
|
||||
paymentVoucherNo: string | null;
|
||||
paymentDate: string | null;
|
||||
dimensions: {
|
||||
departmentId: string | null;
|
||||
ownerEmployeeId: string | null;
|
||||
submitterEmployeeId: string | null;
|
||||
legalEntityCode: string | null;
|
||||
costCenterCode: string | null;
|
||||
};
|
||||
};
|
||||
exportState: {
|
||||
externalId: string | null;
|
||||
lastOutboxId: string | null;
|
||||
lastOutboxStatus: string | null;
|
||||
lastError: string | null;
|
||||
exportedAt: string | null;
|
||||
};
|
||||
};
|
||||
|
||||
export async function triggerErpSync(reimbursementId: string, runNow = true) {
|
||||
return apiRequestData<{
|
||||
outboxId: string;
|
||||
@@ -11,6 +77,36 @@ export async function triggerErpSync(reimbursementId: string, runNow = true) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function fetchErpMasterDataStatus() {
|
||||
return apiRequestData<ErpMasterDataStatusResponse>("/api/integrations/erp/master-data/status");
|
||||
}
|
||||
|
||||
export async function syncErpMasterData(payload: { resources?: ErpMasterDataResourceType[] }) {
|
||||
return apiRequestData<ErpMasterDataStatusResponse>("/api/integrations/erp/master-data/sync", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
}
|
||||
|
||||
export async function previewReimbursementJournal(reimbursementId: string) {
|
||||
return apiRequestData<ReimbursementJournalPreview>(
|
||||
`/api/integrations/erp/journals/reimbursements/${reimbursementId}/preview`,
|
||||
);
|
||||
}
|
||||
|
||||
export async function exportReimbursementJournal(reimbursementId: string, runNow = true) {
|
||||
return apiRequestData<{
|
||||
outboxId: string;
|
||||
status: string;
|
||||
duplicated: boolean;
|
||||
requeued: boolean;
|
||||
eventType: string;
|
||||
}>(`/api/integrations/erp/journals/reimbursements/${reimbursementId}/export?runNow=${runNow ? "1" : "0"}`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({}),
|
||||
});
|
||||
}
|
||||
|
||||
export async function importTravelOrders(payload: {
|
||||
orders: Array<{
|
||||
source: string;
|
||||
|
||||
在新工单中引用
屏蔽一个用户