Skip to main content
Dynamics 365 Community / Forums / Finance forum / Sending Journal Inform...
Finance forum
Suggested answer

Sending Journal Information via API

editSubscribe (0) ShareShare
ReportReport
Posted on by 31
my X++ code, code1 adds an empty linesdata string to the combined request data This is a sample output of my code when I have 2 lines:
Combined Request: {/JournalBatchNumber/:/JBN-000000045/,/Description/:/Vendor payment TEST MULTIPLE LINES/,/NumOfLines/:/2/,
/LinesData/:[{/voucher/:/VPAY-0040/,/LineNum/:/-1.00/,/Currency/:/XOF/},
{/voucher/:/VPAY-0039/,/LineNum/:/1.00/,/Currency/:/XOF/},
{/voucher/://,/LineNum/:/0.00/,/Currency/://}]}

The code sends correctly the 2 lines on the journal but loops a third linesdata information which is empty and irrelevant because I have just 2 lines to be sent.
 
internal final class TestButtonClass{    [FormControlEventHandler(formControlStr(MOVendorPayment, TestButton), FormControlEventType::Clicked)]    public static void TestButton_OnClicked(FormControl sender, FormControlEventArgs e)    {        // Get the current record from the header data source        FormDataSource headerDS = sender.formRun().dataSource(formDataSourceStr(MOVendorPayment, MOVendorPaymentHeaderTable));        FormDataSource linesDS = sender.formRun().dataSource(formDataSourceStr(MOVendorPayment, MOVendorPaymentLinesTable));        if (headerDS && linesDS)        {            // Get the header record            MOVendorPaymentHeaderTable headerRecord = headerDS.cursor();            // Create a string to hold line data            str linesData = //;            int numLines = 0;            // Create an IntegrationLog instance for each line            while (linesDS.next())            {                MOVendorPaymentLinesTable linesRecord = linesDS.cursor();                // Add each line's data to the string                str lineData = strFmt(                   /{///voucher///:///%1///,///LineNum///:///%2///,///Currency///:///%3///}/,                    linesRecord.voucher,                    linesRecord.LineNum,                    linesRecord.Currency                                                       );                if (numLines > 0)                {                    linesData += /,/;                }                linesData += lineData;                 // Increment the line count                numLines++;            }            // Combine header and lines data into a single JSON request            str requestContent = strFmt('{/JournalBatchNumber/:/%1/,/Description/:/%2/,/NumOfLines/:/%3/,/LinesData/:[%4]}',                headerRecord.JournalBatchNumber,                headerRecord.Description,                headerRecord.NumofLines,  // Use numLines instead of headerRecord.NumofLines                linesData);            // Log the combined request            info(strFmt(/Combined Request: %1/, requestContent));            // Make the API call with the combined requestContent (assuming your API call is correct)            var response = VendPaymentAPI.VendPayment.Helper::PostActivity(requestContent, https://TestAPIsalesforce/api/Ref//);            info(/Payment Instructions sent to Bank, Pending Approval, BankTest/);        }        else        {            error(/No header or lines record selected./);        }    }}
 
  • Community member Profile Picture
    Community member 31 on at
    Sending Journal Information via API
    Hi Martin, thank you for your feedback, I am trying to send both header and Lines information from my details transaction page when the header record is selected. The code currently sends only header information, while the line information is empty.The consideration is users will select the Header record and click the Bank send button and this will send both header and Line information.


     
  • Suggested answer
    Martin Dráb Profile Picture
    Martin Dráb 222,562 Super User on at
    Sending Journal Information via API
    I'm still missing your explanation about where you code fails, but I do see some bugs. It's likely that fixing them will solve the problem you meant.
     
    First of all, let me throw away code irrelevant to the iteration, because there is no point in complicating our work more than necessary.
    [FormControlEventHandler(formControlStr(MOVendorPayment, BankSend), FormControlEventType::Clicked)]
    public static void BankSend_OnClicked(FormControl sender, FormControlEventArgs e)
    {
        // Get the current record from the header data source
        FormDataSource headerDS = sender.formRun().dataSource(formDataSourceStr(MOVendorPayment, MOVendorPaymentHeaderTable));
        FormDataSource linesDS = sender.formRun().dataSource(formDataSourceStr(MOVendorPayment, MOVendorPaymentLinesTable));
    
        if (headerDS && linesDS)
        {
            int numLines = 0;
    
            // Create an IntegrationLog instance for each line
            while (linesDS.next())
            {
                MOVendorPaymentLinesTable linesRecord = linesDS.cursor();
                numLines++;
            }
        }
        else
        {
            error("No header or lines record selected.");
        }
    }
    According to the first comment and the error message, you believe that if (headerDS && linesDS) checks whether records were selected, but that's not true. It merely checks whether the form data sources objects were found in the form. It says nothing about records.
     
    The way how you iterate line records is wrong too. Because you apparently want selected records, use MultiSelectionHelper class. For example:
    MOVendorPaymentLinesTable paymentLine = selectionHelper.getFirst();
    
    while (paymentLine.RecId)
    {
        paymentLine = selectionHelper.getNext();
    }
    Try and if you still have a problem with it, please describe the problem to us.
  • Community member Profile Picture
    Community member 31 on at
    Sending Journal Information via API
    Hi Martin, thank you for replying. please here is my code 
    internal final class BankSend
    {
        [FormControlEventHandler(formControlStr(MOVendorPayment, BankSend), FormControlEventType::Clicked)]
        public static void BankSend_OnClicked(FormControl sender, FormControlEventArgs e)
        {
            // Get the current record from the header data source
            FormDataSource headerDS = sender.formRun().dataSource(formDataSourceStr(MOVendorPayment, MOVendorPaymentHeaderTable));
            FormDataSource linesDS = sender.formRun().dataSource(formDataSourceStr(MOVendorPayment, MOVendorPaymentLinesTable));
    
            if (headerDS && linesDS)
            {
                // Get the header record
                MOVendorPaymentHeaderTable headerRecord = headerDS.cursor();
    
                // Create a string to hold line data
                str linesData = "";
                int numLines = 0;
    
                // Create an IntegrationLog instance for each line
                while (linesDS.next())
                {
                    MOVendorPaymentLinesTable linesRecord = linesDS.cursor();
    
                    // Add each line's data to the string
                    str lineData = strFmt(
                        "{\"voucher\":\"%1\",\"LineNum\":\"%2\",\"Currency\":\"%3\",\"Amount\":\"%4\",\"DateTrans\":\"%5\",\"Description\":\"%6\",\"VendorName\":\"%7\",\"VendorBankAccountName\":\"%8\",\"VendorBankAccountNumber\":\"%9\",\"VendorBankAccountAddress\":\"%10\",\"CountryCode\":\"%11\",\"CountryName\":\"%12\",\"RoutingNumber\":\"%13\",\"SwiftCode\":\"%14\",\"ChargeBeneficiary\":\"%15\",\"HasIntermediary\":\"%16\",\"IntermediaryAccountNumber\":\"%17\",\"IntermediaryBankName\":\"%18\",\"IntermediaryBankAddress\":\"%19\",\"IntermediarySortCode\":\"%20\",\"IntermediarySwiftCode\":\"%21\",\"SourceAccount\":\"%22\",\"PaymentReference\":\"%23\"}",
                        linesRecord.voucher,
                        linesRecord.LineNum,
                        linesRecord.Currency,
                        linesRecord.Amount,
                        linesRecord.DateTrans,
                        linesRecord.Description,
                        linesRecord.VendorName,
                        linesRecord.VendorBankAccountName,
                        linesRecord.VendorBankAccountNumber,
                        linesRecord.VendorBankAccountAddress,
                        linesRecord.CountryCode,
                        linesRecord.CountryName,
                        linesRecord.RoutingNumber,
                        linesRecord.SwiftCode,
                        linesRecord.ChargeBeneficiary,
                        linesRecord.HasIntermediary,
                        linesRecord.IntermediaryAccountNumber,
                        linesRecord.IntermediaryBankName,
                        linesRecord.IntermediaryBankAddress,
                        linesRecord.IntermediarySortCode,
                        linesRecord.IntermediarySwiftCode,
                        linesRecord.SourceAccount,
                        linesRecord.PaymentReference
                    );
    
                    if (numLines > 0)
                    {
                        linesData += ",";
                    }
                    linesData += lineData;
    
                    // Create a new IntegrationLog record for each line
                    IntegrationLog integrationLog;
                    integrationLog.initValue();
    
                    // Populate IntegrationLog fields with data from Lines
                    integrationLog.Currency = linesRecord.Currency;
                    integrationLog.Amount = linesRecord.Amount;
                    integrationLog.DateTrans = linesRecord.DateTrans;
                    integrationLog.Description = linesRecord.Description;
                    integrationLog.CountryCode = linesRecord.CountryCode;
                    integrationLog.HasIntermediary = linesRecord.HasIntermediary;
                    integrationLog.ChargeBeneficiary = linesRecord.ChargeBeneficiary;
                    integrationLog.IntermediaryAccountNumber = linesRecord.IntermediaryAccountNumber;
                    integrationLog.VendorName = linesRecord.VendorName;
                    integrationLog.RoutingNumber = linesRecord.RoutingNumber;
                    integrationLog.SwiftCode = linesRecord.SwiftCode;
                    integrationLog.IntermediaryBankAddress = linesRecord.IntermediaryBankAddress;
                    integrationLog.IntermediaryBankName = linesRecord.IntermediaryBankName;
                    integrationLog.IntermediarySortCode = linesRecord.IntermediarySortCode;
                    integrationLog.IntermediarySwiftCode = linesRecord.IntermediarySwiftCode;
                    integrationLog.PaymentReference = linesRecord.PaymentReference;
                    integrationLog.JournalBatchNumber = linesRecord.JournalBatchNumber;
                    integrationLog.voucher = linesRecord.voucher;
                    integrationLog.LineNum = linesRecord.LineNum;
                    integrationLog.VendorBankAccountName = linesRecord.VendorBankAccountName;
                    integrationLog.VendorBankAccountNumber = linesRecord.VendorBankAccountNumber;
                    integrationLog.VendorBankAccountAddress = linesRecord.VendorBankAccountAddress;
    
                    // Save the IntegrationLog record
                    integrationLog.insert();
    
                    // Increment the line count
                    numLines++;
                }
    
                // Combine header and lines data into a single JSON request
                str requestContent = strFmt('{"JournalBatchNumber":"%1","Description":"%2","NumOfLines":"%3","PaymentGateway":"%4","JournalBalance":"%5","VendorPaymentType":"%6","LinesData":[%7]}',
                    headerRecord.JournalBatchNumber,
                    headerRecord.Description,
                    numLines,
                    headerRecord.PaymentGateway,
                    headerRecord.JournalBalance,
                    headerRecord.VendorPaymentType,
                    linesData);
    
                // Log the combined request
                info(strFmt("Combined Request: %1", requestContent));
    
                // Make the API call with the combined requestContent (assuming your API call is correct)
                var response = VendPaymentAPI.VendPayment.Helper::PostActivity(requestContent, "https://TestAPIsalesforce/api/Ref//");
    
                info("Payment Instructions sent to Bank, Pending Approval, BankTest");
            }
            else
            {
                error("No header or lines record selected.");
            }
        }
    
        [FormControlEventHandler(formControlStr(MOVendorPayment, BankSend), FormControlEventType::Clicked)]
        public static void Ok_OnClicked(FormControl sender, FormControlEventArgs e)
        {
            // Get the current record from the data source
            MOVendorPaymentHeaderTable movVendorPaymentHeaderTable = sender.formRun().dataSource(formDataSourceStr(MOVendorPayment, MOVendorPaymentHeaderTable)).cursor();
    
            if (movVendorPaymentHeaderTable)
            {
                ttsbegin;
                movVendorPaymentHeaderTable.VendPaymentApprovalStatus = VendPaymentApprovalStatus::Sent;
                movVendorPaymentHeaderTable.update();
                ttscommit;
    
                info("Payment has been sent");
            }
            else
            {
                info("Payment cannot be recalled.");
            }
        }
    }
    
     
  • Martin Dráb Profile Picture
    Martin Dráb 222,562 Super User on at
    Sending Journal Information via API
    Please create a reply and paste your code once more. One of the bugs of this website wreaks havoc in formatting when used in the first post of a thread.
     
    Also, can't you tell us more about what you found when you debugged your code?

Helpful resources

Quick Links

What Motivates a Super User?

We know many of you visit the Dynamics 365 Community and Power Platform…

Demystifying Copilot with Sundar…

Industry experts answer burning questions directly from our amazing Community…

Enabling Copilot Case and Conversation…

Agents can easily recap an ongoing chat, transcribe a voice conversation…

Leaderboard

#1
Andre Arnaud de Calavon Profile Picture

Andre Arnaud de Cal... 282,978 Super User

#2
Martin Dráb Profile Picture

Martin Dráb 222,562 Super User

#3
nmaenpaa Profile Picture

nmaenpaa 101,138

Product updates

Dynamics 365 release plans