Tuesday, 31 August 2021

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

Get Current language in AX 2012 and D365FO

 Here is the X++ code to find the current language


static void main(Args _args)
{


info(companyinfo::languageId());

    // user
    info(new xInfo().language());\


    // system
    info(SystemParameters::getSystemLanguageId());

}

Scheduling Batch Job using X++

X++ code for  Scheduling Batch Job

static void JobSchedule(Args _args)

    {
        BatchHeader objBatchheader;
        SysRecurrenceData sysRecurrenceData;       
        BatchInfo objBatchInfo;
        BatchRetries noOfRetriesOnFailure = 0;
        Batch batch;
        BatchJob batchJob;
        RetailCDXScheduleRunner objRetailSchedule;
        ;

        // Setup the RunBaseBatch Job
        objBatchheader = Batchheader::construct();
        objRetailSchedule = new RetailCDXScheduleRunner();
        objBatchInfo = objRetailSchedule.batchInfo();
        objBatchInfo.parmRetriesOnFailure(noOfRetriesOnFailure);
        objBatchInfo.parmCaption("Description should be here"); // Description Batch Job
        objBatchInfo.parmGroupId('YourBatchGroup'); // Batch Gorup
        objBatchInfo.parmBatchExecute(NoYes::Yes);
        objBatchheader.addTask(objRetailSchedule);

        // Set the recurrence data
        sysRecurrenceData = SysRecurrence::defaultRecurrence();
        SysRecurrence::setRecurrenceStartDateTime(sysRecurrenceData, DateTimeUtil::addSeconds(DateTimeUtil::utcNow(), 20)); // Set range of recurrence
        SysRecurrence::setRecurrenceNoEnd(sysRecurrenceData);
        SysRecurrence::setRecurrenceUnit(sysRecurrenceData, SysRecurrenceUnit::Minute); // Set reccurence pattern
        objBatchheader.parmRecurrenceData(sysRecurrenceData);
        // Set the batch alert configurations
        objBatchheader.parmAlerts(NoYes::No, NoYes::Yes, NoYes::No, NoYes::Yes, NoYes::Yes);
        objBatchheader.save();

        // Update the frequency to run the job to every two minutes
        ttsbegin;
        select forupdate batchJob
            join batch
            where batchJob.RecId == batch.BatchJobId
            && batch.ClassNumber == classnum(RetailConnScheduleRunner);

        sysRecurrenceData = batchJob.RecurrenceData;
        sysRecurrenceData = conpoke(sysRecurrenceData, 8, [10]);
        batchJob.RecurrenceData = sysRecurrenceData;
        batchJob.update();
        ttscommit;
    }

Get ledger dimension values for active account structure in AX 2012 & D365FO

Here is the code  for  ledger dimension values for active account structure

public static DimensionValue getdimension(LedgerDimensionAccount _ledgerDimension, 

Name _dimensionName )

    {
        DimensionAttributeLevelValueAllView dimAttrView; //View that will display all values for ledger dimensionsDimensionAttribute dimAttr; 

        select DisplayValue from dimAttrViewwhere dimAttrView.ValueCombinationRecId == _ledgerDimension 
        return dimAttrView.DisplayValue;
    }

Monday, 30 August 2021

Uploading and download file in D365FO

Create a simple form with two buttons file upload & download.

For Upload:

Using button clicked event: File::GetFileFromUser()

For Download:

For Download button: new Browser().navigate(fileUrl).


[Form]

public class SLD_UploadDownload extends FormRun
{
    str fileUrl;
 
    [Control("Button")]
    class UploadButton
    {
        public void clicked()
        {
            FileUploadTemporaryStorageResult result = File::GetFileFromUser() as FileUploadTemporaryStorageResult;
            if (result && result.getUploadStatus())
            {
                fileUrl = result.getDownloadUrl();
                info(fileUrl);
            }
        }
    }
 
    [Control("Button")]
    class DownloadButton
    {
        public void clicked()
        {
            new Browser().navigate(fileUrl);
        }
    }
}

Run AX report using X++

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