Friday, June 4, 2021

Importing data through Data entities using X++

This post shows code to import data in D365 F&O through Data entities using X++ code. One of the best part of this approach is that no more complex joins and relevant tables need to be populate, it just utilizes the power of Data entity and get the data in the system.

To begin with, we will first need to define a data project in Data management workspace as shown in the pictures below.




Step1:
Define a function that will find and return DMFDefinitionGroup.

    private DMFDefinitionGroup findDMFDefinitionGroup(Filename   _fileName)
    {
        DMFDefinitionGroup definitionGroup;
        
        if (strStartsWith(_fileName, 'WorkerEnrolledBenefitDetail'))
        {
            select firstonly definitionGroup
                where definitionGroup.DefinitionGroupName == 'Pledge-GLImport'; //DMF import data project
        }        

        return definitionGroup;
    }

Step2:
Define a function that will find and return DMFDefinitionGroupEntity based on DMFDefinitionGroup.

    private DMFDefinitionGroupEntity findDMFDefinitionGroupEntity(DMFDefinitionGroup _definitionGroup)
    {
        DMFDefinitionGroupEntity definitionGroupEntity;
        DMFEntity dmfEntity;

        select firstonly RecId, Entity from definitionGroupEntity 
            exists join dmfEntity
        where definitionGroupEntity.DefinitionGroup == _definitionGroup.DefinitionGroupName
           && dmfEntity.EntityName == definitionGroupEntity.Entity;

        if (!definitionGroupEntity)
        {
            throw error(strFmt("@DMF:DMFNoEntityExists", _definitionGroup.DefinitionGroupName));
        }

        return definitionGroupEntity;
    }

Step3:
Define a function that will apply transforms which work as mapping fields.

    private DMFLocalFilePath applyTransforms(SharedServiceUnitFileID _uploadedStatement, DMFDefinitionGroup definitionGroup)
    {
        DMFDefinitionGroupEntity    definitionGroupEntity = this.findDMFDefinitionGroupEntity(definitionGroup);
        DMFExecutionId              executionId = DMFUtil::setupNewExecution(definitionGroup.DefinitionGroupName);

        DMFDefinitionGroupExecution execution = DMFDefinitionGroupExecution::find(
            definitionGroup.DefinitionGroupName,
            definitionGroupEntity.Entity,
            executionId,
            true);

        execution.IsTransformed = NoYes::No;
        DMFLocalFilePath filePath = execution.applyTransforms(_uploadedStatement);

        DMFExecution e = DMFExecution::find(executionId, true);
        e.delete();

        return filePath;
    }

Step4:
Lastly we will write a function which can be called to upload a file by passing filename and IO stream.

    /// <summary>
    ///  Import files from Input Blob and write it using DIXF entities
    /// </summary>
    /// <param name = "_memory">File stream</param>
    /// <param name = "_fileName">Read file name</param>
    /// <returns></returns>
    private void importFromBlob(System.IO.Stream  _memory, str _fileName)
    {
        SharedServiceUnitFileID     fileId;
        DMFDefinitionGroup          definitionGroup;
        DMFDefinitionGroupEntity    definitionGroupEntity;
        DMFExecutionId              executionId;
        DMFDefinitionGroupExecution execution;

        //Should be used to get file into FileUploadTemporaryStorageResult object
        FileUploadTemporaryStorageResult result = File::SendFileToTempStore_GetResult(_memory, _fileName);

        if (result && result.getUploadStatus())
        {
            fileId = result.getFileId();

            definitionGroup = this.findDMFDefinitionGroup(_fileName);

            this.applyTransforms(fileId, definitionGroup);

            definitionGroupEntity = this.findDMFDefinitionGroupEntity(definitionGroup);
            executionId = DMFUtil::setupNewExecution(definitionGroup.DefinitionGroupName);

            // Find execution
            execution = DMFDefinitionGroupExecution::find(definitionGroup.DefinitionGroupName, definitionGroupEntity.Entity, executionId, true);
            execution.FilePath = fileId;
            execution.IsTransformed = NoYes::Yes;
            execution.IsSelected = NoYes::Yes;
            execution.ExecuteTargetStep = NoYes::Yes;
            execution.update();

            setPrefix(strFmt("@SYS73667", _fileName));

            // Import the file via quick import DMF
            DMFQuickImport::doPGImport(definitionGroup.DefinitionGroupName, executionId, true);

            //deletes file
            result.deleteResult();
        }
    }

No comments:

Post a Comment