>

Category Archives: Development

How to add new action under Context menu in Dynamics AX

Each node in the AOT contains a set of available actions. You can access these actions from the
context menu, which you can open by right-clicking any node.

You can create custom actions for any element in the AOT by enlist a class as a new add-in by following:
1. Create a new menu item and give it a meaningful name, a label, and Help text.
2. Set the menu item’s Object Type property to Class.
3. Set the menu item’s Object property to the name of the class to be invoked by the add-in.
4. Drag the menu item to the SysContextMenu menu.
5. If you want the action available only for certain nodes, you need to modify the verifyItem
method on the SysContextMenu class.

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;
}

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;
    }
}

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);
                    }
                }
            }
        }
    }
}

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’);
}

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”;
}

How to: View the History of an Object in AOT – Dynamics AX

If you use version control (There another is another post about Version Control ), you can view the history of an object in the Application Object Tree (AOT).

View the history of an object
  • In the AOT, right-click an object, and then click History.or

    In the AOT, click the History button.

Compare versions of an object

  1. In the AOT, right-click an object, and then click History.or

    In the AOT, click the History button.

  2. Select the versions of the object to compare and then click Compare.
  3. Optionally click the Advanced tab and select advanced options.
  4. Click Compare.

View the change list

  • From the Microsoft Dynamics AX menu, point to Tools, point to Development tools, point to Version control, point to Inquiries, and then click Changes.

Cannot create a record in Purchase order header – Updating table (PurchParmSubTable)

Error message when you post a purchase order in Microsoft Dynamics AX 2009: “Cannot create a record in Purchase order header – Updating table (PurchParmSubTable)”

Problem
When you post a purchase order in Microsoft Dynamics AX 2009, you receive the following error message:
Cannot create a record in Purchase order header – Updating table (PurchParmSubTable).
This problem occurs if one of the following conditions is true:
You enable the “Life sciences electronic signature audit trail setup” setting for all tables.
You create a record for the Common table.
You set the PurchParmTable table in the database log.
This problem occurs when you post a purchase order, a receipts list, a packing slip, and an invoice.

This problem occurs in the following products:
Microsoft Dynamics AX 2009 with Service Pack 1
Microsoft Dynamics AX 2009

Click here to read the complete post

Follow

Get every new post on this blog delivered to your Inbox.

Join other followers:

error: Content is protected !!