Monday, August 21, 2023

X++ Code to import file using data entity

internal final class TestDataEntityImport
{
    public static void main(Args _args)
    {
        FileUploadTemporaryStorageResult    fileUpload;
        AsciiStreamIo                       file;
        System.IO.Stream                    stream;

        fileUpload  = File::GetFileFromUser() as FileUploadTemporaryStorageResult;

        file        = AsciiStreamIo::constructForRead(fileUpload.openResult());

        stream      = file.getStream();
        
        TestDataEntityImport  TestDataEntityImport = new TestDataEntityImport();

        TestDataEntityImport.importFromBlob(stream,fileUpload.getFileName());
    }

    public DMFDefinitionGroup findDMFDefinitionGroup(Filename   _fileName)
    {
        DMFDefinitionGroup definitionGroup;
        
        if (strStartsWith(_fileName, 'Test'))
        {
            select firstonly definitionGroup
                where definitionGroup.DefinitionGroupName == 'TestVendorPlantImport'; //DMF import data project
        }

        return definitionGroup;
    }

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

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

    public 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
            DMFQuickImportExport::doPGImport(definitionGroup.DefinitionGroupName, executionId, true);

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

}
Importing Files Using Data Management in D365FO/X++

Data migration and integration are critical aspects of any business application, and Microsoft Dynamics 365 Finance and Operations (D365FO) offers a powerful toolset to facilitate these tasks. One of the key features for importing data is the Data Management framework (DMF). In this blog post, we'll explore how to use X++ code to import files using the Data Management framework in D365FO. This code is useful in scenarios where you want to call data entity import throgh integration and also by this code you dont need to worry about how many columns user is going to add later.

Background

The X++ code provided in this blog post demonstrates how to import files using the Data Management framework in D365FO. This code is encapsulated within the TestDataEntityImport class and consists of several methods that work together to achieve a successful file import.


internal final class TestDataEntityImport
{
    public static void main(Args _args)
    {
        FileUploadTemporaryStorageResult fileUpload;
        AsciiStreamIo file;
        System.IO.Stream stream;

        fileUpload = File::GetFileFromUser() as FileUploadTemporaryStorageResult;
        file = AsciiStreamIo::constructForRead(fileUpload.openResult());
        stream = file.getStream();
        
        TestDataEntityImport TestDataEntityImport = new TestDataEntityImport();
        TestDataEntityImport.importFromBlob(stream, fileUpload.getFileName());
    }

    public DMFDefinitionGroup findDefinitionGroup(Filename _fileName)
    {
        DMFDefinitionGroup definitionGroup;
        
        if (strStartsWith(_fileName, 'Test'))
        {
            select firstonly definitionGroup
             where definitionGroup.DefinitionGroupName == 'TestVendorPlantImport'; 
                //DMF import data project
        }

        return definitionGroup;
    }
    public 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;
    }

	public 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.findDefinitionGroup(_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
            DMFQuickImportExport::doPGImport(definitionGroup.DefinitionGroupName, executionId, true);

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

Getting Started

The main method serves as the entry point for the file import process. Let's break down the code step by step:

  1. File Upload: The code begins by getting a file from the user using the File::GetFileFromUser() method. The file is uploaded and stored in temporary storage.
  2. File Reading: The uploaded file is then read using an AsciiStreamIo object. This object provides methods to read data from the uploaded file.
  3. Stream Handling: The stream variable is assigned the stream of the file data, which will be used to process the contents of the file.

Conclusion

In this blog post, we've explored how to use X++ code to import files using the Data Management framework in Dynamics 365 Finance and Operations. The provided code demonstrates the step-by-step process of uploading a file, identifying the appropriate DMF Definition Group and Entity, applying transformations, and executing the import.

The Data Management framework in D365FO simplifies data migration and integration tasks, enabling organizations to efficiently import and process large volumes of data. By leveraging the power of X++ and the DMF, businesses can ensure accurate and streamlined data management within their Dynamics 365 environment.

Thursday, August 3, 2023

Attributes cannot be deleted while dependent Provisioned channel product attribute exist. Delete dependent Provisioned channel product attribute and try again.

How to Delete Attributes with Dependent Provisioned Channel Product Attributes in D365 Finance and Operations

Deleting Attributes with Dependent Provisioned Channel Product Attributes

Struggling to remove attributes due to linked Provisioned channel product attributes? Discover a simple solution below!

The Problem:

Trying to delete attributes, but encountering obstacles due to connected Provisioned channel product attributes.

The Solution:

Follow these steps to regain control:

  1. Step 1: Access the Table Browser by adding below line after your dynamics url
    /?mi=SysTableBrowser&prt&limitednav=true&TableName=RETAILPROVISIONEDCHANNELPRODUCTATTRIBUTE&cmp=dat
  2. Step 2: Identify Linked Records
    Locate records connected to the attribute you want to delete. These ties are causing the issue.
  3. Step 3: Delete Dependent Records
    Bid farewell to linked records to break the dependency.

For more insights and learning on #MicrosoftLearn and #D365FO, check out Microsoft Learn's Dynamics 365 Finance and Operations resources.

Post partial packing slip in D365FO

How to Post a Partial Packing Slip in D365FO and AX 2012 How to Post a Partial Packing Slip in D365FO and AX 2012 Understanding t...