Tuesday, August 14, 2018

X++ code to recalculate Item transactions



static void lan_recalcInventSumItem(Args _args)
{
InventSumRecalcItem InventSumRecalcItem;
;
InventSumRecalcItem = new InventSumRecalcItem("Item Number", true, checkfix::Fix);// enter the item number that need to be re-calc
InventSumRecalcItem.updatenow();
}

Friday, June 1, 2018

X++ code to cancel Deliver Remainder Qty on purchase orders

Below Job is used to select a date range and checks for the ended production orders. Then searches for the purchases orders that are in open status with deliver remainder qty and cancel the qty automatically.

This Job helped our Accounting user to save lot of time. Hence, sharing with you all.


static void lan_CancelingDeliveryRemainderQty(Args _args)
{

   DialogField    dialogStartDate, dialogEndDate;
   TransDate      fromDate, todate;
   PurchLine      purchLine;
    ProdTable prodTable;
    ProdBOM prodBom;
    PurchTable purchTable;
    int cnt =0;

    Dialog     dialog = new Dialog("Select date range");

    dialogStartDate = dialog.addField(extendedTypeStr(TransDate));
    dialogEndDate   = dialog.addField(extendedTypeStr(TransDate));

    dialogStartDate.label("From Date");
    dialogEndDate.label("To Date");

    if(dialog.run())
    {
        fromDate = mkDate(1, mthOfYr(dialogStartDate.value()), year(dialogStartDate.value()));
        toDate   = (mkDate(1, (mthOfYr(dialogEndDate.value()) + 1), year(dialogEndDate.value())) - 1);

        while select * from prodTable
                    join prodBom
                    where  prodTable.ProdId  == prodBom.ProdId
                    && (prodTable.SchedEnd >= fromDate && prodTable.SchedEnd <= todate)
                        && prodBom.InventRefType == 2
                        && prodTable.ProdStatus  == 7
        {
        if(prodTable)

        {
            select * from purchTable
            where purchTable.PurchId == prodBom.InventRefId
            && (purchTable.PurchStatus == 1 || purchTable.PurchStatus == 2);

            if(purchTable)
            {

                     select forupdate purchLine where purchLine.InventRefId == prodTable.ProdId
                     && purchLine.PurchId == prodBom.InventRefId
                     && purchLine.RemainPurchPhysical > 0;
                {

                   if (purchLine)
                    {
                        ttsBegin;
                        // Set remaining inventory Qty to zero
                        purchLine.RemainInventPhysical  = 0;

                        // Set remaining physical Qty to zero
                        purchLine.RemainPurchPhysical   = 0;

                        // We have to cancel the purchLine
                        // Not necessary, I did this to do exactly like AX does
                      //  purchLine.PurchStatus           = PurchStatus::Canceled;

                        // Update PurchLine
                        purchLine.update();
                       cnt++;
                            ttsCommit;
                        // This method will update the inventory transactions
                        InventMovement::bufferSetRemainQty(purchLine);
                    } // purchLine exit
                }
            } //purchTable exit
         }// pordTable exit
        }

    }

         info(strFmt("Start Month %1", fromDate));
        info(strFmt("End Month %1", todate));

    info(strFmt("Total no. of purchlines updated: %1", cnt));


}

Wednesday, March 21, 2018

PowerShell code to see when AOS service was started/stopped

I often need to see when an AOS was stopped for various reasons, and scanning the event viewer can be a hassle. Running this simple 1-line PowerShell script will give you that information.

You can also use this script as a guide to run other PowerShell scripts to search the event log for specific text.

Get-WinEvent -ErrorAction SilentlyContinue -FilterHashtable @{logname='system'; StartTime=(((get-date).AddDays(-30).Date)); EndTime=(((get-date).AddDays(1).Date)); id=7036} -MaxEvents 10000 | ? {$_.Message -like '*Microsoft Dynamics AX Object Server*'}

Thursday, October 19, 2017

X++ class that fetches the data from tables in a different Database and create Payment Journals in AX

Class Declaration:

class LanCreatePaymentJournal_B2B extends RunBaseBatch
{

LedgerjournalTable      LedgerjournalTable;
}



Method lanB2BPaymentJournal:

void lanB2BPaymentJournal()
{

    LedgerjournalTrans      LedgerjournalTrans;
    LedgerjournalCheckPost  LedgerjournalCheckPost;
    CustInvoiceJour custInvoiceJour;
    LedgerJournalEngine_CustPayment     ledgerJournalEngine;
    ResultSet               ResultSet;
    str                     CurCode[], PayStatus[],  InvoiceID[],CardConnectRef[], strdate;
    real Amt[], invoiceamt;
    int                     i = 0;
    int                     cnt = 1;
    Ledgerjournalname       ledgerjournalname;
    CustTransOpen                   custTransOpen;
    CustTrans                       custTrans;
    SpecTransManager                specTransManager;

    NumberSeq               numberSeq;
    CustPaymModeTable _custPaymModeTable;
    CustInvoiceId _invoiceId;
    boolean journalexist = false;


;

    try
    {
    //call the method to get the data from Payment tables
    ResultSet = this.lanReadPaymentTables();

    //Loop through resultset from the above method
    while(ResultSet.next())
    {
        i++;
       // assign resultset values to the arrays
         Amt[i]    = ResultSet.getReal(3);
         PayStatus[i]    = strlrtrim(ResultSet.getString(4));
         CurCode[i]    = strlrtrim(ResultSet.getString(6));
         CardConnectRef[i]    = strlrtrim(ResultSet.getString(7));
         InvoiceID[i]    = strlrtrim(ResultSet.getString(12));

    }
    ResultSet.close();
    ResultSet = null;

    if (i == 0)
        return;

    cnt = i;

      //get the payment method record to get offset Ledger dimension
          select * from _custPaymModeTable
               where _custPaymModeTable.PaymMode == 'MCV';
        // loop through each record from the resultset and create Payment Journals
    for (i = 1; i <= cnt; i++)
    {

           _invoiceId = InvoiceID[i];
            invoiceamt = Amt[i];

            // get the customer invoice journal record
            select * from custInvoiceJour
                    where custInvoiceJour.InvoiceId == _invoiceId;
                   // && custInvoiceJour.InvoiceAmount == invoiceamt;

                select firstonly custTransOpen
                    join custTrans
                    where  custTransOpen.AccountNum  == custTrans.AccountNum
                        && custTransOpen.RefRecId    == custTrans.RecId
                        && custTrans.Invoice         == custInvoiceJour.InvoiceId
                        && custTrans.AccountNum      == custInvoiceJour.InvoiceAccount
                        && custTrans.TransDate       == custInvoiceJour.InvoiceDate;

        if(custTransOpen)
            {

                // create journal
                if(journalexist == false) // Only one Journal Header per mulitple invoices
                {
                     info("Payment Journal Creation to be started");
                ttsBegin;
                    LedgerjournalTable.clear();
                    ledgerjournalname = LedgerJournalName::find('ARCCP');
                    ledgerJournalTable.initFromLedgerJournalName(ledgerjournalname.JournalName);
                    ledgerJournalTable.JournalNum = NumberSeq::newGetNum(LedgerParameters::numRefJournalNum()).num();
                    LedgerjournalTable.Name = strFmt("%1 Credit Card Payment" , systemDateGet());
                    ledgerJournalTable.OffsetAccountType = _custPaymModeTable.AccountType;
                    ledgerJournalTable.parmOffsetLedgerDimension(_custPaymModeTable.offsetLedgerDimension());
                         if (ledgerJournalTable.validateWrite())
                            {
                                ledgerJournalTable.insert();
                                journalexist = true;
                            }
                            else
                            {
                                throw error("Journal header");
                            }
                ttsCommit;
                }

                ttsBegin;
                // create journal Lines
                LedgerjournalTrans.clear();
                ledgerJournalEngine = new LedgerJournalEngine_CustPayment();
                LedgerjournalTrans.initValue();
                ledgerJournalEngine.newJournalActive(ledgerJournalTable);
                ledgerJournalEngine.initValue(LedgerjournalTrans);
                ledgerJournalEngine.initFromCustTable(LedgerjournalTrans);
                numberSeq                               =   NumberSeq::newGetVoucherFromId((ledgerjournalname.NumberSequenceTable));
                LedgerjournalTrans.Voucher              =   numberSeq.voucher();
                LedgerjournalTrans.JournalNum           =   LedgerjournalTable.JournalNum;
                LedgerjournalTrans.accountName();
                LedgerjournalTrans.CurrencyCode         =   CurCode[i];

                LedgerjournalTrans.ExchRate             =   Currency::exchRate(LedgerjournalTrans.CurrencyCode);
                LedgerjournalTrans.AccountType          =   LedgerJournalACType::Cust;
                LedgerjournalTrans.parmAccount(custInvoiceJour.InvoiceAccount,LedgerjournalTrans.AccountType);
                LedgerjournalTrans.Txt                  =   CardConnectRef[i];
                LedgerjournalTrans.MarkedInvoice   = _invoiceId;

                LedgerjournalTrans.AmountCurCredit      =   custTransOpen.AmountCur;
                LedgerjournalTrans.TransDate            =   systemDateGet();
                LedgerjournalTrans.PaymReference = CardConnectRef[i];
                LedgerJournalTrans.OffsetTxt = 'Credit Card Payment';
                LedgerJournalTrans.BankTransType = _custPaymModeTable.BankTransType;
                LedgerJournalTrans.DocumentDate = systemDateGet();
                LedgerjournalTrans.SettleVoucher        = SettlementType::SelectedTransact;

                LedgerjournalTrans.OffsetAccountType    =   LedgerJournalACType::Bank;
                LedgerjournalTrans.OffsetLedgerDimension=    _custPaymModeTable.offsetLedgerDimension();
                LedgerjournalTrans.DefaultDimension     =   CustTable::find(custInvoiceJour.InvoiceAccount).DefaultDimension;
                LedgerjournalTrans.OffsetDefaultDimension =  CustTable::find(custInvoiceJour.InvoiceAccount).DefaultDimension;
                LedgerjournalTrans.LedgerDimension      =   DimensionStorage::getDynamicAccount(custInvoiceJour.InvoiceAccount, LedgerJournalACType::Cust);

                ledgerJournalEngine.currencyModified(LedgerjournalTrans);

                 if (!LedgerjournalTrans.parmOffsetLedgerDimension())
                    {
                        throw info("@SYS122148");
                    }

                 ledgerJournalEngine.initOffsetDefaultDimension(LedgerjournalTrans);
                 LedgerjournalTrans.PaymMode = 'MCV';
                 LedgerjournalTrans.insert();
                 this. lanUpdatePaymentTables(_invoiceId,CardConnectRef[i]);
                ttsCommit;

                // mark the transaction for settlement
                 specTransManager = SpecTransManager::construct(LedgerjournalTrans);

                specTransManager.insert(
                    custTransOpen.company(),
                    custTransOpen.TableId,
                    custTransOpen.RecId,
                    custTransOpen.AmountCur,
                    custInvoiceJour.CurrencyCode);

                ttsBegin;
                LedgerjournalTrans.reread();
                LedgerjournalTrans.MarkedInvoice        = custTrans.Invoice;
                LedgerjournalTrans.MarkedInvoiceCompany = custTrans.company();
                LedgerjournalTrans.MarkedInvoiceRecId   = custTransOpen.RecId;
                LedgerjournalTrans.SettleVoucher        = SettlementType::SelectedTransact;
                LedgerjournalTrans.update();
                ttsCommit;


       }
     }
    }
      catch (Exception::Error)
        {
            ttsabort;
            ttsBegin;
              ledgerJournalTable.delete(); // delete the jorunal header on error
            ttsCommit;
            throw Exception::Error;
        }

}

Method lanReadPaymentTables:

//this method reads the data from Payments and PaymentInvoices tables in different database
//stores the output to Resultset

public ResultSet lanReadPaymentTables()
{
    str         sql;
    str         strSQTYPE;
    ResultSet   ResultSet;
    int         conlength;
    int         counter = 0;
    str         dbServer;
    str         dbName;

//getting server details form parameters table

    dbServer = lanParameters::Find().LAN_ManualPackDbServer;
    if (dbServer == '')
        dbServer = '';

    dbName = lanParameters::Find().Lan_B2BAPIDB;
    if (dbName == '')
        dbName = '';

    sql =  "";
    sql += strFmt('SELECT * FROM [%1].[%2].[dbo].[Payments] P ', dbServer, dbName);
    sql +=    strfmt('inner join [%1].[%2].[dbo].[PaymentsInvoices] PI ', dbServer, dbName);
    sql +=    'on PI.PaymentId = P.ID ';
    sql += strfmt('WHERE P.AXStatus = %1%2%3 ', "'", counter, "'");
    sql +=    strfmt('AND PI.AXInvoiceStatus = %1%2%3 ', "'", counter, "'");

    ResultSet = QueryHelperRunOnServer::executeSQLQuery(sql);

    return ResultSet;

}

Method lanUpdatePaymentTables:

//this method update the data on Payments and PaymentInvoices tables in different database

public void lanUpdatePaymentTables(CustInvoiceId _invoiceId1, str CardConnectRef)
{
    str         sql,sql1;
    str         strSQTYPE;
    int   ResultSet1;
    int         conlength;
    int         counter;
    str         dbServer;
    str         dbName;
    int AXstatus = 1;

    dbServer = lanParameters::Find().LAN_ManualPackDbServer;
    if (dbServer == '')
        dbServer = '';

    dbName = lanParameters::Find().Lan_B2BAPIDB;
    if (dbName == '')
        dbName = '';

   // update AXStatus value on the payments table
    sql += strFmt('Update [%1].[%2].[dbo].[Payments] set AXStatus = %3 ', dbServer, dbName, AXstatus);
    sql += strfmt('WHERE CardConnectRetRef  = %1%2%3 ', "'", CardConnectRef, "'");

      // update AXInvoiceStatus value on the paymentsInvoices table
       sql1 += strfmt("UPDATE [%1].[%2].[dbo].[PaymentsInvoices]  set AXInvoiceStatus = %3", dbServer, dbName, AXstatus);
     sql1 += strfmt("where InvoiceID  = %1%2%3 ", "'", _invoiceId1, "'");


    ResultSet1 = QueryHelperRunOnServer::executeSQLUpdate(sql);
    ResultSet1 = QueryHelperRunOnServer::executeSQLUpdate(sql1);



}

Method Run:

void run()
{

    info(StrFmt("%1 %2", "Start-time: ", time2str(timenow(),1,2)));

  this.lanB2BPaymentJournal();

    info(StrFmt("End-time: %1",  time2str(timenow(),1,2)));

}

Method Void:

static void main(Args args)
{
    LanCreatePaymentJournal_B2B   LanCreatePaymentJournal_B2B;
    ;

    LanCreatePaymentJournal_B2B = new LanCreatePaymentJournal_B2B();

    if (LanCreatePaymentJournal_B2B.prompt())
    {
        LanCreatePaymentJournal_B2B.run();
    }
}


Thursday, September 21, 2017

add menu items to favorites menu via X++ in Dynamics AX


The favorites menu is a bit unusual in AX in the way you need to add to it. Most of the way it works appears to be 
Kernel level, but through some TreeNode usage you can add items to it.

This will add the "SalesTable" menu item to your favorites.


static void JobAddToFavorites(Args _args)
{
    TreeNode                treeNode;
    TreeNode                menuToAdd = TreeNode::findNode(@"\Menu Items\Display\SalesTable");
    TreeNodeIterator        iterator;
    UserMenuList            userMenu;
    Menu                    menuNode;


    treeNode = infolog.userNode();
    iterator = treeNode.AOTiterator();
    treeNode = iterator.next();
    if (treeNode)
    {
        userMenu = treeNode;

        // find 'My Favorites' user menu; 
        treeNode = userMenu.AOTfindChild("@SYS95713");

        // Note menuNode is a different object than userMenu
        menuNode = treeNode;

        menuNode.addMenuitem(menuToAdd);
    }    
}

Another table to take note of is SysPersonalization if you're looking at doing this for multiple users. I haven't dug into this deeply, 
but this code snippet should get you started with what you may want to do.

Friday, September 8, 2017

Removing diacritics (accents on letters) from strings in X++

If you want to remove diacritics (accents on letters) from strings like this "ÁÂÃÄÅÇÈÉàáâãäåèéêëìíîïòóôõ£ALEX" to use the more friendly string "AAAAAACEEaaaaaaeeeeiiiioooo£ALEX", you can use this block of code:

static void AlexRemoveDiacritics(Args _args)
{
    str strInput = 'ÁÂÃÄÅÇÈÉàáâãäåèéêëìíîïòóôõ£ALEX';
    System.String input = strInput;
    str retVal;
    int i;

    System.Char c;
    System.Text.NormalizationForm FormD = System.Text.NormalizationForm::FormD;
    str normalizedString = input.Normalize(FormD);
    System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();

    for (i = 1; i <= strLen(normalizedString); i++)
    {
        c = System.Char::Parse(subStr(normalizedString, i, 1));

        if (System.Globalization.CharUnicodeInfo::GetUnicodeCategory(c) != System.Globalization.UnicodeCategory::NonSpacingMark)
        {
            stringBuilder.Append(c);
        }
    }

    input = stringBuilder.ToString();
    input = input.Normalize();
    retVal = input;

    info(strFmt("Before: '%1'", strInput));
    info(strFmt("After: '%1'", retVal));
}



 It is still very useful.

Wednesday, July 19, 2017

Export and Import a Model Store in AX 2012



Below are the steps to import and export a model store in ax 2012.

Step 1 :

Make sure the client configuration, in which environment you are going import / export model store.

Example : I'm exporting my development model store . So that should be active in Ax Client configuration.

Step 2 :

stop AOS

Step 3 :

On the Start menu, point to All Programs, point to Administrative Tools, and then click Microsoft Dynamics AX Management Shell. 





 At the Windows PowerShell command prompt, PS C:\>, type the following command, and then press ENTER. 

For Export 
-----------------------

Export-AXModelStore -File <Filename> -Details
This command exports the model store to an .axmodelstore file. 

Example :
Export-AXModelStore -File "C:\Rahul\R2ModelStore.axmodelstore" -Details



For Import 
-----------------

Import-AXModelStore -File <Filename>

Example :

Import-AXModelStore -File "C:\DIXF\Rahul\2712\R2ModelStore.axmodelstore"






 
 
 


Press "Y" and Enter...