web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

News and Announcements icon
Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Suggested Answer

Creating General Journal with X++ with validation

(0) ShareShare
ReportReport
Posted on by 405
Hi everyone,
 
I want to create General Journal using X++ by reading a csv file, recently to insert normal journal is working, however may I know is there possiblity to run validation first before the journal created ready to be posted ?
 
This is my current code, it run within loop of reading the csv line by line:
            if (!ledgerjourTable.JournalNum)            {                ttsbegin;                ledgerjourTable.clear();                                    ledgerjourTable.initFromLedgerJournalName(ledgerJourName.JournalName);                ledgerjourTable.JournalNum = JournalTableData::newTable(ledgerjourTable).nextJournalId();                str journalDate = date2str(today(), 321, DateDay::Digits2, DateSeparator::None, DateMonth::Digits2, DateSeparator::None, DateYear::Digits4);                ledgerjourTable.insert();                ttscommit;            }                            ttsbegin;            ledgerJourTrans.clear();            NumberSeq   numberSeq = NumberSeq::newGetVoucherFromId(ledgerJourName.NumberSequenceTable, true, false, UnknownNoYes::No);            ledgerJourTrans.Voucher              = numberSeq.voucher();                                       ledgerJourTrans.JournalNum           = ledgerjourTable.JournalNum;            ledgerJourTrans.DefaultDimension     = MyMasterAccountTable.DimensionDefault;            ledgerJourTrans.OffsetDefaultDimension =  MyMasterAccountTable.DimensionDefault;            ledgerJourTrans.CurrencyCode         = Ledger::accountingCurrency(CompanyInfo::current());            if (accountType == LedgerJournalACType::Ledger)            {                ledgerJourTrans.AccountType      = accountType;            }            else            {                ledgerJourTrans.AccountType      = ledgerJourName.OffsetAccountType;            }                        ledgerJourTrans.LedgerDimension      = LedgerDefaultAccountHelper::getDefaultAccountFromMainAccountId(MyMasterAccountTable.MainAccountNum);                                          if (amount > 0)            {                ledgerJourTrans.AmountCurDebit = amount;            }            else            {                ledgerJourTrans.AmountCurCredit = amount;            }                        ledgerJourTrans.PaymMode            = paymMode;            ledgerJourTrans.TransDate           = transdate;             ledgerJourTrans.TransactionType     = LedgerTransType::None;            ledgerJourTrans.OffsetAccountType   = ledgerJourName.OffsetAccountType;            ledgerJourTrans.OffsetLedgerDimension   = ledgerJourName.OffsetLedgerDimension;                                    ledgerJourTrans.insert();            lineimported ++;            ledgerJourTable.selectForUpdate(true);            ledgerJourTable.NumOfLines = lineimported;            ledgerJourTable.doUpdate();            ledgerJourTable.selectForUpdate(false);            ttscommit;
 
So, may I know can we validate this journal first, just like when we doing it manual and press Validate Button? and basically how to do it in X++ ?
The intention also, if the validation result is not passed (Invalid), I should not insert this journal.
 
Thanks
 
I have the same question (0)
  • Teevo Profile Picture
    405 on at
    Sorry,
     
    the code looks in mess. This is the formatted.
                if (!ledgerjourTable.JournalNum)
                {
                    ttsbegin;
                    ledgerjourTable.clear();
                        
                    ledgerjourTable.initFromLedgerJournalName(ledgerJourName.JournalName);
                    ledgerjourTable.JournalNum = JournalTableData::newTable(ledgerjourTable).nextJournalId();
                    str journalDate = date2str(today(), 321, DateDay::Digits2, DateSeparator::None, DateMonth::Digits2, DateSeparator::None, DateYear::Digits4);
                    ledgerjourTable.insert();
                    ttscommit;
                }
                    
                ttsbegin;
                ledgerJourTrans.clear();
                NumberSeq   numberSeq = NumberSeq::newGetVoucherFromId(ledgerJourName.NumberSequenceTable, true, false, UnknownNoYes::No);
                ledgerJourTrans.Voucher              = numberSeq.voucher();                           
                ledgerJourTrans.JournalNum           = ledgerjourTable.JournalNum;
                ledgerJourTrans.DefaultDimension     = MyMasterAccountTable.DimensionDefault;
                ledgerJourTrans.OffsetDefaultDimension =  MyMasterAccountTable.DimensionDefault;
                ledgerJourTrans.CurrencyCode         = Ledger::accountingCurrency(CompanyInfo::current());
                if (accountType == LedgerJournalACType::Ledger)
                {
                    ledgerJourTrans.AccountType      = accountType;
                }
                else
                {
                    ledgerJourTrans.AccountType      = ledgerJourName.OffsetAccountType;
                }            
                ledgerJourTrans.LedgerDimension      = LedgerDefaultAccountHelper::getDefaultAccountFromMainAccountId(MyMasterAccountTable.MainAccountNum);
                       
               
                if (amount > 0)
                {
                    ledgerJourTrans.AmountCurDebit = amount;
                }
                else
                {
                    ledgerJourTrans.AmountCurCredit = amount;
                }
                
                ledgerJourTrans.PaymMode            = paymMode;
                ledgerJourTrans.TransDate           = transdate; 
    
                ledgerJourTrans.TransactionType     = LedgerTransType::None;
                ledgerJourTrans.OffsetAccountType   = ledgerJourName.OffsetAccountType;
                ledgerJourTrans.OffsetLedgerDimension   = ledgerJourName.OffsetLedgerDimension;            
                
                ledgerJourTrans.insert();
    
                lineimported ++;
    
                ledgerJourTable.selectForUpdate(true);
                ledgerJourTable.NumOfLines = lineimported;
                ledgerJourTable.doUpdate();
                ledgerJourTable.selectForUpdate(false);
                ttscommit;
     
  • Suggested answer
    Martin Dráb Profile Picture
    239,684 Most Valuable Professional on at
    Use LedgerJournalCheckPost class. For example:
    LedgerJournalCheckPost checkPost = LedgerJournalCheckPost::newLedgerJournalTable(ledgerJourTable, NoYes::No);
    checkPost.runOperation();
    Then you can check numOfErrorsInList() if needed.
  • Teevo Profile Picture
    405 on at
    Hi Martin,
     
    May I know how to get the numOfErrorsInList ?
     
    Btw, about my intention of using this LedgerJournalCheckPost to validate first my journal creation, how is the "block code" should be, so when the result of CheckPost is "Invalid", the journal I inserted (created) is rolled back (creation cancel) ?
     
    Should I use Try..Catch() and in which part I should use ttsbegin.. ttscommit ? Is the ttsbegin.. ttscommit put one time only at the the beginning and end of Try... block ? where exactly I should put the CheckPost ?
     
    Sorry, I'm pretty confuse how exactly the best way of writing this. Hope I can get some guidance.
     
    Thanks.
  • Martin Dráb Profile Picture
    239,684 Most Valuable Professional on at
    You just need to call the method: checkPost.numOfErrorsInList().
     
    If you want to rollback a transaction when the number of errors isn't zero, you indeed have to use a transaction (ttsbegin/ttscommit) and have all the operations there. When the condition is met, throw an error, which rollbacks the transaction. You don't necessarily need try/catch.
  • Teevo Profile Picture
    405 on at
    May I know if this kind of "block" correct ?
    try
    {           
    ttsbegin;
    
         <<< processing data and insert into LedgerJournalTable and LedgerJournalTrans >>>     
         
         LedgerJournalCheckPost checkPost = LedgerJournalCheckPost::newLedgerJournalTable(ledgerJourTable, NoYes::No);
         checkPost.runOperation();
    
         if (checkPost.numOfErrorsInList() > 0)
         {
             throw Error("@SYS88904");
         }
    
         ttscommit;
    
         info(strFmt("@GLS91938", journalId));
         info("Import Completed");   
    }
    catch
    {
          ttsabort;
    }
     
    If the checkPost.numOfErrorInList() contain some number, it will throw error and aborting... including roll back whatever being inserted ?
     
    Thanks.
     
     
  • Martin Dráb Profile Picture
    239,684 Most Valuable Professional on at
    Yes, the transaction will be rolled back automatically.
     
    Your call of ttsabort isn't needed; the transaction is already rolled back before your code gets called.
  • Teevo Profile Picture
    405 on at
    Hi Martin,
     
    I'm not sure I'm doing it right, but if I try to debug, the check post NumOfErrorInList() didn't have any value even though I can see this class also have tableErrorLog field and having some errors ->
    If you see in VoucherErrorList, it says {{}} ->
     
    So basically, now I'm using that field TableErrorLog ->

                    LedgerJournalCheckPost checkPost = LedgerJournalCheckPost::newLedgerJournalTable(ledgerJourTable, NoYes::No);
                    checkPost.runOperation();
                    if (checkPost.tableErrorLog())
                    {
                        throw Error("@SYS88904");
                    }

    Do you have any advices ?

    Thanks
  • Martin Dráb Profile Picture
    239,684 Most Valuable Professional on at
    Maybe my idea wasn't a good one. What we can do is to check how voucherErrorList is populated.
     
    It seems to me that insertInVoucherErrorList() puts a value to voucherErrorList only if transferErrors is true. So maybe we just need to change the value of _transferErrors parameter of newLedgerJournalTrans().
    LedgerJournalCheckPost::newLedgerJournalTable(ledgerJourTable, NoYes::No, NoYes::Yes);
    Give it a try.
  • Teevo Profile Picture
    405 on at
    Hi Martin,
     
    Sorry, I haven't test what your suggest. Later will do. So currently I'm using TableErrorLog() to identify there are errors after validate, as below:
    try
    {
       ttsbegin;
       . 
       .
       LedgerJournalCheckPost checkPost = LedgerJournalCheckPost::newLedgerJournalTable(ledgerJourTable, NoYes::No);
       checkPost.runOperation();
    
       if (checkPost.tableErrorLog())
       {
           throw Error("@SYS88904");
       }
    
       ttscommit;
    
    } 
    catch
    {
    
    }
    
    
    In regards of this journal not passed validation, it will throw error, and journal will not be created (rolled back)
    But may I know how to release the Voucher number sequence ? As I checked there are bunch of vouchers in Number sequence with status "ActiveNonBlocking"
     
     
    May I know how to release this ? delete this from Number sequence.
     
    Thanks.
     
     
  • Martin Dráb Profile Picture
    239,684 Most Valuable Professional on at
    Please create a new thread about this new topic and tell us how you've configured the number sequence.

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

Season of Sharing Community Challenge Launch!

Jump in, show your community spirit, and win prizes!

Women in Power Builds Momentum

Expanding mentorship, skilling, and AI innovation

Congratulations to the May Top 10 Community Leaders

These are the community rock stars!

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
Abhilash Warrier Profile Picture

Abhilash Warrier 668 Super User 2026 Season 1

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 630 Super User 2026 Season 1

#3
Giorgio Bonacorsi Profile Picture

Giorgio Bonacorsi 581

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans