Skip to main content

Notifications

Finance | Project Operations, Human Resources, ...
Suggested answer

Sending Journal Information via API

(0) ShareShare
ReportReport
Posted on by 33
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./);        }    }}
 
  • capedcrusader Profile Picture
    capedcrusader 33 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 230,848 Most Valuable Professional 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.
  • capedcrusader Profile Picture
    capedcrusader 33 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 230,848 Most Valuable Professional 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?

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Announcing Our 2025 Season 1 Super Users!

A new season of Super Users has arrived, and we are so grateful for the daily…

Announcing Forum Attachment Improvements!

We're excited to announce that attachments for replies in forums and improved…

Vahid Ghafarpour – Community Spotlight

We are excited to recognize Vahid Ghafarpour as our February 2025 Community…

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,979 Super User 2025 Season 1

#2
Martin Dráb Profile Picture

Martin Dráb 230,848 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Product updates

Dynamics 365 release plans