Showing posts with label AX2012. Show all posts
Showing posts with label AX2012. Show all posts

Tuesday, 7 September 2021

CurrencyExchangeHelper class in Ax / X++

In AX 2012, a class CurrencyExchangeHelper is available to do conversions from one currency to another. Here are some important examples

This method will convert amounts from one currency to another currency:

Static void main(Args args)
{
CurrencyExchangeHelper currencyExchangeHelper;
AmountMst convertedamount;
CurrencyCode FromCurrency =  ‘USD’;
CurrencyCode toCurrency =  ‘EUR’;    
        AmountMst amountToConvert = 5000;
TransDate transactionDate = systemDateGet();

//initializing class CurrencyExchangeHelper
currencyExchangeHelper = CurrencyExchangeHelper::newExchangeDate(Ledger::current(), transactionDate);

//converting AED to USD
        convertedamount =  currencyExchangeHelper.calculateCurrencyToCurrency(toCurrency, fromCurrency, amountToConvert, true); 
 
info(strFmt(“Converted Amount: %1”, Convertedamount));
}

transaction currency into accounting currency:

Static void main(Args args)
{
CurrencyExchangeHelper currencyExchangeHelper;
AmountMst convertedamount;
CurrencyCode transCurCode = ‘EUR’;   
        AmountMst amountToConvert = 5000;
TransDate transactionDate = systemDateGet();
//initializing class CurrencyExchangeHelper
currencyExchangeHelper = CurrencyExchangeHelper::newExchangeDate(Ledger::current(), transactionDate );

//converting Transaction To Accounting
    convertedamount =  currencyExchangeHelper.calculateTransactionToAccounting(transCurCode, amountToConvert, true);  
info(strFmt(“Converted Amount: %1”, Convertedamount));

}

accounting  currency into transaction currency:

Static void main(Args args)
{
CurrencyExchangeHelper currencyExchangeHelper;
AmountMst convertedamount;
CurrencyCode AccCurCode = ‘USD’;   
        AmountMst amountToConvert = 5000;
TransDate transactionDate = systemDateGet();
//initializing class CurrencyExchangeHelper
currencyExchangeHelper = CurrencyExchangeHelper::newExchangeDate(Ledger::primaryLedger(CompanyInfo::findDataArea("ISL").RecId), transactionDate );

//converting accounting into trancastion currency
    convertedamount =  currencyExchangeHelper.calculateAccountingToTransaction(AccCurCode, amountToConvert, true);  

info(strFmt(“Converted Amount: %1”, Convertedamount));

}



Thursday, 2 September 2021

Get Company Currency in X++ / AX

Here is the one-line code to get company currency

static void  main(Args _args)
{
    info(CompanyInfo::standardCurrency());
    info(Ledger::accountingCurrency(CompanyInfo::current());
}

Wednesday, 1 September 2021

Converting amount in words using X++

During SSRS report development in ax sometimes we have a requirement to convert the amount into words, unfortunatly in SSRS report level, there is no such method available. You have to write VB code to do it.

The more simple solution would be to write the code in the report data provider class to perform conversion and store it into a field that can easily be used in the SSRS report

Here is the code you can convert the amount in words in Ax / D365FO 

private String255 AmountInWords(real _amount)

{

     int             amount;

     String255             amount2Words;

    amount       = real2int(round(_amount , 1));

    amount2Words = Global::numeralsToTxt(amount);

    amount2Words = subStr(amount2Words,5,strLen(amount2Words)-4);

    amount2Words = subStr(amount2Words,strLen(amount2Words)-10,-strLen(amount2Words));

    amount2Words = (amount2Words) + ' Only';

    return amount2Words;

}

there is a builtin function available in Global class as well, you can try this as well

Global::numeralsToTxt(Amount)


Tuesday, 31 August 2021

Get item Category hierarchy using X++ in Ax / D365FO

Here you can find the X++ code to get complete item Category hierarchy using X++ in Ax

Static void main(Args args)

ItemId itemId = "MT0001";
EcoResProductCategory EcoResProductCategory;
EcoResCategory EcoResCategory,EcoResCategoryNext;
EcoResCategoryId parentCategory;
List li = new List(Types::String);
ListEnumerator enumer;

select * from EcoResCategory
join RecId from EcoResProductCategory
where EcoResCategory.RecId == EcoResProductCategory.Category
&& EcoResProductCategory.Product == InventTable::find(itemId).Product;
parentCategory = EcoResCategory.ParentCategory;
li.addStart(EcoResCategory.Name);

while (parentCategory)
{
    select * from EcoResCategory
        where EcoResCategory.RecId == parentCategory;
    //&& EcoResCategory.ParentCategory != 0;
        parentCategory = EcoResCategory.ParentCategory;
        li.addStart(EcoResCategory.Name);
}

enumer = li.getEnumerator();

while (enumer.moveNext())
{
    info(enumer.current());
}
}

Find item attributes using X++ in Ax and D365FO

 static void GetAttribute(Args _args)

{

    inventTable                 InventTable;

    EcoResProductAttributeValue ecoResProductAttributeValue;

    EcoResAttribute             ecoResAttribute;

    EcoResValue                 ecoResValue;

    while select InventTable where InventTable.itemid == "0000001"

        join RecId from ecoResProductAttributeValue

        where ecoResProductAttributeValue.Product == InventTable.Product

            join Name from ecoResAttribute

            where ecoResProductAttributeValue.Attribute == ecoResAttribute.RecId

                join ecoResValue

                where ecoResValue.RecId == ecoResProductAttributeValue.Value

    {

        info(strFmt("%1 - %2 - %3", InventTable.ItemId, ecoResAttribute.Name, ecoResValue.value()));

    }

}

Sending Email using X++ / Sending Email in Ax / D365FO/ Ax 7

 Here is the complete class for sending email notifications in Ax and D365FO. Make sure the email template is already created

/// <summary>
/// Class can  be used for sending email
/// </summary>
class EmailNotification
{
    private  boolean isEmailSent(Map _mappings, str _recipientEmail, str _templateName)
    {
        boolean         isSucess;
        SysEmailTable   sysEmailTable;       
        sysEmailTable = sysEmailTable::find(_templateName);
        SysEmailMessageTable msg = SysEmailMessageTable::find(sysEmailTable.EmailId, sysEmailTable.DefaultLanguage);
        if (msg)
        {
            str messageBody = msg.Mail;
            messageBody = SysLabel::resolveLabels(messageBody, sysEmailTable.DefaultLanguage);
            messageBody = SysEmailMessage::stringExpand(messageBody, SysEmailTable::htmlEncodeParameters(_mappings));
            messageBody = strReplace(messageBody, '\n', '<br>');
            var builder = new SysMailerMessageBuilder()
                .setFrom(sysEmailTable.SenderAddr)
                .addTo(_recipientEmail)
                .setSubject(msg.Subject)
                .setBody(messageBody);
            var message = builder.getMessage();
            isSucess = SysMailerFactory::getNonInteractiveMailer().sendNonInteractive(message);
        }
        return isSucess;
    }
    /// <summary>
    /// Sending single emails
    /// </summary>
    /// <param name = "_sysEmailTable">SysEmailTable buffer</param>
    /// <param name = "_mappings">Map</param>
    /// <param name = "_recipient">Recipient detail</param>
    /// <param name = "_attachment">File attachement</param>
    /// <returns>True/false</returns>
    private  boolean sendSingleMail(SysEmailTable   _sysEmailTable,
                                Map                 _mappings,
                                str                 _recipient,
                                FilenameOpen        _attachment = '')
    {
        boolean     isSucess;
        try
        {
            SysEmailTable::sendMail(_sysEmailTable.EmailId,
                                _sysEmailTable.DefaultLanguage,
                                _recipient,
                                _mappings,
                                _attachment,
                                '' ,
                                true,
                                _sysEmailTable.SenderName,
                                true); 
            isSucess  = true;
        }
        catch(Exception::Error)
        {
            isSucess = false;
        }
        return isSucess;
    }
    /// <summary>
    /// Method used for sending email
    /// </summary>
    /// <param name = "_emailTemplate">Email template name</param>
    /// <param name = "_mappings">Map</param>
    /// <param name = "_recipient">Recipient detail</param>
    /// <param name = "_attachment">File attachement</param>
    /// <returns>True/false</returns>
    public Static boolean sendEmail(str         _emailTemplate,
                                Map             _mappings,
                                str             _recipient   = '',
                                FilenameOpen    _attachment  = '')
    {
        SysEmailTable           sysEmailTable;
        boolean                 isSucess;
        sysEmailTable           = SysEmailTable::find(_emailTemplate); 
        EmailNotification emailNotification   =   new EmailNotification();
        if (sysEmailTable)
        {
            isSucess = emailNotification.isEmailSent(_mappings, _recipient, _emailTemplate);
        }
        else
        {
            info(strFmt("Email Template Not Found"));
        }
        return isSucess;
    }
}

Get Worker Primary Position in valid date time in X++ / Worker Primary Position in Ax

Here is the X++ code to find  Worker Primary Position in given date time

public static HcmWorkerPrimaryPosition findByWorker(

    HcmWorkerRecId      _worker,

    utcdatetime         _validFrom = DateTimeUtil::utcNow(),

    utcdatetime         _validTo   = _validFrom,

    boolean             _forUpdate = false,

    ConcurrencyModel    _concurrencyModel = ConcurrencyModel::Auto)

    {

        HcmWorkerPrimaryPosition hcmWorkerPrimaryPosition;


        hcmWorkerPrimaryPosition.selectForUpdate(_forUpdate );

        if (_forUpdate && _concurrencyModel != ConcurrencyModel::Auto)

        {

            hcmWorkerPrimaryPosition.concurrencyModel(_concurrencyModel);

        }


        if (_worker)

        {

            if (prmisdefault(_validFrom) && prmisdefault(_validTo))

            {

                select firstonly hcmWorkerPrimaryPosition

                    where hcmWorkerPrimaryPosition.Worker == _worker;

            }

            else if (_validFrom == _validTo)

            {

                select firstonly ValidTimeState(_validFrom) hcmWorkerPrimaryPosition

                    where hcmWorkerPrimaryPosition.Worker == _worker;

            }

            else

            {

                select ValidTimeState(_validFrom, _validTo) hcmWorkerPrimaryPosition

                    where hcmWorkerPrimaryPosition.Worker == _worker;

            }

        }


        return hcmWorkerPrimaryPosition;

    }


current database name in Ax

There is a class available in AX SysSQLSystemInfo. Using this we can get the current database name

static void databse_name(Args _args)
{
    info(SysSQLSystemInfo::construct().getloginDatabase());
}

Creating Default Dimension using X++ / D365FO / AX-2012

X++ code to create default dimension in both D365FO and AX-2012

public class DefaultDimesnionHelper

{

    public static DimensionDefault createDefaultDimension(container conAttribute,container attributeValue)
    {
        DimensionAttributeValueSetStorage   valueSetStorage                     new DimensionAttributeValueSetStorage();
        DimensionDefault        result;
        DimensionAttribute      dimensionAttribute;
        DimensionAttributeValue dimensionAttributeValue;
        int                     i;
        
  
        container               conAttr = conAttribute;
        container               conValue = attributeValue;
        str                     dimValue;
  
        for (i = 1; i <= conLen(conAttr); i++)
        {
            dimensionAttribute = dimensionAttribute::findByName(conPeek(conAttr,i));
      
            if (dimensionAttribute.RecId == 0)
            {
                continue;
            }
      
            dimValue = conPeek(conValue,i);
      
            if (dimValue != "")
            {
                // The last parameter is "true". A dimensionAttributeValue record will be created if not found.
                dimensionAttributeValue =
                    dimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute,dimValue,false,true);
          
                // Add the dimensionAttibuteValue to the default dimension
                valueSetStorage.addItem(dimensionAttributeValue);
            }
        }
  
        result = valueSetStorage.save();
        return result;
    }
}

Get Employee Dimensions using X++

 X++ code to find employee dimension

static void employeeDim(Args _args)

    {
        HcmEmployment                         hcmEmployment;
        DimensionAttributeValueSetItem  setItem;
        DimensionAttributeValue              dimAttrValue;
        DimensionAttribute                      dimAttribute;
        ;

        dimAttribute    = DimensionAttribute::findByName('CostCenter');

        while select hcmEmployment
              join RecId, DisplayValue from setItem
              where setItem.DimensionAttributeValueSet ==
              hcmEmployment.DefaultDimension
              join dimAttrValue
              where dimAttrValue.RecId == setItem.DimensionAttributeValue &&
              dimAttrValue.DimensionAttribute == dimAttribute.RecId       &&
              dimAttrValue.IsDeleted == false
        {
            info(strFmt("Employee personnel number  = %1  %2 = %3 ",
           HcmWorker::find(hcmEmployment.Worker).PersonnelNumber,
           dimAttribute.Name, setItem.DisplayValue));
        }
    }

Get List of Tables using X++

 Here is the X++ code to find the complete list of tables in Ax 2012 and D365FO

public void getTableList()   

{
    SysDictTable sysDictTable;
    Dictionary dict = new Dictionary();
    DictTable dictTable;
    
    for (int i=1; i<=dict.tableCnt(); i++)
    {
        sysDictTable=new SysDictTable(dict.tableCnt2Id(i));
        }
}

Run AX report using X++

       Args                     args;      ReportRun          report;     salesLineProductPartProd salesLineProductPartProdLocal;     ;     ...