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?
Have you considered using AIF?
The easy way if you insist on calling AX directly:
Create static X++ methods and call these:
- for creating a journal
- for creating a journal line, fields as parameters
- 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()));
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;
}