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>
99 lines
4.3 KiB
Transact-SQL
99 lines
4.3 KiB
Transact-SQL
-- SP_Webhook_CaptureEvent — SQL Server / T-SQL
|
|
--
|
|
-- Toda la lógica de captura del emulador vive acá, en un procedimiento
|
|
-- propio y con nombre descriptivo — no directamente en el cuerpo de
|
|
-- SBO_SP_PostTransactionNotice (ver mssql.sql), que es un hook compartido
|
|
-- de SAP donde puede convivir código de otros add-ons. Así el nuestro
|
|
-- queda identificable y fácil de mantener o remover por separado.
|
|
--
|
|
-- Requiere que la UserTable "@OEVN" ya exista (creada por
|
|
-- `npm run provision`, ver src/provisioning/).
|
|
--
|
|
-- U_UserID: no se completa. SUSER_SNAME() da el login de la conexión a SQL
|
|
-- Server (una cuenta técnica), no el usuario real de SAP que hizo la
|
|
-- transacción — confirmado equivalente en HANA (CURRENT_USER, ver
|
|
-- sp-webhook-capture-event-hana.sql). Ninguno de los 5 parámetros que
|
|
-- recibe el hook trae ese dato, así que por ahora el campo queda sin
|
|
-- poblar en las dos variantes.
|
|
--
|
|
-- Name: en una UserTable de SAP, "Name" también debe ser único (no solo
|
|
-- "Code") — confirmado contra Service Layer real (ODBC -2035 al repetir
|
|
-- un Name, con Code distinto). Por eso Name usa el mismo UUID que Code:
|
|
-- cualquier otro valor (como el propio ObjectType) se repite entre
|
|
-- eventos del mismo tipo y hace fallar el INSERT en el segundo evento
|
|
-- (en silencio, por el TRY/CATCH).
|
|
--
|
|
-- Eco de nuestras propias escrituras: cualquier POST/PATCH/DELETE que
|
|
-- hace el dispatcher sobre @OEVC/@EVC1/@OEVN/@EVN1 vía Service Layer
|
|
-- dispara este mismo hook de nuevo, con un ObjectType especial de SAP
|
|
-- para "operación genérica sobre una UserTable simple": un código
|
|
-- negativo + tab + nombre físico de la tabla (confirmado real:
|
|
-- "-3\t@OEVN" para un DELETE). Si insertáramos esa fila iba a generar
|
|
-- otro eco al borrarla, indefinidamente — por eso NO se inserta nada
|
|
-- cuando el ObjectType matchea ese patrón para una de nuestras 4 tablas
|
|
-- (ver docs/DISENO.md, hallazgo 5).
|
|
--
|
|
-- Filtro por suscripción activa: además de lo anterior, solo se inserta
|
|
-- si existe al menos una fila en @EVC1 (con su @OEVC en State='A') para
|
|
-- este ObjectType+TransType exacto. No es "lógica de negocio propia" del
|
|
-- SP — consulta la misma tabla de configuración que ya es la fuente de
|
|
-- verdad para el dispatcher, no una copia/lista fija a mantener
|
|
-- sincronizada. Evita ensuciar @OEVN con todo lo que SAP genera y a
|
|
-- nadie le interesa (en el ambiente de prueba, cientos de eventos por
|
|
-- minuto sin ninguna suscripción real).
|
|
|
|
CREATE OR ALTER PROCEDURE [dbo].[SP_Webhook_CaptureEvent]
|
|
@object_type NVARCHAR(20),
|
|
@transaction_type NCHAR(1),
|
|
@num_of_cols_in_key INT,
|
|
@list_of_key_cols_tab_del NVARCHAR(255),
|
|
@list_of_cols_val_tab_del NVARCHAR(255),
|
|
@error INT OUTPUT,
|
|
@error_message NVARCHAR(200) OUTPUT
|
|
AS
|
|
BEGIN
|
|
SET @error = 0
|
|
SET @error_message = N'Ok'
|
|
|
|
DECLARE @code NVARCHAR(36) = CONVERT(NVARCHAR(36), NEWID())
|
|
|
|
DECLARE @isOwnTableEcho BIT = CASE
|
|
WHEN @object_type LIKE '-%' + CHAR(9) + '@OEVC' THEN 1
|
|
WHEN @object_type LIKE '-%' + CHAR(9) + '@EVC1' THEN 1
|
|
WHEN @object_type LIKE '-%' + CHAR(9) + '@OEVN' THEN 1
|
|
WHEN @object_type LIKE '-%' + CHAR(9) + '@EVN1' THEN 1
|
|
ELSE 0
|
|
END
|
|
|
|
DECLARE @hasActiveSubscription BIT = CASE WHEN EXISTS (
|
|
SELECT 1
|
|
FROM [dbo].[@EVC1] f
|
|
INNER JOIN [dbo].[@OEVC] s ON s.Code = f.U_WebhookID
|
|
WHERE f.U_ObjectType = @object_type
|
|
AND f.U_TransType = @transaction_type
|
|
AND s.U_State = 'A'
|
|
) THEN 1 ELSE 0 END
|
|
|
|
-- Solo inserta si no es un eco de nuestras propias tablas (arriba) y
|
|
-- si hay una suscripción activa interesada en este ObjectType+TransType.
|
|
IF @isOwnTableEcho = 0 AND @hasActiveSubscription = 1
|
|
BEGIN
|
|
BEGIN TRY
|
|
INSERT INTO [dbo].[@OEVN] (
|
|
Code, Name,
|
|
U_SourceDB, U_Status, U_ObjectType, U_TransType,
|
|
U_FieldsInKe, U_FieldNames, U_FieldValue, U_ReplayStat
|
|
) VALUES (
|
|
@code, @code,
|
|
DB_NAME(), 'N', @object_type, @transaction_type,
|
|
@num_of_cols_in_key, @list_of_key_cols_tab_del, @list_of_cols_val_tab_del, 'N'
|
|
)
|
|
END TRY
|
|
BEGIN CATCH
|
|
SET @error = ERROR_NUMBER()
|
|
SET @error_message = LEFT(ERROR_MESSAGE(), 200)
|
|
END CATCH
|
|
END
|
|
END
|
|
GO
|