diff --git a/SWESQL/SQL-Server/Prozeduren/[PRCUST_SET_JSON_INVOICE_DATA].sql b/SWESQL/SQL-Server/Prozeduren/[PRCUST_SET_JSON_INVOICE_DATA].sql index 1114e11..bda272e 100644 --- a/SWESQL/SQL-Server/Prozeduren/[PRCUST_SET_JSON_INVOICE_DATA].sql +++ b/SWESQL/SQL-Server/Prozeduren/[PRCUST_SET_JSON_INVOICE_DATA].sql @@ -5,10 +5,11 @@ GO -- [PRCUST_SET_JSON_INVOICE_DATA] -- ================================================================= --- Imports invoice JSON payload into relational tables and returns --- normalized JSON response for all imported documents. --- --- Returns: RESULTSET; success/message/data +-- Reads invoice data from relational tables and returns a normalized +-- JSON response matching the CreateInvoice_Request structure. +-- +-- Parameter: @DocumentID INT = NULL (NULL = alle Dokumente) +-- Returns: RESULTSET; success/message/data -- ================================================================= -- Copyright (c) 2026 by Digital Data GmbH -- @@ -17,56 +18,44 @@ GO -- ================================================================= -- Creation Date / Author: 26.02.2026 / MK -- Version Date / Editor: 26.02.2026 / MK --- Version Number: 1.2.0.0 +-- Version Number: 2.0.0.0 -- ================================================================= -- History: -- 26.02.2026 / MK - Initial version based on JSON invoice import -- 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 - #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 - #16 success column as BIT --- 26.02.2026 / MK - PaymentDiscountIR-Feld hinzugefügt (Request-Abgleich) --- 26.02.2026 / MK - JSON-Ausgabe: alle Feldnamen auf camelCase umgestellt --- 26.02.2026 / MK - OPENJSON WITH: explizite camelCase JSON-Pfade für Input-Parsing +-- 26.02.2026 / MK - Umstellung auf Export-Prozedur (Tabellen → JSON) +-- 26.02.2026 / MK - JSON-Ausgabe: camelCase, INCLUDE_NULL_VALUES, CreateInvoice_Request-Vorlage CREATE OR ALTER PROCEDURE [dbo].[PRCUST_SET_JSON_INVOICE_DATA]( - @json NVARCHAR(MAX) + @DocumentID INT = NULL ) AS BEGIN TRY SET NOCOUNT ON; - SET XACT_ABORT ON; -- declare runtime vars DECLARE @MY_PROCEDURE_NAME NVARCHAR(128) = OBJECT_NAME(@@PROCID), - @RETURN_STATUS INT = 0, + @RETURN_STATUS INT = 0, @RETURN_STATUS_TEXT NVARCHAR(MAX) = CONCAT('START PROCEDURE [',OBJECT_NAME(@@PROCID),'] @ ',CONVERT(VARCHAR(50),GETDATE(),120)), @RETURN_ERROR_TEXT NVARCHAR(MAX) = N''; - DECLARE @doc 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); + DECLARE @output NVARCHAR(MAX); PRINT '===================================================================================================='; PRINT @RETURN_STATUS_TEXT; PRINT ''; - --==============================================-- Validate JSON payload --==============================================-- - IF dbo.FN_VALIDATE_JSON_INVOICE_DATA(@json) = 0 BEGIN + --==========================================-- Validate: Document exists --==========================================-- + IF @DocumentID IS NOT NULL AND NOT EXISTS (SELECT 1 FROM dbo.PurchaseDocument WHERE DocumentID = @DocumentID) BEGIN SET @RETURN_STATUS = 40001; - SET @RETURN_STATUS_TEXT = N'JSON validation failed.'; - SET @RETURN_ERROR_TEXT = N'Ungültige JSON-Struktur.'; + SET @RETURN_STATUS_TEXT = N'Document not found.'; + SET @RETURN_ERROR_TEXT = N'Kein PurchaseDocument mit DocumentID = ' + CAST(@DocumentID AS NVARCHAR(20)) + N' gefunden.'; PRINT 'ERROR: ' + @RETURN_ERROR_TEXT; @@ -79,24 +68,12 @@ BEGIN TRY END; ----------------------------------------------------------------------------------------------------------------------------------- - PRINT 'INFO: JSON-Validierung erfolgreich.'; - - 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; + --========================================-- Validate: Any documents available --========================================-- + IF NOT EXISTS (SELECT 1 FROM dbo.PurchaseDocument WHERE @DocumentID IS NULL OR DocumentID = @DocumentID) BEGIN SET @RETURN_STATUS = 40002; - SET @RETURN_STATUS_TEXT = N'Empty purchaseDocuments array.'; - SET @RETURN_ERROR_TEXT = N'purchaseDocuments-Array ist leer. Mindestens ein Dokument erforderlich.'; + SET @RETURN_STATUS_TEXT = N'No documents available.'; + SET @RETURN_ERROR_TEXT = N'Keine PurchaseDocuments vorhanden.'; PRINT 'ERROR: ' + @RETURN_ERROR_TEXT; @@ -109,286 +86,6 @@ BEGIN TRY 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...'; --===============================================-- Build output JSON result --===============================================-- @@ -465,7 +162,7 @@ BEGIN TRY , [dimensionValueCode] = d.DimensionValueCode FROM dbo.DimSetEntry d WHERE d.LineID = pl.LineID - FOR JSON PATH + FOR JSON PATH, INCLUDE_NULL_VALUES ) , '[]' ) @@ -487,22 +184,22 @@ BEGIN TRY , [appliesToDocLineAmount] = ia.AppliesToDocLineAmount FROM dbo.ItemChargeAssignment ia WHERE ia.LineID = pl.LineID - FOR JSON PATH + FOR JSON PATH, INCLUDE_NULL_VALUES ) , '[]' ) ) FROM dbo.PurchaseLine pl WHERE pl.DocumentID = pd.DocumentID - FOR JSON PATH + FOR JSON PATH, INCLUDE_NULL_VALUES ) , '[]' ) ) 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 - FOR JSON PATH + FOR JSON PATH, INCLUDE_NULL_VALUES ) , '[]' ) @@ -511,8 +208,6 @@ BEGIN TRY ); ----------------------------------------------------------------------------------------------------------------------------------- - COMMIT TRANSACTION; - SET @RETURN_STATUS = 0; 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 --====================================================-- - -- 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_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());