CREATE OR ALTER PROCEDURE PRCUST_SET_JSON_INVOICE_DATA
    @json NVARCHAR(MAX)
AS
BEGIN
    SET NOCOUNT ON;

    PRINT 'Starte Verarbeitung von JSON-Daten...';

    ---------------------------------------------------------
    -- JSON VALIDIEREN
    ---------------------------------------------------------
    IF dbo.FN_VALIDATE_JSON_INVOICE_DATA(@json) = 0
    BEGIN
        PRINT 'JSON-Validierung fehlgeschlagen.';
        SELECT
              success = 0
            , message = 'Ungültige JSON-Struktur.'
            , data = NULL;
        RETURN;
    END

    PRINT 'JSON-Validierung erfolgreich.';

    BEGIN TRY
        DECLARE @docs TABLE (doc NVARCHAR(MAX));
        DECLARE @doc NVARCHAR(MAX);
        DECLARE @DocumentID INT;

        PRINT 'Extrahiere purchaseDocuments...';

        INSERT INTO @docs(doc)
        SELECT value
        FROM OPENJSON(@json, '$.purchaseDocuments');

        DECLARE doc_cursor CURSOR FOR SELECT doc FROM @docs;
        OPEN doc_cursor;
        FETCH NEXT FROM doc_cursor INTO @doc;

        WHILE @@FETCH_STATUS = 0
        BEGIN
            PRINT 'Füge PurchaseDocument ein...';

            ---------------------------------------------------------
            -- PurchaseDocument einfügen (zeilenweise)
            ---------------------------------------------------------
            INSERT INTO PurchaseDocument (
                  DocumentType
                , No_
                , NoSeries
                , ProcessIDTransfer
                , BuyFromVendorNo
                , PayToVendorNo
                , PostingDate
                , PaymentTermsCode
                , PaymentTermsCodeIR
                , DueDate
                , PmtDiscountDate
                , PaymentDiscount
                , 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
                , CurrencyCode
                , InvoiceDiscCode
                , PostingDescription
                , PaymentMethodCode
                , VendorInvoiceNo
                , VendorCrMemoNo
                , PhrVendorBankAccountCode
                , PhrBankBranchNo
                , PhrBankAccountNo
                , PhrIBAN
                , PhrSWIFTCode
                , PhrBankName
                , PhrBankAccountEntryPriority
                , PhrRMCashDiscountReceived
                , PhrRMAmountIncludingVAT
                , PhrRMAmountLessDiscount
            FROM OPENJSON(@doc)
            WITH (
                  DocumentType INT
                , No NVARCHAR(50)
                , NoSeries NVARCHAR(50)
                , ProcessIDTransfer NVARCHAR(50)
                , BuyFromVendorNo NVARCHAR(50)
                , PayToVendorNo NVARCHAR(50)
                , PostingDate DATE
                , PaymentTermsCode NVARCHAR(20)
                , PaymentTermsCodeIR NVARCHAR(20)
                , DueDate DATE
                , PmtDiscountDate DATE
                , PaymentDiscount DECIMAL(10,2)
                , CurrencyCode NVARCHAR(10)
                , InvoiceDiscCode NVARCHAR(50)
                , PostingDescription NVARCHAR(250)
                , PaymentMethodCode NVARCHAR(20)
                , VendorInvoiceNo NVARCHAR(50)
                , VendorCrMemoNo NVARCHAR(50)
                , PhrVendorBankAccountCode NVARCHAR(50)
                , PhrBankBranchNo NVARCHAR(50)
                , PhrBankAccountNo NVARCHAR(50)
                , PhrIBAN NVARCHAR(50)
                , PhrSWIFTCode NVARCHAR(50)
                , PhrBankName NVARCHAR(100)
                , PhrBankAccountEntryPriority BIT
                , PhrRMCashDiscountReceived BIT
                , PhrRMAmountIncludingVAT DECIMAL(18,2)
                , PhrRMAmountLessDiscount DECIMAL(18,2)
                , purchaseLines NVARCHAR(MAX) AS JSON
            );

            SET @DocumentID = SCOPE_IDENTITY();

            PRINT 'PurchaseDocument eingefügt. DocumentID = ' + CAST(@DocumentID AS NVARCHAR(20));

            ---------------------------------------------------------
            -- purchaseLines extrahieren
            ---------------------------------------------------------
            PRINT 'Extrahiere purchaseLines...';

            DECLARE @lines TABLE (line NVARCHAR(MAX));
            INSERT INTO @lines(line)
            SELECT value
            FROM OPENJSON(@doc, '$.purchaseLines');

            DECLARE @line NVARCHAR(MAX);
            DECLARE @LineID INT;

            DECLARE line_cursor CURSOR FOR SELECT line FROM @lines;
            OPEN line_cursor;
            FETCH NEXT FROM line_cursor INTO @line;

            WHILE @@FETCH_STATUS = 0
            BEGIN
                PRINT 'Füge PurchaseLine ein...';

                INSERT INTO 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
                    , Type INT
                    , No NVARCHAR(50)
                    , Description NVARCHAR(250)
                    , Description2 NVARCHAR(250)
                    , LocationCode NVARCHAR(50)
                    , VariantCode NVARCHAR(50)
                    , Quantity DECIMAL(18,4)
                    , UnitOfMeasureCode NVARCHAR(20)
                    , DirectUnitCost DECIMAL(18,4)
                    , LineDiscount DECIMAL(18,4)
                    , AbleToDiscount BIT
                    , DiscountCalculated BIT
                    , WorkOrderNo NVARCHAR(50)
                    , GenBusPostingGroup NVARCHAR(20)
                    , GenProdPostingGroup NVARCHAR(20)
                    , VatBusPostingGroup NVARCHAR(20)
                    , VatProdPostingGroup NVARCHAR(20)
                    , ApplToItemEntry INT
                    , PostingWithoutApply BIT
                    , AnticipatedPayment DECIMAL(18,2)
                    , ReceiptNo NVARCHAR(50)
                    , ReceiptLineNo INT
                    , IrOrderNo NVARCHAR(50)
                    , IrOrderLineNo INT
                    , dimSetEntries NVARCHAR(MAX) AS JSON
                    , itemChargeAssignmentLines NVARCHAR(MAX) AS JSON
                );

                SET @LineID = SCOPE_IDENTITY();

                PRINT 'PurchaseLine eingefügt. LineID = ' + CAST(@LineID AS NVARCHAR(20));

                ---------------------------------------------------------
                -- dimSetEntries
                ---------------------------------------------------------
                PRINT 'Füge dimSetEntries ein...';

                INSERT INTO DimSetEntry (
                      LineID
                    , DimensionCode
                    , DimensionValueCode
                )
                SELECT
                      @LineID
                    , DimensionCode
                    , DimensionValueCode
                FROM OPENJSON(@line, '$.dimSetEntries')
                WITH (
                      DimensionCode NVARCHAR(50)
                    , DimensionValueCode NVARCHAR(50)
                );

                ---------------------------------------------------------
                -- itemChargeAssignmentLines
                ---------------------------------------------------------
                PRINT 'Füge itemChargeAssignmentLines ein...';

                INSERT INTO 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)
                    , UnitCost DECIMAL(18,4)
                    , AppliesToDocType INT
                    , AppliesToDocNo NVARCHAR(50)
                    , AppliesToDocLineNo INT
                    , ItemNo NVARCHAR(50)
                    , Description NVARCHAR(250)
                    , QtyToAssign DECIMAL(18,4)
                    , QtyAssigned DECIMAL(18,4)
                    , AmountToAssign DECIMAL(18,4)
                    , AppliesToDocLineAmount DECIMAL(18,4)
                );

                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 'Erzeuge JSON-Ausgabe...';

        ---------------------------------------------------------
        -- JSON-Ausgabe exakt wie Upload-Datei
        ---------------------------------------------------------
        DECLARE @output NVARCHAR(MAX);

        SELECT @output =
        (
            SELECT
                (
                    SELECT
                        (
                            SELECT
                                  pd.*
                                , (
                                    SELECT
                                          pl.*
                                        , (
                                            SELECT *
                                            FROM DimSetEntry d
                                            WHERE d.LineID = pl.LineID
                                            FOR JSON PATH
                                        ) AS dimSetEntries
                                        , (
                                            SELECT *
                                            FROM ItemChargeAssignment ia
                                            WHERE ia.LineID = pl.LineID
                                            FOR JSON PATH
                                        ) AS itemChargeAssignmentLines
                                    FROM PurchaseLine pl
                                    WHERE pl.DocumentID = pd.DocumentID
                                    FOR JSON PATH
                                ) AS purchaseLines
                            FROM PurchaseDocument pd
                            WHERE pd.DocumentID = @DocumentID
                            FOR JSON PATH
                        ) AS purchaseDocuments
                    FOR JSON PATH
                )
        );

        PRINT 'JSON-Ausgabe erstellt.';

        ---------------------------------------------------------
        -- Erfolgsmeldung + strukturierte JSON-Ausgabe
        ---------------------------------------------------------
        SELECT
              success = 1
            , message = 'Daten erfolgreich verarbeitet.'
            , data = @output;

        PRINT 'Verarbeitung erfolgreich abgeschlossen.';

    END TRY
    BEGIN CATCH
        PRINT 'FEHLER: ' + ERROR_MESSAGE();

        SELECT
              success = 0
            , message = ERROR_MESSAGE()
            , data = NULL;
    END CATCH
END
GO
