Welcome to Dynamics AX 2012 blog for learning, sharing and transferring dynamics AX knowledge and all related topics to AX for example Business Intelligence (SSRS & SSAS), SQL, Workflow, SharePoint, ALL Dynamics AX Reporting tools, AX Integration ( AIF, Web Service, ...)
How to Delete Company Transactions in AX 2012 including Trial balance?
To delete Transactions
data inside any company in ax, you can do by using the class
SysDatabaseTransDelete under AOT.
But you may facing an
issue since the Trial Balance will not be deleted so, to delete GL Trans
by deleting the following tables:
GeneralJournalAccountEntry
GeneralJournalEntry
LedgerEntryJournal
LedgerEntry
Ledgerjournaltrans
Ledgerjournaltable
To remove the Trial
Balance you have to follow the steps below:
1-) Modify
'handleTable()' method by adding 2 new cases
Case TableGroup::TransactionHeader:
Case
TableGroup::TransactionLine:
void handleTable(SysDictTable
sysDictTable)
{
TableGroup tableGroup;
if (tableSet.in(sysDictTable.id()))
return;
tableSet.add(sysDictTable.id());
if (sysDictTable
&& !sysDictTable.isTmp() && !sysDictTable.isMap())
{
tableGroup
= sysDictTable.tableGroup();
//
Handle company specific tables to be deleted
if (sysDictTable.dataPrCompany())
{
switch(tableGroup)
{
case TableGroup::Transaction:
case TableGroup::TransactionHeader:
case TableGroup::TransactionLine:
case TableGroup::WorksheetHeader:
case TableGroup::WorksheetLine:
this.handleTransTable(sysDictTable);
break;
default:
this.handleNonTransTable(sysDictTable);
break;
}
}
else
{
//
Handle global tables to be deleted
switch(tableGroup)
{
case TableGroup::Transaction:
case TableGroup::TransactionHeader:
case TableGroup::TransactionLine:
case TableGroup::TransactionHeader
:
case TableGroup::WorksheetHeader:
case TableGroup::WorksheetLine:
this.handleGlobalTransTable(sysDictTable);
break;
default:
break;
}
}
}
}
2) Add a new method to
handle LEDGERJOURNALTABLE:
private void
deleteLedgerJournalTables()
{
{
GeneralJournalEntry GJEntry;
GeneralJournalAccountEntry GJAEntry;
LedgerJournalTable ledgerjournalTable;
LedgerEntryJournal ledgerEntryJournal;
ttsBegin;
while select forupdate LedgerJournalTable
{
while select forUpdate ledgerEntryJournal
where ledgerEntryJournal.JournalNumber == ledgerjournalTable.JournalNum
//&& ledgerEntryJournal.dataAreaId == ledgerjournalTable.dataAreaId
{
while select forUpdate GJEntry
where GJEntry.LedgerEntryJournal == ledgerEntryJournal.RecId
{
delete_from GJAEntry where GJAEntry.GeneralJournalEntry == GJEntry.RecId;
GJEntry.delete();
}
ledgerEntryJournal.delete();
}
LedgerJournalTable.delete();
}
ttsCommit;
}
GeneralJournalAccountEntry GJAEntry;
LedgerJournalTable ledgerjournalTable;
LedgerEntryJournal ledgerEntryJournal;
ttsBegin;
while select forupdate LedgerJournalTable
{
while select forUpdate ledgerEntryJournal
where ledgerEntryJournal.JournalNumber == ledgerjournalTable.JournalNum
//&& ledgerEntryJournal.dataAreaId == ledgerjournalTable.dataAreaId
{
while select forUpdate GJEntry
where GJEntry.LedgerEntryJournal == ledgerEntryJournal.RecId
{
delete_from GJAEntry where GJAEntry.GeneralJournalEntry == GJEntry.RecId;
GJEntry.delete();
}
ledgerEntryJournal.delete();
}
LedgerJournalTable.delete();
}
ttsCommit;
}
3) Modify the 'handleTransTable()'
method to call the above method
void
handleTransTable(SysDictTable sysDictTable)
{
switch(sysDictTable.id())
{
case tablenum(CustCollectionLetterLine):
case tablenum(InventDim):
case tablenum(DocuRef):
case tablenum(DirPartyRelationship) :
break;
case tablenum(LedgerJournalTable) :
this.deleteLedgerJournalTables();
break;
default:
this.deleteTable(sysDictTable);
break;
}
}
{
switch(sysDictTable.id())
{
case tablenum(CustCollectionLetterLine):
case tablenum(InventDim):
case tablenum(DocuRef):
case tablenum(DirPartyRelationship) :
break;
case tablenum(LedgerJournalTable) :
this.deleteLedgerJournalTables();
break;
default:
this.deleteTable(sysDictTable);
break;
}
}
4) You may have to
modify the 'deleteVoucher()' method in the 'LedgerJournalTrans' table to skip
over releasing non-existing voucher numbers
public server void
deleteVoucher(Voucher _voucher = this.Voucher)
{
LedgerJournalTable ledgerJournalTable = LedgerJournalTable::find(this.JournalNum);
if (! ledgerJournalTable.Posted && !this.Transferred)
{
if (_voucher && ! LedgerJournalTrans::existTransMinusThis(this.JournalNum, _voucher, this.RecId))
{
if (this.checkVoucherNotUsed(ledgerJournalTable, _voucher))
{
if (this.checkVoucherNotUsedDataSource(_voucher))
{
// replace the voucher number so it can be re-used
if (ledgerJournalTable.NumberSequenceTable) /* 28Nov12-Admin */
NumberSeq::releaseNumber(ledgerJournalTable.NumberSequenceTable, _voucher);
if (this.Voucher == _voucher)
{
// delete voucher template record if exists and the voucher on the line is not being changed
LedgerJournalTransVoucherTemplate::deleteForJournalOrVoucher(this.JournalNum, _voucher);
}
}
}
}
}
}
{
LedgerJournalTable ledgerJournalTable = LedgerJournalTable::find(this.JournalNum);
if (! ledgerJournalTable.Posted && !this.Transferred)
{
if (_voucher && ! LedgerJournalTrans::existTransMinusThis(this.JournalNum, _voucher, this.RecId))
{
if (this.checkVoucherNotUsed(ledgerJournalTable, _voucher))
{
if (this.checkVoucherNotUsedDataSource(_voucher))
{
// replace the voucher number so it can be re-used
if (ledgerJournalTable.NumberSequenceTable) /* 28Nov12-Admin */
NumberSeq::releaseNumber(ledgerJournalTable.NumberSequenceTable, _voucher);
if (this.Voucher == _voucher)
{
// delete voucher template record if exists and the voucher on the line is not being changed
LedgerJournalTransVoucherTemplate::deleteForJournalOrVoucher(this.JournalNum, _voucher);
}
}
}
}
}
}
5) After running
'SysDatabaseTransDelete', rebuild balances for the financial dimension sets
(General Ledger\Setup\Financial Dimensions\Financial dimension sets)
If you still have
non-zero amounts in the Trial balance then you must manually remove the 'left-over'
rows in the shared tables (results of your previous executions of the
'SysDatabaseTransDelete'). Identify these entries in the 'LedgerEntryJournal'
table then use the following job to clear them:
static void
tg_deleteTables(Args _args)
{
GeneralJournalEntry GJEntry;
GeneralJournalAccountEntry GJAEntry;
LedgerJournalTable ledgerjournalTable;
LedgerEntryJournal ledgerEntryJournal;
ttsBegin;
while select forUpdate ledgerEntryJournal
where ledgerEntryJournal.JournalNumber like 'clau*'
{
while select forUpdate GJEntry
where GJEntry.LedgerEntryJournal == ledgerEntryJournal.RecId
{
delete_from GJAEntry where GJAEntry.GeneralJournalEntry == GJEntry.RecId;
GJEntry.delete();
}
ledgerEntryJournal.delete();
}
ttsCommit;
info('completed');
}
{
GeneralJournalEntry GJEntry;
GeneralJournalAccountEntry GJAEntry;
LedgerJournalTable ledgerjournalTable;
LedgerEntryJournal ledgerEntryJournal;
ttsBegin;
while select forUpdate ledgerEntryJournal
where ledgerEntryJournal.JournalNumber like 'clau*'
{
while select forUpdate GJEntry
where GJEntry.LedgerEntryJournal == ledgerEntryJournal.RecId
{
delete_from GJAEntry where GJAEntry.GeneralJournalEntry == GJEntry.RecId;
GJEntry.delete();
}
ledgerEntryJournal.delete();
}
ttsCommit;
info('completed');
}
How to post PO by Code in Dynamics AX
I have task to integrate Dynamics AX with another application by posting PO
from out side Dynamics AX, so I used AIF and build new web service to be used
from out of AX and call the method below to post PO (packing slip, or invoice)
.
public str CreatePostProductReceipt(PurchId _PurchId, Num _PackingSlip, ItemId Itemid, Qty qty,
InventSiteId InventSiteId ='', InventLocationId InventLocationId= '' , inventBatchid batchid = '', InventSerialId serialId = '', inventsizeId inventsizeId ='', InventColorId InventColorId ='')
{
PurchFormLetter purchFormLetter;
PurchParmUpdate purchParmUpdate;
PurchParmTable purchParmTable;
PurchParmLine purchParmLine;
PurchTable purchTable;
PurchLine purchLine;
PurchId purchId;
Num packingSlipId;
InventDim inventDim;
str ret='';
System.Exception err;
;
packingSlipId = _PackingSlip;
purchTable = PurchTable::find(_PurchId);
ttsBegin;
try
{
// Create PurchParamUpdate table
purchFormletter = PurchFormLetter::construct(DocumentStatus::PackingSlip); // to post invoice change to DocumentStatus::invoice
purchFormLetter.createParmUpdate(true);
purchParmUpdate = PurchFormLetter.purchParmUpdate();
// Set PurchParmTable table
purchParmTable.clear();
purchParmTable.TransDate = SystemDateGet();
purchParmTable.Ordering = DocumentStatus::PackingSlip;
purchParmTable.ParmJobStatus = ParmJobStatus::Waiting;
purchParmTable.Num = packingSlipId;
purchParmTable.PurchId = purchTable.PurchId;
purchParmTable.PurchName = purchTable.PurchName;
purchParmTable.DeliveryName = purchTable.DeliveryName;
purchParmTable.OrderAccount = purchTable.OrderAccount;
purchParmTable.CurrencyCode = purchTable.CurrencyCode;
purchParmTable.InvoiceAccount = purchTable.InvoiceAccount;
purchParmTable.ParmId = purchParmUpdate.ParmId;
purchParmTable.insert();
// Set PurchParmLine table
while select purchLine
where purchLine.PurchId == purchTable.purchId && purchline.ItemId == Itemid
{
purchParmLine.InitFromPurchLine(purchLine);
inventDim = purchline.inventDim(true);
// Set batch and serial number
if(InventSiteId != '')
inventDim.InventSiteId = InventSiteId;
if(InventLocationId != '')
inventDim.InventLocationId = InventLocationId;
if(batchid != '')
inventDim.inventBatchId = batchId;
if(serialid != '')
inventDim.inventSerialId = serialID;
if(inventsizeId != '')
inventDim.inventsizeId = inventsizeId;
if(InventColorId != '')
inventDim.InventColorId = InventColorId;
purchParmLine.InventDimId = inventDim::findOrCreate(inventdim).inventDimId;
purchParmLine.ReceiveNow = 1 ; //PurchLine.PurchQty;
purchParmLine.setInventReceiveNow();
purchParmLine.ParmId = purchParmTable.ParmId;
purchParmLine.TableRefId = purchParmTable.TableRefId;
purchParmLine.setQty(DocumentStatus::PackingSlip, false, true);
purchParmLine.setLineAmount();
purchParmLine.insert();
}
ttsCommit;
purchFormLetter = PurchFormLetter::construct(DocumentStatus::PackingSlip);
purchFormLetter.transDate(systemDateGet());
purchFormLetter.proforma(false);
purchFormLetter.specQty(PurchUpdate::PackingSlip);
purchFormLetter.purchTable(purchTable);
// This is the ID we hard code as the product receipt ID, if we do the posting via UI
// user would have the option to manually enter this value
purchFormLetter.parmParmTableNum(purchParmTable.ParmId);
purchFormLetter.parmId(purchParmTable.ParmId);
purchFormLetter.purchParmUpdate(purchparmupdate);
purchFormLetter.run();
return "OK";
}
catch (Exception::CLRError)
{
err = CLRInterop::getLastException();
ret = err.ToString();
return ret;
}
Return "Error";
}
public str CreatePostProductReceipt(PurchId _PurchId, Num _PackingSlip, ItemId Itemid, Qty qty,
InventSiteId InventSiteId ='', InventLocationId InventLocationId= '' , inventBatchid batchid = '', InventSerialId serialId = '', inventsizeId inventsizeId ='', InventColorId InventColorId ='')
{
PurchFormLetter purchFormLetter;
PurchParmUpdate purchParmUpdate;
PurchParmTable purchParmTable;
PurchParmLine purchParmLine;
PurchTable purchTable;
PurchLine purchLine;
PurchId purchId;
Num packingSlipId;
InventDim inventDim;
str ret='';
System.Exception err;
;
packingSlipId = _PackingSlip;
purchTable = PurchTable::find(_PurchId);
ttsBegin;
try
{
// Create PurchParamUpdate table
purchFormletter = PurchFormLetter::construct(DocumentStatus::PackingSlip); // to post invoice change to DocumentStatus::invoice
purchFormLetter.createParmUpdate(true);
purchParmUpdate = PurchFormLetter.purchParmUpdate();
// Set PurchParmTable table
purchParmTable.clear();
purchParmTable.TransDate = SystemDateGet();
purchParmTable.Ordering = DocumentStatus::PackingSlip;
purchParmTable.ParmJobStatus = ParmJobStatus::Waiting;
purchParmTable.Num = packingSlipId;
purchParmTable.PurchId = purchTable.PurchId;
purchParmTable.PurchName = purchTable.PurchName;
purchParmTable.DeliveryName = purchTable.DeliveryName;
purchParmTable.OrderAccount = purchTable.OrderAccount;
purchParmTable.CurrencyCode = purchTable.CurrencyCode;
purchParmTable.InvoiceAccount = purchTable.InvoiceAccount;
purchParmTable.ParmId = purchParmUpdate.ParmId;
purchParmTable.insert();
// Set PurchParmLine table
while select purchLine
where purchLine.PurchId == purchTable.purchId && purchline.ItemId == Itemid
{
purchParmLine.InitFromPurchLine(purchLine);
inventDim = purchline.inventDim(true);
// Set batch and serial number
if(InventSiteId != '')
inventDim.InventSiteId = InventSiteId;
if(InventLocationId != '')
inventDim.InventLocationId = InventLocationId;
if(batchid != '')
inventDim.inventBatchId = batchId;
if(serialid != '')
inventDim.inventSerialId = serialID;
if(inventsizeId != '')
inventDim.inventsizeId = inventsizeId;
if(InventColorId != '')
inventDim.InventColorId = InventColorId;
purchParmLine.InventDimId = inventDim::findOrCreate(inventdim).inventDimId;
purchParmLine.ReceiveNow = 1 ; //PurchLine.PurchQty;
purchParmLine.setInventReceiveNow();
purchParmLine.ParmId = purchParmTable.ParmId;
purchParmLine.TableRefId = purchParmTable.TableRefId;
purchParmLine.setQty(DocumentStatus::PackingSlip, false, true);
purchParmLine.setLineAmount();
purchParmLine.insert();
}
ttsCommit;
purchFormLetter = PurchFormLetter::construct(DocumentStatus::PackingSlip);
purchFormLetter.transDate(systemDateGet());
purchFormLetter.proforma(false);
purchFormLetter.specQty(PurchUpdate::PackingSlip);
purchFormLetter.purchTable(purchTable);
// This is the ID we hard code as the product receipt ID, if we do the posting via UI
// user would have the option to manually enter this value
purchFormLetter.parmParmTableNum(purchParmTable.ParmId);
purchFormLetter.parmId(purchParmTable.ParmId);
purchFormLetter.purchParmUpdate(purchparmupdate);
purchFormLetter.run();
return "OK";
}
catch (Exception::CLRError)
{
err = CLRInterop::getLastException();
ret = err.ToString();
return ret;
}
Return "Error";
}
Subscribe to:
Posts (Atom)