web
You’re offline. This is a read only version of the page.
close
Skip to main content
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 375
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
    375 on at
    Creating General Journal with X++ with validation
    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
    236,847 Most Valuable Professional on at
    Creating General Journal with X++ with validation
    Use LedgerJournalCheckPost class. For example:
    LedgerJournalCheckPost checkPost = LedgerJournalCheckPost::newLedgerJournalTable(ledgerJourTable, NoYes::No);
    checkPost.runOperation();
    Then you can check numOfErrorsInList() if needed.
  • Teevo Profile Picture
    375 on at
    Creating General Journal with X++ with validation
    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
    236,847 Most Valuable Professional on at
    Creating General Journal with X++ with validation
    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
    375 on at
    Creating General Journal with X++ with validation
    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
    236,847 Most Valuable Professional on at
    Creating General Journal with X++ with validation
    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
    375 on at
    Creating General Journal with X++ with validation
    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
    236,847 Most Valuable Professional on at
    Creating General Journal with X++ with validation
    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
    375 on at
    Creating General Journal with X++ with validation
    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
    236,847 Most Valuable Professional on at
    Creating General Journal with X++ with validation
    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

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Pallavi Phade – Community Spotlight

We are honored to recognize Pallavi Phade as our Community Spotlight honoree for…

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

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 756 Super User 2025 Season 2

#2
CA Neeraj Kumar Profile Picture

CA Neeraj Kumar 678

#3
Martin Dráb Profile Picture

Martin Dráb 526 Most Valuable Professional

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans