LedgerJournalEngine and LedgerJournalCheckPost

2019-08-25 17:44发布

问题:

I am creating and posting Dynamics AX Ledger Journals from C#.

I want to use the two helper classes the come with AX,

LedgerJournalEngine and LedgerJournalCheckPost, to validate the journals I create.

My questions are:

1.) How do you get a list of errors -> voucher from either of these classes or some other class?

2.) Can you simulate a post inside of a AX transaction and roll it back?

2-a.) If you roll back a posting in a transaction will AX be smart enough to reuse the voucher numbers that got rolled back?

回答1:

Have you considered using AIF?

The easy way if you insist on calling AX directly:

Create static X++ methods and call these:

  1. for creating a journal
  2. for creating a journal line, fields as parameters
  3. for posting a journal, return infolog (as a string)

Let the AX methods do the plumbing with the ledger posting classes.

The posting is all or nothing (with possible transfer of error lines to a new journal). Voucher numbers are reused in case of error. This implies, I guess, that voucher numbers are allocated on posting, which can be set up on the journal name.

The infolog return value could be converted to a string to simplify the C# side.

X++ code to convert to string:

client server static str infoCon2List(container c)
{
    TextBuffer t = new TextBuffer();
    str info;
    int i;
    int n;
    for (i = 1; i <= conlen(c); i += 2)
    {
        info = conpeek(c,i+1);
        n = strFind(info,'\t',strLen(info),-99999);
        t.appendText(strFmt('%1\t%2\t%3\n', conpeek(c,i), n > 1 ? strReplace(subStr(info,2,n-2), '\t', '\\') : '', substr(info,n+1,9999)));
    }
    return t.getText();
}

The way to call it:

int e = infolog.num();
try
{
    doThePosting(...);
}
catch //anything
{
    exceptionTextFallThrough();
}
return Info::infoCon2List(infolog.copy(e+1,infolog.num()));


回答2:

I ended up with:

public static ERSImport_Errors PostJournal(int64 _journalRecID)
{
    LedgerJournalTable          ledgerJournaltable;
    LedgerJournalCheckPost      ledgerJournalCheckPost;
    LedgerJournalID             errorJournalID;
    LedgerJournalEngine         lje;
    ERSImport_Errors             errors;

    boolean                     ret = true;//True we posted this journalRecID
    LedgerJournalTrans          ledgerJournalTrans;
    ;

    errors = new ERSImport_Errors();
    select crosscompany ledgerjournaltable where ledgerjournaltable.RecId == _journalRecID;

    if(ledgerJournalTable == null)
        throw error("Could not find ledger journal table provided");

    changecompany(ledgerJournalTable.dataAreaId)
    {
        ledgerJournalCheckPost = LedgerJournalCheckPost::newLedgerJournalTable(ledgerJournalTable,NoYes::Yes,NoYes::No);
        lje = LedgerJournalEngine::construct(ledgerJournalTable.JournalType);
        lje.newJournalActive(ledgerJournalTable,true);
        ledgerJournalCheckPost.parmLedgerJournalEngine(lje);
        try
        {
            ledgerJournalCheckPost.run();
        }
        catch
        {
            while select ledgerJournalTrans where ledgerJournalTrans.JournalNum == ledgerJournalTable.JournalNum
            {
                if(lje.errorExists(ledgerJournalTrans.Voucher))
                {
                    errors.addError(lje.errorLog(ledgerJournalTrans.Voucher),ledgerJournalTrans.RecId);
                }
            }
        }
    }
    return errors;
}