Tuesday 3 January 2023

How to setup workflow in D365 AX Finance & operations

Workflow has become necessities in an organization where any action of one user is needed to be approved by his senior or responsible role member. For eg – Creating new Fixed assets or posting invoices may need approval before posting.

Trying to set up a workflow in D365 Finance & operations AX for any module, You first need to do some setup to enable it. A complete detailed steps guide is provided below. If you like the article, don’t forget to share the article

Time needed: 5 minutes.

Setup workflow

  1. Go to Organisation administration -> Number sequence

    Click on number sequence on New tab for generating new number sequence
    Workflow parameters -- Finance and Operations

  2. Define number sequence

    Define number sequence code ,name in shared scope and add ######### (9#) in alphanumeric segment as shown belowDefine Number sequences -- Finance and Operations

  3. Add 1st Reference

    Under Workflow area, add Instance Id reference as shown belowInstance reference workflow-- Finance and Operations

  4. Similarly, add 2nd reference for Workflow ID

    After adding 2nd reference, you’ll have set up like below screenshotReference workflow- Fixed asset-Number sequences -- Finance and Operations

  5. Go to System administration -> Workflow -> Workflow infrastructure configuration

    Select an existing user to be used for batch workflow execution and define minutes for workflow batch job execution.
    Refer below screenshotWorfklow Infrastructure configuration

  6. Verify Batch job created by the system after the above configuration

    Go to System administration ->Inquiries -> Batch jobs
    and filter in the job description for workflow. You’ll have 3 batch jobs enabled for a workflow like below screenshot

After following the above 6 easy to understand steps, you can now easily setup any ERP module workflow without any problem. I hope this article helped you learn how you can setup a workflow in D365 Finance & operations AX. Don’t forget to share this article.

Tuesday 26 October 2021

Get Ledger Dimension By Merging Main Account and Default Dimensions in D365 X++

Hello Guys,

Here is the post to convert the Default dimension to the ledger dimension.


protected DimensionDynamicAccount getLedgerDimension(mainAccountNum _mainAccountId,                                                                                                          RefRecId _defaultDimension)

    {

        mainAccountNum                      mainAccountId = _mainAccountId;

        MainAccount                         mainAccount;

        DimensionAttribute                  dimensionAttribute;

        DimensionAttributeValue             dimensionAttributeValue;

        DimensionSetSegmentName             dimensionSet;

        DimensionStorage                    dimensionStorage;

        LedgerAccountContract               ledgerAccountContract = new LedgerAccountContract();

        DimensionAttributeValueContract     valueContract;

        DimensionAttributeValueSetStorage   dimStorage;

        List                                valueContracts = new List(Types::Class);

        Counter                             i;

        int                                 hierarchyCount;

        int                                 hierarchyIdx;

        RefRecId                            recordvalue;


        mainAccount = MainAccount::findByMainAccountId(mainAccountId);

        recordvalue = DimensionHierarchy::getAccountStructure(mainAccount.RecId,Ledger::current());

        hierarchyCount = DimensionHierarchy::getLevelCount(recordvalue);

        DimensionSet = DimensionHierarchyLevel::getDimensionHierarchyLevelNames(recordvalue);


        for(hierarchyIdx = 1;hierarchyIdx<=hierarchyCount;hierarchyIdx++)

        {

            if(hierarchyIdx == 1)

            {

                continue;

            }

     

            // _defaultDimension is a RecId that combines all Dimension Values

            dimStorage = DimensionAttributeValueSetStorage::find(_defaultDimension);

   

            for (i= 1 ; i<= dimStorage.elements() ; i++)

            {

                if(DimensionAttribute::find(dimStorage.getAttributeByIndex(i)).Name == DimensionSet[hierarchyIdx])

                {

                    dimensionAttribute = DimensionAttribute::findByLocalizedName(DimensionSet[hierarchyIdx],false, CompanyInfo::find().LanguageId);


                    if(dimensionAttribute)

                    {

                        dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute,dimStorage.getDisplayValueByIndex(i));

                        if(dimensionAttributeValue)

                        {

                            ValueContract = new DimensionAttributeValueContract();

                            ValueContract.parmName(dimensionAttribute.Name) ;

                            ValueContract.parmValue(dimensionAttributeValue.CachedDisplayValue);

                            valueContracts.addEnd(ValueContract);

                        }

                    }

                    continue;

                }

            }

        }

        LedgerAccountContract.parmMainAccount(mainAccountId);

        LedgerAccountContract.parmValues(valueContracts);

        dimensionStorage = DimensionServiceProvider::buildDimensionStorageForLedgerAccount(LedgerAccountContract);

        return DimensionAttributeValueCombination::find(dimensionStorage.save()).RecId;

    }

Tuesday 9 July 2019

Hey again,

Today let's see how to enable and disable the Form controls using code.

FormRun             formRun = sender.formRun();

formRun.control(formRun.controlId(formControlStr(SalesTable, CheckJournal))).enabled(false);

It's that simple!!!


Tuesday 30 April 2019

Delete File/ Folder from Azure storage account in D365 using X++ code

This code will help you to delete list of files in a folder using CloudBlobContainer reference

public void deleteFilesFromAzure(CloudBlobContainer _blobContainer)
{
CloudBlobDirectory blobDirectoryToDelete;
System.Collections.IEnumerable listToDelete;
System.Collections.IEnumerator listEnumeratorToDelete;
CloudBlockBlob blobToDelete;

blobDirectoryToDelete = _blobContainer.GetDirectoryReference("File/ folder name");

listToDelete = new System.Collections.Generic.List<str>();

listToDelete =  blobDirectoryToDelete.ListBlobs(false, 0, null, null);

listEnumeratorToDelete = listToDelete.getEnumerator();

while  (listEnumeratorToDelete.moveNext())
{
blobToDelete = listEnumeratorToDelete.get_Current();
blobToDelete.DeleteIfExists(DeleteSnapshotsOption::None, null, null, null);
}
}

Thanks,
DAXBuddy

Convert Base64(PDF file) to Memory stream in D365

Now converting Base64 to Memory stream is a single piece of code. 

Here you go...

System.IO.MemoryStream memoryStream = Binary::constructFromContainer(BinData::loadFromBase64("Base64 Value")).getMemoryStream() as System.IO.MemoryStream;

Thanks,
DAXBuddy

Get all files (Blobs) in a list from Azure storage container in D365 using X++ code

Now a days Microsoft have moved everything to Azure. But in D365 fetching blobs as a list from a storage container is still tricky. Here in this blog code you'll be able to get all the blobs from Azure container in a single list.

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;

class Azure
{
    public void processAzureBlobFiles()
    {      
         var storageCredentials = new Microsoft.WindowsAzure.Storage.Auth.StorageCredentials("Storage account name", "Access key");

CloudStorageAccount storageAccount = new Microsoft.WindowsAzure.Storage.CloudStorageAccount(storageCredentials, true);

CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

CloudBlobContainer blobContainer = blobClient.GetContainerReference("Container Name");

System.Collections.IEnumerable list = new System.Collections.Generic.List<str>();
list = blobContainer.ListBlobs(null, false, 0, null, null);
System.Collections.IEnumerator listEnumerator = list.getEnumerator();

while  (listEnumerator.moveNext())
{
CloudBlockBlob blob = listEnumerator.get_Current();

if (blob.Exists(null, null))
{
        str file = blob.StorageUri.PrimaryUri.AbsoluteUri;
str fileName = blob.Name;
}
}
    }
}

"Storage account name" Can be taken from Azure -> Storage accounts -> Settings -> Access keys -> Storage account name

"Access key" Can be taken from Azure -> Storage accounts -> Settings -> Access keys -> Key1 or Key2


"Container Name" Can be taken from Azure -> Storage accounts -> Blobs -> Container name

Thanks,
DAXBuddy