FNCUST_GET_JSON_INVOICE_DATA: Erste Tabellenfunktion

This commit is contained in:
2026-02-26 14:24:18 +01:00
parent 1477da92ac
commit 1f4d919a0f

View File

@@ -3,13 +3,15 @@ GO
SET QUOTED_IDENTIFIER ON SET QUOTED_IDENTIFIER ON
GO GO
-- [PRCUST_SET_JSON_INVOICE_DATA] -- [FNCUST_GET_JSON_INVOICE_DATA]
-- ================================================================= -- =================================================================
-- Reads invoice data from relational tables and returns a normalized -- Reads invoice data from relational tables and returns a normalized
-- JSON response matching the CreateInvoice_Request structure. -- JSON response matching the CreateInvoice_Request structure.
-- --
-- Parameter: @DocumentID INT = NULL (NULL = alle Dokumente) -- Parameter: @DocumentID INT = NULL (NULL = alle Dokumente)
-- Returns: RESULTSET; success/message/data -- Returns: TABLE (success BIT, message NVARCHAR(MAX), data NVARCHAR(MAX))
-- Usage: SELECT * FROM dbo.FNCUST_GET_JSON_INVOICE_DATA(NULL)
-- SELECT * FROM dbo.FNCUST_GET_JSON_INVOICE_DATA(42)
-- ================================================================= -- =================================================================
-- Copyright (c) 2026 by Digital Data GmbH -- Copyright (c) 2026 by Digital Data GmbH
-- --
@@ -18,229 +20,169 @@ 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: 2.0.0.0 -- Version Number: 3.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 - #4 RETURN @RETURN_STATUS for proper return codes
-- 26.02.2026 / MK - #12 Extended error diagnostics in CATCH
-- 26.02.2026 / MK - #16 success column as BIT
-- 26.02.2026 / MK - Umstellung auf Export-Prozedur (Tabellen → JSON) -- 26.02.2026 / MK - Umstellung auf Export-Prozedur (Tabellen → JSON)
-- 26.02.2026 / MK - JSON-Ausgabe: camelCase, INCLUDE_NULL_VALUES, CreateInvoice_Request-Vorlage -- 26.02.2026 / MK - JSON-Ausgabe: camelCase, INCLUDE_NULL_VALUES, CreateInvoice_Request-Vorlage
-- 26.02.2026 / MK - Umbau zu Inline-Tabellenwertfunktion (ITVF)
CREATE OR ALTER PROCEDURE [dbo].[PRCUST_SET_JSON_INVOICE_DATA]( CREATE OR ALTER FUNCTION [dbo].[FNCUST_GET_JSON_INVOICE_DATA](
@DocumentID INT = NULL @DocumentID INT = NULL
) )
RETURNS TABLE
AS AS
BEGIN TRY RETURN
(
SELECT
--==== success ====--
success = CAST(IIF(v.status = 0, 1, 0) AS BIT)
SET NOCOUNT ON; --==== message ====--
, message = CAST(
CASE v.status
WHEN 1 THEN N'Kein PurchaseDocument mit DocumentID = ' + CAST(@DocumentID AS NVARCHAR(20)) + N' gefunden.'
WHEN 2 THEN N'Keine PurchaseDocuments vorhanden.'
ELSE N'Daten erfolgreich verarbeitet.'
END
AS NVARCHAR(MAX))
-- declare runtime vars --==== data ====--
DECLARE @MY_PROCEDURE_NAME NVARCHAR(128) = OBJECT_NAME(@@PROCID), , data = CAST(
@RETURN_STATUS INT = 0, CASE WHEN v.status > 0 THEN NULL
@RETURN_STATUS_TEXT NVARCHAR(MAX) = CONCAT('START PROCEDURE [',OBJECT_NAME(@@PROCID),'] @ ',CONVERT(VARCHAR(50),GETDATE(),120)), ELSE (
@RETURN_ERROR_TEXT NVARCHAR(MAX) = N''; --===============================================-- Build output JSON result --===============================================--
SELECT
DECLARE @output NVARCHAR(MAX); JSON_QUERY(
COALESCE(
PRINT '===================================================================================================='; (
PRINT @RETURN_STATUS_TEXT; SELECT
PRINT ''; [documentType] = pd.DocumentType
, [no] = pd.No_
--==========================================-- Validate: Document exists --==========================================-- , [noSeries] = pd.NoSeries
IF @DocumentID IS NOT NULL AND NOT EXISTS (SELECT 1 FROM dbo.PurchaseDocument WHERE DocumentID = @DocumentID) BEGIN , [processIDTransfer] = pd.ProcessIDTransfer
, [buyFromVendorNo] = pd.BuyFromVendorNo
SET @RETURN_STATUS = 40001; , [payToVendorNo] = pd.PayToVendorNo
SET @RETURN_STATUS_TEXT = N'Document not found.'; , [postingDate] = pd.PostingDate
SET @RETURN_ERROR_TEXT = N'Kein PurchaseDocument mit DocumentID = ' + CAST(@DocumentID AS NVARCHAR(20)) + N' gefunden.'; , [paymentTermsCode] = pd.PaymentTermsCode
, [paymentTermsCodeIR] = pd.PaymentTermsCodeIR
PRINT 'ERROR: ' + @RETURN_ERROR_TEXT; , [dueDate] = pd.DueDate
, [pmtDiscountDate] = pd.PmtDiscountDate
SELECT , [paymentDiscount] = pd.PaymentDiscount
success = CAST(0 AS BIT) , [paymentDiscountIR] = pd.PaymentDiscountIR
, message = @RETURN_ERROR_TEXT , [currencyCode] = pd.CurrencyCode
, data = CAST(NULL AS NVARCHAR(MAX)); , [invoiceDiscCode] = pd.InvoiceDiscCode
, [postingDescription] = pd.PostingDescription
RETURN @RETURN_STATUS; , [paymentMethodCode] = pd.PaymentMethodCode
END; , [vendorInvoiceNo] = pd.VendorInvoiceNo
----------------------------------------------------------------------------------------------------------------------------------- , [vendorCrMemoNo] = pd.VendorCrMemoNo
, [phrVendorBankAccountCode] = pd.PhrVendorBankAccountCode
--========================================-- Validate: Any documents available --========================================-- , [phrBankBranchNo] = pd.PhrBankBranchNo
IF NOT EXISTS (SELECT 1 FROM dbo.PurchaseDocument WHERE @DocumentID IS NULL OR DocumentID = @DocumentID) BEGIN , [phrBankAccountNo] = pd.PhrBankAccountNo
, [phrIBAN] = pd.PhrIBAN
SET @RETURN_STATUS = 40002; , [phrSWIFTCode] = pd.PhrSWIFTCode
SET @RETURN_STATUS_TEXT = N'No documents available.'; , [phrBankName] = pd.PhrBankName
SET @RETURN_ERROR_TEXT = N'Keine PurchaseDocuments vorhanden.'; , [phrBankAccountEntryPriority] = pd.PhrBankAccountEntryPriority
, [phrRMCashDiscountReceived] = pd.PhrRMCashDiscountReceived
PRINT 'ERROR: ' + @RETURN_ERROR_TEXT; , [phrRMAmountIncludingVAT] = pd.PhrRMAmountIncludingVAT
, [phrRMAmountLessDiscount] = pd.PhrRMAmountLessDiscount
SELECT , purchaseLines = JSON_QUERY(
success = CAST(0 AS BIT) COALESCE(
, message = @RETURN_ERROR_TEXT (
, data = CAST(NULL AS NVARCHAR(MAX)); SELECT
[attachedToLineNo] = pl.AttachedToLineNo
RETURN @RETURN_STATUS; , [type] = pl.Type
END; , [no] = pl.No_
----------------------------------------------------------------------------------------------------------------------------------- , [description] = pl.Description
, [description2] = pl.Description2
PRINT 'INFO: Erzeuge JSON-Ausgabe...'; , [locationCode] = pl.LocationCode
, [variantCode] = pl.VariantCode
--===============================================-- Build output JSON result --===============================================-- , [quantity] = pl.Quantity
SELECT @output = , [unitOfMeasureCode] = pl.UnitOfMeasureCode
( , [directUnitCost] = pl.DirectUnitCost
SELECT , [lineDiscount] = pl.LineDiscount
JSON_QUERY( , [ableToDiscount] = pl.AbleToDiscount
COALESCE( , [discountCalculated] = pl.DiscountCalculated
( , [workOrderNo] = pl.WorkOrderNo
SELECT , [genBusPostingGroup] = pl.GenBusPostingGroup
[documentType] = pd.DocumentType , [genProdPostingGroup] = pl.GenProdPostingGroup
, [no] = pd.No_ , [vatBusPostingGroup] = pl.VatBusPostingGroup
, [noSeries] = pd.NoSeries , [vatProdPostingGroup] = pl.VatProdPostingGroup
, [processIDTransfer] = pd.ProcessIDTransfer , [applToItemEntry] = pl.ApplToItemEntry
, [buyFromVendorNo] = pd.BuyFromVendorNo , [postingWithoutApply] = pl.PostingWithoutApply
, [payToVendorNo] = pd.PayToVendorNo , [anticipatedPayment] = pl.AnticipatedPayment
, [postingDate] = pd.PostingDate , [receiptNo] = pl.ReceiptNo
, [paymentTermsCode] = pd.PaymentTermsCode , [receiptLineNo] = pl.ReceiptLineNo
, [paymentTermsCodeIR] = pd.PaymentTermsCodeIR , [irOrderNo] = pl.IrOrderNo
, [dueDate] = pd.DueDate , [irOrderLineNo] = pl.IrOrderLineNo
, [pmtDiscountDate] = pd.PmtDiscountDate , dimSetEntries = JSON_QUERY(
, [paymentDiscount] = pd.PaymentDiscount COALESCE(
, [paymentDiscountIR] = pd.PaymentDiscountIR (
, [currencyCode] = pd.CurrencyCode SELECT
, [invoiceDiscCode] = pd.InvoiceDiscCode [dimensionCode] = d.DimensionCode
, [postingDescription] = pd.PostingDescription , [dimensionValueCode] = d.DimensionValueCode
, [paymentMethodCode] = pd.PaymentMethodCode FROM dbo.DimSetEntry d
, [vendorInvoiceNo] = pd.VendorInvoiceNo WHERE d.LineID = pl.LineID
, [vendorCrMemoNo] = pd.VendorCrMemoNo FOR JSON PATH, INCLUDE_NULL_VALUES
, [phrVendorBankAccountCode] = pd.PhrVendorBankAccountCode )
, [phrBankBranchNo] = pd.PhrBankBranchNo , '[]'
, [phrBankAccountNo] = pd.PhrBankAccountNo )
, [phrIBAN] = pd.PhrIBAN
, [phrSWIFTCode] = pd.PhrSWIFTCode
, [phrBankName] = pd.PhrBankName
, [phrBankAccountEntryPriority] = pd.PhrBankAccountEntryPriority
, [phrRMCashDiscountReceived] = pd.PhrRMCashDiscountReceived
, [phrRMAmountIncludingVAT] = pd.PhrRMAmountIncludingVAT
, [phrRMAmountLessDiscount] = pd.PhrRMAmountLessDiscount
, purchaseLines = JSON_QUERY(
COALESCE(
(
SELECT
[attachedToLineNo] = pl.AttachedToLineNo
, [type] = pl.Type
, [no] = pl.No_
, [description] = pl.Description
, [description2] = pl.Description2
, [locationCode] = pl.LocationCode
, [variantCode] = pl.VariantCode
, [quantity] = pl.Quantity
, [unitOfMeasureCode] = pl.UnitOfMeasureCode
, [directUnitCost] = pl.DirectUnitCost
, [lineDiscount] = pl.LineDiscount
, [ableToDiscount] = pl.AbleToDiscount
, [discountCalculated] = pl.DiscountCalculated
, [workOrderNo] = pl.WorkOrderNo
, [genBusPostingGroup] = pl.GenBusPostingGroup
, [genProdPostingGroup] = pl.GenProdPostingGroup
, [vatBusPostingGroup] = pl.VatBusPostingGroup
, [vatProdPostingGroup] = pl.VatProdPostingGroup
, [applToItemEntry] = pl.ApplToItemEntry
, [postingWithoutApply] = pl.PostingWithoutApply
, [anticipatedPayment] = pl.AnticipatedPayment
, [receiptNo] = pl.ReceiptNo
, [receiptLineNo] = pl.ReceiptLineNo
, [irOrderNo] = pl.IrOrderNo
, [irOrderLineNo] = pl.IrOrderLineNo
, dimSetEntries = JSON_QUERY(
COALESCE(
(
SELECT
[dimensionCode] = d.DimensionCode
, [dimensionValueCode] = d.DimensionValueCode
FROM dbo.DimSetEntry d
WHERE d.LineID = pl.LineID
FOR JSON PATH, INCLUDE_NULL_VALUES
) )
, '[]' , itemChargeAssignmentLines = JSON_QUERY(
) COALESCE(
) (
, itemChargeAssignmentLines = JSON_QUERY( SELECT
COALESCE( [itemChargeNo] = ia.ItemChargeNo
( , [unitCost] = ia.UnitCost
SELECT , [appliesToDocType] = ia.AppliesToDocType
[itemChargeNo] = ia.ItemChargeNo , [appliesToDocNo] = ia.AppliesToDocNo
, [unitCost] = ia.UnitCost , [appliesToDocLineNo] = ia.AppliesToDocLineNo
, [appliesToDocType] = ia.AppliesToDocType , [itemNo] = ia.ItemNo
, [appliesToDocNo] = ia.AppliesToDocNo , [description] = ia.Description
, [appliesToDocLineNo] = ia.AppliesToDocLineNo , [qtyToAssign] = ia.QtyToAssign
, [itemNo] = ia.ItemNo , [qtyAssigned] = ia.QtyAssigned
, [description] = ia.Description , [amountToAssign] = ia.AmountToAssign
, [qtyToAssign] = ia.QtyToAssign , [appliesToDocLineAmount] = ia.AppliesToDocLineAmount
, [qtyAssigned] = ia.QtyAssigned FROM dbo.ItemChargeAssignment ia
, [amountToAssign] = ia.AmountToAssign WHERE ia.LineID = pl.LineID
, [appliesToDocLineAmount] = ia.AppliesToDocLineAmount FOR JSON PATH, INCLUDE_NULL_VALUES
FROM dbo.ItemChargeAssignment ia )
WHERE ia.LineID = pl.LineID , '[]'
FOR JSON PATH, INCLUDE_NULL_VALUES )
) )
, '[]' FROM dbo.PurchaseLine pl
) WHERE pl.DocumentID = pd.DocumentID
FOR JSON PATH, INCLUDE_NULL_VALUES
) )
FROM dbo.PurchaseLine pl , '[]'
WHERE pl.DocumentID = pd.DocumentID )
FOR JSON PATH, INCLUDE_NULL_VALUES
) )
, '[]' FROM dbo.PurchaseDocument pd
) WHERE @DocumentID IS NULL OR pd.DocumentID = @DocumentID
ORDER BY pd.DocumentID
FOR JSON PATH, INCLUDE_NULL_VALUES
) )
FROM dbo.PurchaseDocument pd , '[]'
WHERE @DocumentID IS NULL OR pd.DocumentID = @DocumentID )
ORDER BY pd.DocumentID ) AS purchaseDocuments
FOR JSON PATH, INCLUDE_NULL_VALUES FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) -----------------------------------------------------------------------------------------------------------------------------------
, '[]' )
) END
) AS purchaseDocuments AS NVARCHAR(MAX))
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
);
-----------------------------------------------------------------------------------------------------------------------------------
SET @RETURN_STATUS = 0; FROM (VALUES (1)) AS src(x)
SET @RETURN_STATUS_TEXT = CONCAT('END PROCEDURE [',@MY_PROCEDURE_NAME,'] @ ',CONVERT(NVARCHAR(50),GETDATE(),120)); CROSS APPLY (
SELECT status = CASE
PRINT ''; WHEN @DocumentID IS NOT NULL
PRINT @RETURN_STATUS_TEXT; AND NOT EXISTS (SELECT 1 FROM dbo.PurchaseDocument WHERE DocumentID = @DocumentID)
PRINT '===================================================================================================='; THEN 1
WHEN NOT EXISTS (SELECT 1 FROM dbo.PurchaseDocument WHERE @DocumentID IS NULL OR DocumentID = @DocumentID)
SELECT THEN 2
success = CAST(1 AS BIT) ELSE 0
, message = N'Daten erfolgreich verarbeitet.' END
, data = @output; ) AS v
);
RETURN @RETURN_STATUS;
END TRY BEGIN CATCH
--====================================================-- exception / error --====================================================--
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());
PRINT 'ERROR IN PROCEDURE: [' + OBJECT_NAME(@@PROCID) + ']' + CHAR(13) + @RETURN_ERROR_TEXT;
PRINT @RETURN_STATUS_TEXT;
PRINT '====================================================================================================';
-----------------------------------------------------------------------------------------------------------------------------------
SELECT
success = CAST(0 AS BIT)
, message = ERROR_MESSAGE()
, data = CAST(NULL AS NVARCHAR(MAX));
RETURN @RETURN_STATUS;
END CATCH;
GO GO