Saturday, December 21, 2013

Exchange Rate in Dynamics Ax 2012



·         In Microsoft Dynamics AX, all currencies are provided by default. The currencies are loaded the first time a user opens the General ledger parameters form.
·         Only one currency can represent the Triangulation currency. By default, the EUR currency is selected as the Triangulation currency. To change the Triangulation currency, you must first clear the Reference currency for triangulation check box on the EUR record in the Currencies form. Then, you can select the Reference currency for triangulation on the desired currency.
·         Accounting Currency: This is the monetary unit of measure that is used to record the converted monetary value of economic transactions in ledger accounts. It may also be referred to as the "company" or ledger currency.
·         Reporting Currency: The monetary unit of measure used to record the converted monetary value of economic transactions in ledger accounts for financial and management reporting purposes

·         Create Exchange Rate Types: Exchange rates types are shared data across the entire system and only need to be setup once. Exchange rate types are a grouping that allows different exchange rates for two currencies. Examples include Buy, Sell, Spot, and Budget
·         A currency pair can only exist once and entering a reciprocal pair is not supported in the system. Therefore, if you already have USD to EUR set up, you cannot create a EUR to USD currency pair for the same exchange rate type. The system will calculate the reciprocal rate automatically if it cannot find the exact currency pair during the translation conversion. If you only have USD to EUR set up and you are entering a transaction amount in EUR in a legal entity where USD is the accounting currency, the system will first look for the exact currency pair in the rate type used by the ledger: EUR to USD. If not found, the system will then look for USD to EUR and calculate the reciprocal rate.
·         Display Currency: When you change the display currency, the default currency of a company does not change. Also, this is not a global change; it does not affect any other users in the company, nor does it change the original transaction. It is also meant to be an estimate of the amount in the selected currency.


Friday, December 20, 2013

Form Performance - Checklist


 q Set the caching of display methods correctly depending on their usage.
Infrequently used display methods should not be cached.

q Set OnlyFetchActive=Yes on datasources if no fields from the table are being used in X++
This optimizes the amount of data that is fetched from the database and moved from the database, to the AOS and finally to the client.

q Set AutoSearch=No on infrequently used datasources and only execute the query when the data is displayed

q Enable or disable controls in a single RPC call to the server.
This means that you get all relevant data needed, and then enable or disable controls on the form based on the data. Do not get a specific piece of data, disable a control, and then get another piece of data (database call), and disable a control, and repeat the process until you have worked through the display elements.

q Wrap calls that cause a layout change or window redraws in element.lock() and element.unLock() to minimize extraneous drawing that result in flicker.
The element.lock() and element.unlock() methods are new in Dynamics AX 2012. When the form is 'locked', the form will not be redrawn (changes in the layout will not be addressed). Once a form is 'unlocked' any layout changes will be made. This has been implemented as a way of minimizing the times a form has to update the layout.

q Minimize the work that you do in a datasource's active() method.
Like accessing additional database, complex calculations in datasource's active() method.

q Make first FactBox on your form cheap to display.
The first FactBox is expanded initially by default,the data retrieved for the fact box is not a complex query, and that it will execute quickly.


q Correctly set the LinkType property of datasources to minimize the number of queries sent to the server.

Using Data Contracts in X++ [AX 2012]


Microsoft Dynamics AX supports the use of .NET and X++ types as data contracts for service operation input and return parameters. This enables you to pass complex data types without having to explicitly implement XML serialization and deserialization. The data contract serialization and deserialization is handled by Windows Communication Foundation (WCF).
In order to serialize complex data types, we must define them as data contracts.
X++ Types
X++ provides support for data contract serialization through the following attributes.
·         DataContractAttribute – This attribute is applied to an X++ class and specifies that the class can be used as a data contract (that it should be serialized).
·         DataMemberAttribute – This attribute is applied to a parm method on an X++ data contract class and specifies that the data member should be serialized. The attribute can be applied to public and instance methods, as long as the method uses a get/set pattern that contains one optional parameter. The data type of the return type and the parameter should be the same. For example, [DataMemberAttribute] Int parmXX(int _x = x)
The X++ data contract attributes function just as the data contract attributes for .NET types.
The following X++ constructs can be used implicitly as data contracts and do not require markup with the data contract attributes:
·         Primitive types such as str, int, int64, real, guid, utcdatetime, and date. Primitive types are shared between services on the same integration port and stored in a shared types .xsd file.
·         Extended data types.
·         Enumerations including X++ boolean.
·         Collections in which all elements are the same type and all elements are of a type that is a valid data contract. This includes the Array class, which is part of Collections.
·         Tables and views. All columns and array fields are exposed as a System.Data.Dataset.
.NET Types
Any .NET type that can be serialized by WCF can be used as a parameter or return type by a service in Microsoft Dynamics AX. By default, WCF uses the Data Contract Serializer to serialize and deserialize data.

To use .NET types as parameters or return types in X++, we must first create a .NET assembly that contains the .NET data contract classes that have been decorated with the data contract attributes. We then add this assembly as a reference in the AOT, and we can use the data contracts in X++ service operations.

When using the DataContractSerializer, WCF serializes DateTime values as Coordinated Universal Time (UTC). When you use DateTime values in a data contract, you must pass them as UTC values and convert to local time in the client that calls the service.


Dynamics Ax on Cloud


SaaS – Software as a Service
IaaS – Infrastructure as a Service
PaaS – Platform as a Service

Multi-tenant (Serving multiple customers in the same instance of the software)

Today Microsoft Dynamics AX 2009 & 2012 are not designed to be multi-tenant, 100% SaaS offerings.
This applies for Microsoft Dynamics AX 2009 and Microsoft Dynamics AX 2012.

Microsoft does plan to have a total SaaS offering in the future for Microsoft Dynamics AX. Until then, Microsoft Dynamics AX will exist in the Cloud as sitting on top of IaaS, or in a Hybrid cloud mode.

The next release of AX, version 7, will be developed to run on Azure First!
Moving forward to Microsoft Dynamics AX 7.0, it is being developed to run 100% on Microsoft Azure, PaaS offering. It's being developed first, for the cloud, but still the same applies that it can 100% run on-premise.

This flexibility because not everyone wants to run 100% of their total business solution on the cloud, and companies want options.

For some it's all-in, everything, while others, it will be a hyrbid, best of breed for their case mix of SaaS, IaaS & PaaS cloud offerings that makes up their total overall solution.

Thursday, December 19, 2013

How To Flush label Files Using x++ code.

static void LabelFlush(Args _args)
{
    Label::flush('DTD', 'en-gb');
    Label::flush('DTD', 'en-us');
    Box::info('done');


}

How to update sales price for already created sales orders by applying latest trade agreements using x++ code

In one of  implementation project. I got a requirement in this Client wants to update sales orders that were created in past.Requirement was to update sales price by applying new trade agreements that were created later in system after the sales order creation.

I used the following code to update the sales price.

private void updateSalesPrice()
{
    SalesLine                   salesLine;
    PriceDiscPolicyCheckPolicy  checkPolicy;
    str                         text;
    SysOperationProgress        operationProgress;
    boolean                     salesLineFound;
    #AviFiles
    // 2013-09-25 #23667_DA0374 dkos: Update Sales Order Unit Price -->
    Dialog                      dialog;
    DialogField                 dfStartDate;
    DialogText                  dialogText;
    TransDate                   startDate;
    // 2013-09-25 #23667_DA0374 dkos: Update Sales Order Unit Price <-- font="">
    ;

    operationProgress = new SysOperationProgress();
    operationProgress.setCaption("@DTD849");
    operationProgress.setAnimation(#AviUpdate);

    // 2013-09-25 #23667_DA0374 dkos: Update Sales Order Unit Price -->
    dialog = new Dialog("@DTD847");
    dfStartDate = dialog.addField(extendedTypeStr(TransDate), "@DTD1042");
    dfStartDate.value(dateNull());

    text = "@DTD845" + '\n\n' +"@DTD846" ;

    dialogText = dialog.addText(text);
    dialogText.displayHeight(4);
    dialogText.displayLengthValue(50);

    if (dialog.run())
    {
        startDate = dfStartDate.value();
    // 2013-09-25 #23667_DA0374 dkos: Update Sales Order Unit Price <-- font="">
        ttsBegin;
        while select forUpdate salesLine
            where salesLine.SalesType   == SalesType::Sales
            &&    salesLine.SalesStatus <=  SalesStatus::Delivered
            &&   !salesLine.InventTransIdReturn //optimisation dkos 2013-09-25
            &&   (salesLine.ShippingDateRequested >= startDate || startDate == dateNull()) // 2013-09-25 #23667_DA0374 dkos: Update Sales Order Unit Price
        {
            salesLine.ManualEntryChangepolicy = 0;                  //optimisation dkos 2013-09-25
            // 2013-02-18 #20169 csek: Job to update SOprice -->
            salesLine.SystemEntryChangePolicy = 0;                  //optimisation dkos 2013-09-25
            // 2013-02-18 #20169 csek: Job to update SOprice <-- font="">

            checkPolicy = PriceDiscPolicyCheckPolicy::newFromParm(salesLine.PriceDiscResultFields::parmPriceDiscResultFields());
            salesLine.salesPurchLine::resetPriceAgreement();
            salesLine.setPriceAgreement(salesLine.inventDim(), null ,false,true);// 2013-02-07 #20169 csek: Job to update SOprice
            salesLine.LineAmount = salesLine.calcLineAmountForced(salesLine.SalesQty, checkPolicy);
            operationProgress.setText(strFmt("@DTD850",salesLine.SalesId));
            salesLine.update();

            salesLineFound = true;
        }
        ttsCommit;
    }
    if (salesLineFound)
    {
        info("@DTD1041"); // 2013-09-25 #23667_DA0374 dkos: Update Sales Order Unit Price
    }
}

Monday, December 9, 2013

Organization Structure Setups in Ax.


How to create Product in Ax2012 using x++ code.

In one of my implementation I had requirement in this I had to create product in Ax using x++ code. Below code explains how we can create product in Ax2012  in a specific company.


private void createProduct(itemId                        _itemId,
                          DataAreaId                    _dataAreaId = curext()
                          )

{
    EcoResProductService                    ecoResProdService;
    EcoResEcoResProduct                     ecoResProduct;
    EcoResEcoResProduct_Product_Distinct    product;
    EcoResEcoResProduct_Translation         translation;
    EcoResEcoResProduct_Identifier          identifier;
    EcoResEcoResProduct_StorageDimGroup     storageDimGroup;
    EcoResEcoResProduct_TrackingDimGroup    trackingDimensionGroup;
    InventTable                             localInventTable;
    ;

    if (!this.isProductAlreadyExists() && this.getItemId())
    {
        localInventTable = InventTable::find(_itemId);
        //Initialize the service object
        changeCompany(_dataAreaId)
        {
            ecoResProdService = EcoResProductService::construct();
            ecoResProduct     = new EcoResEcoResProduct();
            product           = new EcoResEcoResProduct_Product_Distinct();

            //Newly created and initialize product

            product.parmDisplayProductNumber(this.getItemId());
            product.parmProductType(EcoResProductType::Item);
            product.parmSearchName(this.getItemId());

            //Create a new translation object:
            Translation = product.createTranslation().addNew();

            Translation.parmDescription(this.getItemLongDescription());
            Translation.parmLanguageId(CompanyInfo::languageId());
            Translation.parmName(this.getItemShortDescription());
            Identifier = product.createIdentifier().addNew();

            Identifier.parmProductNumber(this.getItemId());

            if (localInventTable.storageDimensionGroup())
            {
                if (EcoResStorageDimensionGroup::find(localInventTable.storageDimensionGroup()).Name)
                {
                    storageDimGroup = product.createStorageDimGroup().addNew();
                    storageDimGroup.parmProduct(this.getItemId());
                    storageDimGroup.parmStorageDimensionGroup(EcoResStorageDimensionGroup::find(localInventTable.storageDimensionGroup()).Name);
                }
            }

            if (localInventTable.trackingDimensionGroup())
            {
                if (EcoResTrackingDimensionGroup::find(localInventTable.trackingDimensionGroup()).Name)
                {
                    trackingDimensionGroup = product.createTrackingDimGroup().addNew();
                    trackingDimensionGroup.parmProduct(this.getItemId());
                    trackingDimensionGroup.parmTrackingDimensionGroup(EcoResTrackingDimensionGroup::find(localInventTable.trackingDimensionGroup()).Name);
                }
            }

            ecoResProduct.createProduct().add(product);
            ecoResProdService.create(ecoResProduct);
            }
        }
}

How to create Product master using x++ code

We can create product master using x++ code. I have used below code in one of my implementation.



private void createProductMaster(itemId                        _itemId,
                                 DataAreaId                    _dataAreaId = curext()
                                )
{
    EcoResProductService                    ecoResProdService;
    EcoResEcoResProduct                     ecoResProduct;
    EcoResEcoResProduct_Product_Master      prodMaster;
    EcoResEcoResProduct_Translation         translation;
    EcoResEcoResProduct_Identifier          identifier;
    EcoResEcoResProduct_ProductDimGroup     prodDimGroup;
    EcoResEcoResProduct_StorageDimGroup     storageDimGroup;
    EcoResEcoResProduct_TrackingDimGroup    trackingDimensionGroup;
    InventTable                             localInventTable;
    ;

    if (!this.isProductAlreadyExists() && this.getItemId())
    {
        localInventTable = InventTable::find(_itemId);
        //Initialize the service object
        changeCompany(_dataAreaId)
        {
            ecoResProdService = EcoResProductService::construct();
            ecoResProduct     = new EcoResEcoResProduct();
            prodMaster        = new EcoResEcoResProduct_Product_Master();

            //Newly created and initialize prodMaster

            prodMaster.parmDisplayProductNumber(this.getItemId());
            prodMaster.parmProductType(EcoResProductType::Item);
            prodMaster.parmSearchName(this.getItemId());

            //Create a new translation object:
            Translation = prodMaster.createTranslation().addNew();

            Translation.parmDescription(this.getItemLongDescription());
            Translation.parmLanguageId(CompanyInfo::languageId());
            Translation.parmName(this.getItemShortDescription());
            Identifier = prodMaster.createIdentifier().addNew();

            Identifier.parmProductNumber(this.getItemId());
            if (localInventTable.productDimensionGroup())
            {
                ProdDimGroup = prodMaster.createProductDimGroup().addNew();
                ProdDimGroup.parmProduct(this.getItemId());
                ProdDimGroup.parmProductDimensionGroup(EcoResProductDimensionGroup::find(localInventTable.productDimensionGroup()).Name);
            }

            if (localInventTable.storageDimensionGroup())
            {
                if (EcoResStorageDimensionGroup::find(localInventTable.storageDimensionGroup()).Name)
                {
                    storageDimGroup = prodMaster.createStorageDimGroup().addNew();
                    storageDimGroup.parmProduct(this.getItemId());
                    storageDimGroup.parmStorageDimensionGroup(EcoResStorageDimensionGroup::find(localInventTable.storageDimensionGroup()).Name);
                }
            }

            if (localInventTable.trackingDimensionGroup())
            {
                if (EcoResTrackingDimensionGroup::find(localInventTable.trackingDimensionGroup()).Name)
                {
                    trackingDimensionGroup = prodMaster.createTrackingDimGroup().addNew();
                    trackingDimensionGroup.parmProduct(this.getItemId());
                    trackingDimensionGroup.parmTrackingDimensionGroup(EcoResTrackingDimensionGroup::find(localInventTable.trackingDimensionGroup()).Name);
                }
            }

            prodMaster.parmVariantConfigurationTechnology(EcoResVariantConfigurationTechnologyType::ConstraintBased);
            ecoResProduct.createProduct().add(prodMaster);
            ecoResProdService.create(ecoResProduct);
            }
        }
}

Sunday, December 8, 2013

How to release item using x++code in ax2012

How to release a item in Ax2012 through x++ code. Below code I have used in one of my requirement

public void releaseItem(DataAreaId     _dataAreaId)
{
    EcoResProduct   product;
    InventTable     inventTable;
    ;

    select firstOnly RecID from product
        where product.DisplayProductNumber == this.getItemId();

    if (product.RecId)
    {
        inventTable = inventTable::findByProductInCompany(product.RecId, _dataAreaId);
        if (!inventTable.RecId)
        {
            EcoResProductReleaseManagerBase::releaseProduct(product.RecId,CompanyInfo::findDataArea(_dataAreaId).RecId);
        }
    }

}

How to convert Product master to Product in Ax2012


In One of my implementation I was having a requirement in this I had to convert product master to product across the companies. You can find in below code how we can do this.


public void convertProductMasterToProduct(ItemId    _itemId,
                                          str       _supplyCompany = "",
                                          str       _demandCompany = "")
{
    EcoResProductMaster             master;
    EcoResDistinctProduct           distinctProduct;
    EcoResProductTranslation        productTranslation;
    InventTable                     inventtable;
    EcoResProductIdentifier         productIdentifier;
    str                             text;
    str                             shortText;
    ;

    ttsBegin;

    master = EcoResProductMaster::find(inventtable::find(_itemId).Product, true);

    if (master)
    {
        distinctProduct.clear();
        distinctProduct.initValue();
        distinctProduct.DisplayProductNumber = master.DisplayProductNumber;
        distinctProduct.SearchName = master.SearchName;
        distinctProduct.ProductType = EcoResProductType::Item;
        text = EcoResProductTranslation::findByProductLanguage(master.RecId, CompanyInfo::languageId()).Description;
        shortText = EcoResProductTranslation::findByProductLanguage(master.RecId, CompanyInfo::languageId()).Name;
        master.delete();
        distinctProduct.insert();

       productTranslation.clear();
       productTranslation.initValue();
       productTranslation.LanguageId = CompanyInfo::find().LanguageId;
       productTranslation.Name = shortText;
       productTranslation.Product = distinctProduct.RecId;
       productTranslation.Description = text;
       productTranslation.insert();

       productIdentifier.clear();
       productIdentifier.initValue();
       productIdentifier.ProductNumber = _itemId;
       productIdentifier.Product = distinctProduct.RecId;
       productIdentifier.insert();
        if (_supplyCompany)
        {
            changeCompany(_supplyCompany)
            {
                inventTable = InventTable::find(_itemId, true);
                if (inventtable)
                {
                    InventTable.Product = distinctProduct.RecId;
                    inventtable.StandardConfigId = "";
                    InventTable.update();
                }
            }
        }
        if (_demandCompany)
        {
            changeCompany(_demandCompany)
            {
                inventTable = InventTable::find(_itemId, true);
                if (inventtable)
                {
                    InventTable.Product = distinctProduct.RecId;
                    inventtable.StandardConfigId = "";
                    InventTable.update();

                }
            }
        }
    }
    ttsCommit;


}

Dynamics AX Solutions Excellence Certification Program

Did you know about Dynamics AX Solutions Excellence Certification Program?



Code comparison:-Ax2012

Troubleshoot

Issue

No colours when comparing code in AX.










Reason
the latest version of the browser, IE10, doesn't support the gradient filter (CSS in HTML) once used for displaying the left hand side colour boxes.

Work around
Just change the HTML code put in the ActiveX components. Comment the code as shown below.




Collection of Walkthroughs & Tutorials

Microsoft Dynamics AX 2012 Build numbers

Microsoft Dynamics AX 2012 Build numbers.




Code to call Ax project reverse engineering tool

Code to call Ax project reverse engineering tool
SysVisioAddIn               sysVisioAddIn   = SysVisioAddIn::construct();

sysVisioAddIn.parmModelType(SysVisioModelType::ERModel);
sysVisioAddIn.parmFile(fileName);
sysVisioAddIn.parmUserSelection(SysVisioUserSelection::SharedProject);
sysVisioAddIn.parmProjectNode(SysTreeNode::getSharedProject().AOTfindChild(projectNode.AOTname()));

sysVisioAddIn.run();

Modules names changes in MS Dynamics AX 2009 Vs. AX 2012

Modules names changes in MS Dynamics AX 2009 Vs. AX 2012





MODULES IN AX 2009



MODULES IN AX 2012

Inventory Management
·       Inventory Management
·       Product Information Management


Accounts Payable
·       Procurement and Sourcing
·       Accounts Payable


Accounts Receivable
·       Sales and Marketing
·       Accounts Receivable



General Ledger
·       General Ledger
·       Budgeting
·       Fixed Assets
·       Compliance and Internal controls

Cost Accounting
·       Cost Accounting

Bank
·       Cash and Bank Management


CRM
·       Moved to Sales and Marketing module

Master Planning
·       Master Planning



Production
·       Production control


Product Builder
·       Moved to Product Information Management






Shop floor Control
This Module is split into three and can be accessed from Home, Human resources and Production Control Modules.
·       Time and Attendance     – Human resources.
·       Clock In and Out – Home
·       Manufacturing execution – Production       control.

Human Resource
·       Human Resources

Questionnaire
·       Moved to Home

Expense Management
·       Travel and Expense


Projects
·       Project Management and Accounting (PSA)

Service
·       Service Management


Basic
·       Organizational Administration

Administration
·       System Administration