PRCUST_SET_JSON_INVOICE_DATA: Vor Konvertierung in Funktion

This commit is contained in:
2026-02-26 14:18:17 +01:00
parent 2868286356
commit 1477da92ac

View File

@@ -5,9 +5,10 @@ GO
-- [PRCUST_SET_JSON_INVOICE_DATA] -- [PRCUST_SET_JSON_INVOICE_DATA]
-- ================================================================= -- =================================================================
-- Imports invoice JSON payload into relational tables and returns -- Reads invoice data from relational tables and returns a normalized
-- normalized JSON response for all imported documents. -- JSON response matching the CreateInvoice_Request structure.
-- --
-- Parameter: @DocumentID INT = NULL (NULL = alle Dokumente)
-- Returns: RESULTSET; success/message/data -- Returns: RESULTSET; success/message/data
-- ================================================================= -- =================================================================
-- Copyright (c) 2026 by Digital Data GmbH -- Copyright (c) 2026 by Digital Data GmbH
@@ -17,29 +18,25 @@ GO
-- ================================================================= -- =================================================================
-- Creation Date / Author: 26.02.2026 / MK -- Creation Date / Author: 26.02.2026 / MK
-- Version Date / Editor: 26.02.2026 / MK -- Version Date / Editor: 26.02.2026 / MK
-- Version Number: 1.2.0.0 -- Version Number: 2.0.0.0
-- ================================================================= -- =================================================================
-- History: -- History:
-- 26.02.2026 / MK - Initial version based on JSON invoice import -- 26.02.2026 / MK - Initial version based on JSON invoice import
-- 26.02.2026 / MK - Style harmonized to PRDEX convention -- 26.02.2026 / MK - Style harmonized to PRDEX convention
-- 26.02.2026 / MK - #3 CAST(NULL AS NVARCHAR(MAX)) for consistent data type -- 26.02.2026 / MK - #3 CAST(NULL AS NVARCHAR(MAX)) for consistent data type
-- 26.02.2026 / MK - #4 RETURN @RETURN_STATUS for proper return codes -- 26.02.2026 / MK - #4 RETURN @RETURN_STATUS for proper return codes
-- 26.02.2026 / MK - #5 Defensive cursor cleanup in CATCH block
-- 26.02.2026 / MK - #7 Reject empty purchaseDocuments array
-- 26.02.2026 / MK - #12 Extended error diagnostics in CATCH -- 26.02.2026 / MK - #12 Extended error diagnostics in CATCH
-- 26.02.2026 / MK - #16 success column as BIT -- 26.02.2026 / MK - #16 success column as BIT
-- 26.02.2026 / MK - PaymentDiscountIR-Feld hinzugefügt (Request-Abgleich) -- 26.02.2026 / MK - Umstellung auf Export-Prozedur (Tabellen → JSON)
-- 26.02.2026 / MK - JSON-Ausgabe: alle Feldnamen auf camelCase umgestellt -- 26.02.2026 / MK - JSON-Ausgabe: camelCase, INCLUDE_NULL_VALUES, CreateInvoice_Request-Vorlage
-- 26.02.2026 / MK - OPENJSON WITH: explizite camelCase JSON-Pfade für Input-Parsing
CREATE OR ALTER PROCEDURE [dbo].[PRCUST_SET_JSON_INVOICE_DATA]( CREATE OR ALTER PROCEDURE [dbo].[PRCUST_SET_JSON_INVOICE_DATA](
@json NVARCHAR(MAX) @DocumentID INT = NULL
) )
AS AS
BEGIN TRY BEGIN TRY
SET NOCOUNT ON; SET NOCOUNT ON;
SET XACT_ABORT ON;
-- declare runtime vars -- declare runtime vars
DECLARE @MY_PROCEDURE_NAME NVARCHAR(128) = OBJECT_NAME(@@PROCID), DECLARE @MY_PROCEDURE_NAME NVARCHAR(128) = OBJECT_NAME(@@PROCID),
@@ -47,26 +44,18 @@ BEGIN TRY
@RETURN_STATUS_TEXT NVARCHAR(MAX) = CONCAT('START PROCEDURE [',OBJECT_NAME(@@PROCID),'] @ ',CONVERT(VARCHAR(50),GETDATE(),120)), @RETURN_STATUS_TEXT NVARCHAR(MAX) = CONCAT('START PROCEDURE [',OBJECT_NAME(@@PROCID),'] @ ',CONVERT(VARCHAR(50),GETDATE(),120)),
@RETURN_ERROR_TEXT NVARCHAR(MAX) = N''; @RETURN_ERROR_TEXT NVARCHAR(MAX) = N'';
DECLARE @doc NVARCHAR(MAX), DECLARE @output NVARCHAR(MAX);
@line NVARCHAR(MAX),
@DocumentID INT,
@LineID INT,
@output NVARCHAR(MAX);
DECLARE @docs TABLE (doc NVARCHAR(MAX));
DECLARE @lines TABLE (line NVARCHAR(MAX));
DECLARE @InsertedDocuments TABLE (DocumentID INT PRIMARY KEY);
PRINT '===================================================================================================='; PRINT '====================================================================================================';
PRINT @RETURN_STATUS_TEXT; PRINT @RETURN_STATUS_TEXT;
PRINT ''; PRINT '';
--==============================================-- Validate JSON payload --==============================================-- --==========================================-- Validate: Document exists --==========================================--
IF dbo.FN_VALIDATE_JSON_INVOICE_DATA(@json) = 0 BEGIN IF @DocumentID IS NOT NULL AND NOT EXISTS (SELECT 1 FROM dbo.PurchaseDocument WHERE DocumentID = @DocumentID) BEGIN
SET @RETURN_STATUS = 40001; SET @RETURN_STATUS = 40001;
SET @RETURN_STATUS_TEXT = N'JSON validation failed.'; SET @RETURN_STATUS_TEXT = N'Document not found.';
SET @RETURN_ERROR_TEXT = N'Ungültige JSON-Struktur.'; SET @RETURN_ERROR_TEXT = N'Kein PurchaseDocument mit DocumentID = ' + CAST(@DocumentID AS NVARCHAR(20)) + N' gefunden.';
PRINT 'ERROR: ' + @RETURN_ERROR_TEXT; PRINT 'ERROR: ' + @RETURN_ERROR_TEXT;
@@ -79,24 +68,12 @@ BEGIN TRY
END; END;
----------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------------------
PRINT 'INFO: JSON-Validierung erfolgreich.'; --========================================-- Validate: Any documents available --========================================--
IF NOT EXISTS (SELECT 1 FROM dbo.PurchaseDocument WHERE @DocumentID IS NULL OR DocumentID = @DocumentID) BEGIN
BEGIN TRANSACTION;
--===========================================-- Extract purchaseDocuments array --===========================================--
INSERT INTO @docs(doc)
SELECT [value]
FROM OPENJSON(@json, '$.purchaseDocuments');
-----------------------------------------------------------------------------------------------------------------------------------
--=========================================-- Reject empty purchaseDocuments array --==========================================--
IF NOT EXISTS (SELECT 1 FROM @docs) BEGIN
ROLLBACK TRANSACTION;
SET @RETURN_STATUS = 40002; SET @RETURN_STATUS = 40002;
SET @RETURN_STATUS_TEXT = N'Empty purchaseDocuments array.'; SET @RETURN_STATUS_TEXT = N'No documents available.';
SET @RETURN_ERROR_TEXT = N'purchaseDocuments-Array ist leer. Mindestens ein Dokument erforderlich.'; SET @RETURN_ERROR_TEXT = N'Keine PurchaseDocuments vorhanden.';
PRINT 'ERROR: ' + @RETURN_ERROR_TEXT; PRINT 'ERROR: ' + @RETURN_ERROR_TEXT;
@@ -109,286 +86,6 @@ BEGIN TRY
END; END;
----------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------------------
DECLARE doc_cursor CURSOR LOCAL FAST_FORWARD FOR SELECT doc FROM @docs;
OPEN doc_cursor;
FETCH NEXT FROM doc_cursor INTO @doc;
WHILE @@FETCH_STATUS = 0 BEGIN
PRINT 'INFO: Füge PurchaseDocument ein...';
--=============================================-- Insert PurchaseDocument row --=============================================--
INSERT INTO dbo.PurchaseDocument (
DocumentType
, No_
, NoSeries
, ProcessIDTransfer
, BuyFromVendorNo
, PayToVendorNo
, PostingDate
, PaymentTermsCode
, PaymentTermsCodeIR
, DueDate
, PmtDiscountDate
, PaymentDiscount
, PaymentDiscountIR
, CurrencyCode
, InvoiceDiscCode
, PostingDescription
, PaymentMethodCode
, VendorInvoiceNo
, VendorCrMemoNo
, PhrVendorBankAccountCode
, PhrBankBranchNo
, PhrBankAccountNo
, PhrIBAN
, PhrSWIFTCode
, PhrBankName
, PhrBankAccountEntryPriority
, PhrRMCashDiscountReceived
, PhrRMAmountIncludingVAT
, PhrRMAmountLessDiscount
)
SELECT
DocumentType
, No
, NoSeries
, ProcessIDTransfer
, BuyFromVendorNo
, PayToVendorNo
, PostingDate
, PaymentTermsCode
, PaymentTermsCodeIR
, DueDate
, PmtDiscountDate
, PaymentDiscount
, PaymentDiscountIR
, CurrencyCode
, InvoiceDiscCode
, PostingDescription
, PaymentMethodCode
, VendorInvoiceNo
, VendorCrMemoNo
, PhrVendorBankAccountCode
, PhrBankBranchNo
, PhrBankAccountNo
, PhrIBAN
, PhrSWIFTCode
, PhrBankName
, PhrBankAccountEntryPriority
, PhrRMCashDiscountReceived
, PhrRMAmountIncludingVAT
, PhrRMAmountLessDiscount
FROM OPENJSON(@doc)
WITH (
DocumentType INT '$.documentType'
, No NVARCHAR(50) '$.no'
, NoSeries NVARCHAR(50) '$.noSeries'
, ProcessIDTransfer NVARCHAR(50) '$.processIDTransfer'
, BuyFromVendorNo NVARCHAR(50) '$.buyFromVendorNo'
, PayToVendorNo NVARCHAR(50) '$.payToVendorNo'
, PostingDate DATE '$.postingDate'
, PaymentTermsCode NVARCHAR(20) '$.paymentTermsCode'
, PaymentTermsCodeIR NVARCHAR(20) '$.paymentTermsCodeIR'
, DueDate DATE '$.dueDate'
, PmtDiscountDate DATE '$.pmtDiscountDate'
, PaymentDiscount DECIMAL(10,2) '$.paymentDiscount'
, PaymentDiscountIR DECIMAL(10,2) '$.paymentDiscountIR'
, CurrencyCode NVARCHAR(10) '$.currencyCode'
, InvoiceDiscCode NVARCHAR(50) '$.invoiceDiscCode'
, PostingDescription NVARCHAR(250) '$.postingDescription'
, PaymentMethodCode NVARCHAR(20) '$.paymentMethodCode'
, VendorInvoiceNo NVARCHAR(50) '$.vendorInvoiceNo'
, VendorCrMemoNo NVARCHAR(50) '$.vendorCrMemoNo'
, PhrVendorBankAccountCode NVARCHAR(50) '$.phrVendorBankAccountCode'
, PhrBankBranchNo NVARCHAR(50) '$.phrBankBranchNo'
, PhrBankAccountNo NVARCHAR(50) '$.phrBankAccountNo'
, PhrIBAN NVARCHAR(50) '$.phrIBAN'
, PhrSWIFTCode NVARCHAR(50) '$.phrSWIFTCode'
, PhrBankName NVARCHAR(100) '$.phrBankName'
, PhrBankAccountEntryPriority BIT '$.phrBankAccountEntryPriority'
, PhrRMCashDiscountReceived BIT '$.phrRMCashDiscountReceived'
, PhrRMAmountIncludingVAT DECIMAL(18,2) '$.phrRMAmountIncludingVAT'
, PhrRMAmountLessDiscount DECIMAL(18,2) '$.phrRMAmountLessDiscount'
, purchaseLines NVARCHAR(MAX) AS JSON
);
-----------------------------------------------------------------------------------------------------------------------------------
SET @DocumentID = SCOPE_IDENTITY();
INSERT INTO @InsertedDocuments (DocumentID) VALUES (@DocumentID);
PRINT 'INFO: PurchaseDocument eingefügt. DocumentID = ' + CAST(@DocumentID AS NVARCHAR(20));
--=============================================-- Extract purchaseLines array --==============================================--
DELETE FROM @lines;
INSERT INTO @lines(line)
SELECT [value]
FROM OPENJSON(@doc, '$.purchaseLines');
-----------------------------------------------------------------------------------------------------------------------------------
DECLARE line_cursor CURSOR LOCAL FAST_FORWARD FOR SELECT line FROM @lines;
OPEN line_cursor;
FETCH NEXT FROM line_cursor INTO @line;
WHILE @@FETCH_STATUS = 0 BEGIN
PRINT 'INFO: Füge PurchaseLine ein...';
INSERT INTO dbo.PurchaseLine (
DocumentID
, AttachedToLineNo
, Type
, No_
, Description
, Description2
, LocationCode
, VariantCode
, Quantity
, UnitOfMeasureCode
, DirectUnitCost
, LineDiscount
, AbleToDiscount
, DiscountCalculated
, WorkOrderNo
, GenBusPostingGroup
, GenProdPostingGroup
, VatBusPostingGroup
, VatProdPostingGroup
, ApplToItemEntry
, PostingWithoutApply
, AnticipatedPayment
, ReceiptNo
, ReceiptLineNo
, IrOrderNo
, IrOrderLineNo
)
SELECT
@DocumentID
, AttachedToLineNo
, Type
, No
, Description
, Description2
, LocationCode
, VariantCode
, Quantity
, UnitOfMeasureCode
, DirectUnitCost
, LineDiscount
, AbleToDiscount
, DiscountCalculated
, WorkOrderNo
, GenBusPostingGroup
, GenProdPostingGroup
, VatBusPostingGroup
, VatProdPostingGroup
, ApplToItemEntry
, PostingWithoutApply
, AnticipatedPayment
, ReceiptNo
, ReceiptLineNo
, IrOrderNo
, IrOrderLineNo
FROM OPENJSON(@line)
WITH (
AttachedToLineNo INT '$.attachedToLineNo'
, Type INT '$.type'
, No NVARCHAR(50) '$.no'
, Description NVARCHAR(250) '$.description'
, Description2 NVARCHAR(250) '$.description2'
, LocationCode NVARCHAR(50) '$.locationCode'
, VariantCode NVARCHAR(50) '$.variantCode'
, Quantity DECIMAL(18,4) '$.quantity'
, UnitOfMeasureCode NVARCHAR(20) '$.unitOfMeasureCode'
, DirectUnitCost DECIMAL(18,4) '$.directUnitCost'
, LineDiscount DECIMAL(18,4) '$.lineDiscount'
, AbleToDiscount BIT '$.ableToDiscount'
, DiscountCalculated BIT '$.discountCalculated'
, WorkOrderNo NVARCHAR(50) '$.workOrderNo'
, GenBusPostingGroup NVARCHAR(20) '$.genBusPostingGroup'
, GenProdPostingGroup NVARCHAR(20) '$.genProdPostingGroup'
, VatBusPostingGroup NVARCHAR(20) '$.vatBusPostingGroup'
, VatProdPostingGroup NVARCHAR(20) '$.vatProdPostingGroup'
, ApplToItemEntry INT '$.applToItemEntry'
, PostingWithoutApply BIT '$.postingWithoutApply'
, AnticipatedPayment DECIMAL(18,2) '$.anticipatedPayment'
, ReceiptNo NVARCHAR(50) '$.receiptNo'
, ReceiptLineNo INT '$.receiptLineNo'
, IrOrderNo NVARCHAR(50) '$.irOrderNo'
, IrOrderLineNo INT '$.irOrderLineNo'
, dimSetEntries NVARCHAR(MAX) AS JSON
, itemChargeAssignmentLines NVARCHAR(MAX) AS JSON
);
SET @LineID = SCOPE_IDENTITY();
PRINT 'INFO: PurchaseLine eingefügt. LineID = ' + CAST(@LineID AS NVARCHAR(20));
--===============================================-- Insert dimSetEntries --===============================================--
INSERT INTO dbo.DimSetEntry (LineID, DimensionCode, DimensionValueCode)
SELECT @LineID, DimensionCode, DimensionValueCode
FROM OPENJSON(@line, '$.dimSetEntries')
WITH (
DimensionCode NVARCHAR(50) '$.dimensionCode'
, DimensionValueCode NVARCHAR(50) '$.dimensionValueCode'
);
-----------------------------------------------------------------------------------------------------------------------------------
--=========================================-- Insert itemChargeAssignmentLines --==========================================--
INSERT INTO dbo.ItemChargeAssignment (
LineID
, ItemChargeNo
, UnitCost
, AppliesToDocType
, AppliesToDocNo
, AppliesToDocLineNo
, ItemNo
, Description
, QtyToAssign
, QtyAssigned
, AmountToAssign
, AppliesToDocLineAmount
)
SELECT
@LineID
, ItemChargeNo
, UnitCost
, AppliesToDocType
, AppliesToDocNo
, AppliesToDocLineNo
, ItemNo
, Description
, QtyToAssign
, QtyAssigned
, AmountToAssign
, AppliesToDocLineAmount
FROM OPENJSON(@line, '$.itemChargeAssignmentLines')
WITH (
ItemChargeNo NVARCHAR(50) '$.itemChargeNo'
, UnitCost DECIMAL(18,4) '$.unitCost'
, AppliesToDocType INT '$.appliesToDocType'
, AppliesToDocNo NVARCHAR(50) '$.appliesToDocNo'
, AppliesToDocLineNo INT '$.appliesToDocLineNo'
, ItemNo NVARCHAR(50) '$.itemNo'
, Description NVARCHAR(250) '$.description'
, QtyToAssign DECIMAL(18,4) '$.qtyToAssign'
, QtyAssigned DECIMAL(18,4) '$.qtyAssigned'
, AmountToAssign DECIMAL(18,4) '$.amountToAssign'
, AppliesToDocLineAmount DECIMAL(18,4) '$.appliesToDocLineAmount'
);
-----------------------------------------------------------------------------------------------------------------------------------
FETCH NEXT FROM line_cursor INTO @line;
END;
CLOSE line_cursor;
DEALLOCATE line_cursor;
FETCH NEXT FROM doc_cursor INTO @doc;
END;
CLOSE doc_cursor;
DEALLOCATE doc_cursor;
PRINT 'INFO: Erzeuge JSON-Ausgabe...'; PRINT 'INFO: Erzeuge JSON-Ausgabe...';
--===============================================-- Build output JSON result --===============================================-- --===============================================-- Build output JSON result --===============================================--
@@ -465,7 +162,7 @@ BEGIN TRY
, [dimensionValueCode] = d.DimensionValueCode , [dimensionValueCode] = d.DimensionValueCode
FROM dbo.DimSetEntry d FROM dbo.DimSetEntry d
WHERE d.LineID = pl.LineID WHERE d.LineID = pl.LineID
FOR JSON PATH FOR JSON PATH, INCLUDE_NULL_VALUES
) )
, '[]' , '[]'
) )
@@ -487,22 +184,22 @@ BEGIN TRY
, [appliesToDocLineAmount] = ia.AppliesToDocLineAmount , [appliesToDocLineAmount] = ia.AppliesToDocLineAmount
FROM dbo.ItemChargeAssignment ia FROM dbo.ItemChargeAssignment ia
WHERE ia.LineID = pl.LineID WHERE ia.LineID = pl.LineID
FOR JSON PATH FOR JSON PATH, INCLUDE_NULL_VALUES
) )
, '[]' , '[]'
) )
) )
FROM dbo.PurchaseLine pl FROM dbo.PurchaseLine pl
WHERE pl.DocumentID = pd.DocumentID WHERE pl.DocumentID = pd.DocumentID
FOR JSON PATH FOR JSON PATH, INCLUDE_NULL_VALUES
) )
, '[]' , '[]'
) )
) )
FROM dbo.PurchaseDocument pd FROM dbo.PurchaseDocument pd
INNER JOIN @InsertedDocuments id ON id.DocumentID = pd.DocumentID WHERE @DocumentID IS NULL OR pd.DocumentID = @DocumentID
ORDER BY pd.DocumentID ORDER BY pd.DocumentID
FOR JSON PATH FOR JSON PATH, INCLUDE_NULL_VALUES
) )
, '[]' , '[]'
) )
@@ -511,8 +208,6 @@ BEGIN TRY
); );
----------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------------------------------------------
COMMIT TRANSACTION;
SET @RETURN_STATUS = 0; SET @RETURN_STATUS = 0;
SET @RETURN_STATUS_TEXT = CONCAT('END PROCEDURE [',@MY_PROCEDURE_NAME,'] @ ',CONVERT(NVARCHAR(50),GETDATE(),120)); SET @RETURN_STATUS_TEXT = CONCAT('END PROCEDURE [',@MY_PROCEDURE_NAME,'] @ ',CONVERT(NVARCHAR(50),GETDATE(),120));
@@ -531,22 +226,6 @@ END TRY BEGIN CATCH
--====================================================-- exception / error --====================================================-- --====================================================-- exception / error --====================================================--
-- defensive cursor cleanup
IF CURSOR_STATUS('local','line_cursor') >= -1 BEGIN
IF CURSOR_STATUS('local','line_cursor') >= 0
CLOSE line_cursor;
DEALLOCATE line_cursor;
END;
IF CURSOR_STATUS('local','doc_cursor') >= -1 BEGIN
IF CURSOR_STATUS('local','doc_cursor') >= 0
CLOSE doc_cursor;
DEALLOCATE doc_cursor;
END;
IF (@@TRANCOUNT > 0) BEGIN
ROLLBACK TRANSACTION;
END;
SET @RETURN_STATUS = 50000; SET @RETURN_STATUS = 50000;
SET @RETURN_STATUS_TEXT = CONCAT('END PROCEDURE [',OBJECT_NAME(@@PROCID),'] @ ',CONVERT(NVARCHAR(50),GETDATE(),120)); SET @RETURN_STATUS_TEXT = CONCAT('END PROCEDURE [',OBJECT_NAME(@@PROCID),'] @ ',CONVERT(NVARCHAR(50),GETDATE(),120));
SET @RETURN_ERROR_TEXT = CONCAT('ERR ',ERROR_NUMBER(),' SEV ',ERROR_SEVERITY(),' STATE ',ERROR_STATE(),' LINE ',ERROR_LINE(),': ',ERROR_MESSAGE()); SET @RETURN_ERROR_TEXT = CONCAT('ERR ',ERROR_NUMBER(),' SEV ',ERROR_SEVERITY(),' STATE ',ERROR_STATE(),' LINE ',ERROR_LINE(),': ',ERROR_MESSAGE());