Initial commit: sap-legacy-webhook-emulator
Reconstruye el Webhook Messenger nativo de SAP B1 (FP2605) para clientes que aun no estan en esa version: captura eventos via SBO_SP_PostTransactionNotice, provisiona UserTables OEVC/EVC1/OEVN/EVN1 y despacha CloudEvents al mismo endpoint que el messenger real. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
commit
e1c8ee9015
42 files changed
+4042
No files matched your search
@@ -0,0 +1,72 @@
|
||||
import type { ServiceLayerClient } from '../service-layer-client.ts';
|
||||
import { generateCode } from '../lib/codes.ts';
|
||||
import { hhmmss } from '../lib/timestamps.ts';
|
||||
import { userTableEntity } from '../lib/service-layer-paths.ts';
|
||||
|
||||
const ENTITY = userTableEntity('EVN1');
|
||||
|
||||
export interface Evn1Row {
|
||||
code: string;
|
||||
eventId: string;
|
||||
webhookId: string;
|
||||
status: string;
|
||||
retry: number;
|
||||
}
|
||||
|
||||
function toRow(raw: Record<string, unknown>): Evn1Row {
|
||||
return {
|
||||
code: raw.Code as string,
|
||||
eventId: raw.U_EventID as string,
|
||||
webhookId: raw.U_WebhookID as string,
|
||||
status: raw.U_Status as string,
|
||||
retry: (raw.U_Retry as number) ?? 0,
|
||||
};
|
||||
}
|
||||
|
||||
export async function findExisting(client: ServiceLayerClient, eventId: string, webhookId: string): Promise<Evn1Row | null> {
|
||||
const filter = encodeURIComponent(`U_EventID eq '${eventId}' and U_WebhookID eq '${webhookId}'`);
|
||||
const res = await client.get(`/${ENTITY}?$filter=${filter}`);
|
||||
const rows = (res.data?.value as Record<string, unknown>[]) ?? [];
|
||||
return rows.length > 0 ? toRow(rows[0]) : null;
|
||||
}
|
||||
|
||||
export async function create(client: ServiceLayerClient, eventId: string, webhookId: string): Promise<void> {
|
||||
await client.post(`/${ENTITY}`, {
|
||||
Code: generateCode(),
|
||||
Name: `${eventId}/${webhookId}`,
|
||||
U_EventID: eventId,
|
||||
U_WebhookID: webhookId,
|
||||
U_Status: 'F',
|
||||
U_Retry: 0,
|
||||
});
|
||||
}
|
||||
|
||||
export async function listPending(client: ServiceLayerClient): Promise<Evn1Row[]> {
|
||||
const rows = await client.getAll(`/${ENTITY}?$filter=${encodeURIComponent("U_Status eq 'F'")}`);
|
||||
return rows.map(toRow);
|
||||
}
|
||||
|
||||
export async function listForEvent(client: ServiceLayerClient, eventId: string): Promise<Evn1Row[]> {
|
||||
const rows = await client.getAll(`/${ENTITY}?$filter=${encodeURIComponent(`U_EventID eq '${eventId}'`)}`);
|
||||
return rows.map(toRow);
|
||||
}
|
||||
|
||||
export async function markDelivered(client: ServiceLayerClient, code: string, returnCode: number): Promise<void> {
|
||||
const now = new Date();
|
||||
await client.patch(`/${ENTITY}('${code}')`, {
|
||||
U_Status: 'D',
|
||||
U_ReturnCode: returnCode,
|
||||
U_LastSentDT: now.toISOString(),
|
||||
U_LastSentTM: hhmmss(now),
|
||||
});
|
||||
}
|
||||
|
||||
export async function markFailedAttempt(client: ServiceLayerClient, row: Evn1Row, returnCode: number): Promise<void> {
|
||||
const now = new Date();
|
||||
await client.patch(`/${ENTITY}('${row.code}')`, {
|
||||
U_Retry: row.retry + 1,
|
||||
U_ReturnCode: returnCode,
|
||||
U_LastSentDT: now.toISOString(),
|
||||
U_LastSentTM: hhmmss(now),
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user