Search your query

Tuesday, September 19, 2017

Entity Extension Events Class (DMF - Data Management)

Operations (Insert, PostLoad) on AX Entity Extension class.

> Bring the List of Datasources value from Args() by using "DataEntityDataSourceRuntimeContext"

> Identify the required Datasource by using this keyword "dataEntityDataSourceStr"

> Write the code for update/insert into particular table / related tables.


For Example:

[PreHandlerFor(tableStr(HcmWorkerEntity), tableMethodStr(HcmWorkerEntity, insertEntityDataSource))]

    public static void HcmWorkerEntity_Pre_insertEntityDataSource(XppPrePostArgs args)
    {
        DataEntityDataSourceRuntimeContext  dataSourceCtx    = args.getArg('_dataSourceCtx');

        switch (dataSourceCtx.name())
        {
            case dataEntityDataSourceStr(HcmWorkerEntity, HcmWorkerTitle):

                HcmWorkerTitle      hcmWorkerTitle = dataSourceCtx.getBuffer();
                // Write your logic..
                break;
        }
    }




Wednesday, July 12, 2017

Display methods in AX Extension Table (Dynamics 365)

Display methods in AX Extension Table (Dynamics 365)


Steps:

1. Create a class and set a name like <"TableName" and "_" and "Extension" > (Example: PurchTable_Extension)

2. Class should be a static class  and public access specifier.

3. Add this attribute  [SysClientCacheDataMethodAttribute(true)] for each display method header.

4. Display method should be a static method and public access specifier.

5. Only one parameter that should be that particular table name.

6. Go to that particular form, Create one field and set the datasource property as the above mentioned table and in datamethod property, Type like ClassName::MethodName.
(Ex: HcmWorker_Extension::dispWorkerPositionTitle)

Example X++ Code: 

//This method is used to find the Position title of current worker.//

public static class HcmWorker_Extension
{
    // BP deviation documented
    [SysClientCacheDataMethodAttribute(true)]
    public static display HcmTitleId dispWorkerPositionTitle(HcmWorker _this)
    {
        HcmPositionWorkerAssignment workerAssignment;
        HcmPosition hcmPosition;
        HcmPositionDetail hcmPositionDetail;

        select firstonly worker, Position from workerAssignment
            where workerAssignment.Worker == _this.RecId
            join recid from hcmPosition
            where hcmPosition.RecId == workerAssignment.Position
            join Title, Position from hcmPositionDetail
            where hcmPositionDetail.Position == hcmPosition.RecId;

        return HcmTitle::find(hcmPositionDetail.Title).TitleId;
    }
}


Fetch CostCenter, Department Dimensions based on Worker's Position


// Fetch CostCenter, Department Dimensions based on Worker's Position //

     public static Name workerPositionCostCenter(HcmWorker _this)
    {
        HcmPositionWorkerAssignment     workerAssignment;
        HcmPosition                     hcmPosition;
        HcmPositionDefaultDimension     hcmPositionDefaultDimension;
        DimensionAttributeValueSet      dimensionAttributeValueSet;
        DimensionAttributeValueSetItem  dimensionAttributeValueSetItem;
        OMOperatingUnit                 omOperatingUnit;

        select firstonly worker, Position from workerAssignment
            where workerAssignment.Worker == _this.RecId
            join recid from hcmPosition
            where hcmPosition.RecId == workerAssignment.Position;

        select firstonly DefaultDimension from hcmPositionDefaultDimension
            where hcmPositionDefaultDimension.Position == hcmPosition.RecId

            join RecId from dimensionAttributeValueSet
                where dimensionAttributeValueSet.RecId ==          
                hcmPositionDefaultDimension.DefaultDimension

                join DimensionAttributeValueSet, DisplayValue from dimensionAttributeValueSetItem
                    where dimensionAttributeValueSetItem.DimensionAttributeValueSet ==
                             dimensionAttributeValueSet.RecId

                    join Name from omOperatingUnit
                        where  omOperatingUnit.OMOperatingUnitNumber ==
                              dimensionAttributeValueSetItem.DisplayValue
                            && omOperatingUnit.OMOperatingUnitType   ==
                                          OMOperatingUnitType::OMCostCenter; // You can change Operating Unit Type based on your requirement.

        return omOperatingUnit.Name;
    }

Friday, May 26, 2017

X++ code to attach the text file from local system directory and send an email.

class EmailTextFile
{      
   
    /// <summary>
    /// Attach the text file from local system directory and send an email using X++.
    /// </summary>
    /// <param name = "_args">The specified arguments.</param>

    public static void main(Args _args)
    {    
        EmailTextFile emailTextFile = new EmailTextFile();
       
        emailTextFile .sendMail();
    }
 
    private void sendMail()
    {
        SysMailerMessageBuilder     sysMailBuilder = new SysMailerMessageBuilder();
        SysMailerSMTP               smtp           = new SysMailerSMTP();
        System.IO.StreamReader      reader         = new System.IO.StreamReader(@"C:\test.txt");
        System.Byte[]               byte           = reader.CurrentEncoding.GetBytes(reader.ReadToEnd());
        System.IO.Stream            stream         = new System.IO.MemoryStream(byte);

        sysMailBuilder.setSubject("Regarding - sending mail");
        sysMailBuilder.setFrom("XXX@yyy.com");
        sysMailBuilder.addTo("yyy@zzz.com");
        sysMailBuilder.addAttachment(stream,'text file');
        smtp.sendNonInteractive(sysMailBuilder.getMessage());          
     
    }

}

Create and Save the text file in specific local directory

class CreateAndSaveTextFile
{      
   
    /// <summary>
    /// Create and Save the text file in specific local directory.
    /// </summary>
    /// <param name = "_args">The specified arguments.</param>
    public static void main(Args _args)
    {    
        CreateAndSaveTextFile createAndSaveTextFile= new CreateAndSaveTextFile ();

        createAndSaveTextFile.generateFile();      
    }

    private void generateFile()
    {
        System.IO.StreamWriter sw;
        InteropPermission perm = new InteropPermission(InteropKind::ClrInterop);
       
        try
        {
            perm.assert();

            sw = new System.IO.StreamWriter(@"C:\test.txt"); // specify the local file path for new file.
            sw.WriteLine('line 1');
            sw.WriteLine('line2');
            sw.Dispose();

            CodeAccessPermission::revertAssert();
         
        }
        catch
        {
            error("Error");
        }
    }
}

Friday, April 21, 2017

X++ Code to access Private / Protected methods and variables of AX class from Class extension (Get the table buffer value when extending the class).

Using System.Reflection;

We will not be able to access private / protected data member and methods of classes when you are going to create extension for them.

But there might be a situation to access those variables / methods from extension class. Reflection would be used in such this scenario.

Create an eventhandler extension class for VersioningPurchaseOrder -> and cosume PostConfirm method.

Using System.Reflection;

class VersioningPurchaseOrderEventHandlers
{
    /// <summary>
    /// accessing VersioningPurchaseOrder -> post_confirm method.
    /// </summary>
    /// <param name="args"></param>

    [PostHandlerFor(classStr(VersioningPurchaseOrder), methodStr(VersioningPurchaseOrder, confirm))]
    public static void VersioningPurchaseOrder_Post_confirm(XppPrePostArgs args)
    {
        VersioningPurchaseOrder   versioningPO;
        PurchTable                       purchTable;

        versioningPO = args.getThis();

        var bindFlags = BindingFlags::Instance | BindingFlags::NonPublic;

        var field = versioningPO.GetType().GetField("PurchTable", bindFlags);

        purchTable = field.getValue(versioningPO);

        if(purchTable)
        {
            info(purchTable.PurchId);
        }
    }

}

// We can also call / invoke the private / protected method(s) this VersioningPurchaseOrder class.

var bindFlags = BindingFlags::Instance | BindingFlags::NonPublic;

var createVersionMethod = versioningPO.GetType().GetMethod(methodStr(VersioningPurchaseOrder, createNewVersion), bindFlags);

if(createVersionMethod)
{
      createVersionMethod.Invoke(versioningPO , new System.Object[0]());
}

Wednesday, March 29, 2017

X++ code to create, write and download the Text files (*.txt)

/// <summary>
///  This Job is used to write Text files and download by browser.
/// </summary>

Public Static void main(Args args)
{
      TextStreamIo            writeStreamIO;
      Int lineNumber;
   
      //writeStreamIO = TextStreamIo::constructForWrite(0); // Code_Page = ANSI encoding.

      writeStreamIO = TextStreamIo::constructForWrite(); //Code_Page = UniCode encoding.

      writeStreamIO.outRecordDelimiter('\n');

      for(lineNumber =1; lineNumber <= 5; lineNumber++)
      {
              writeStreamIO.write(strFmt("Line number - %1", lineNumber ));
      }

      File::SendFileToUser(writeStreamIO.getStream(), @"C:\Test.txt");
}

Wednesday, February 15, 2017

Convert SSRS report to PDF file in AX 7 (Dynamics 365)

    /// <summary>
    /// SSRS to PDF
    /// </summary>
    public static void main(Args _args)
    {
        SrsReportRunController          controller = new SrsReportRunController();
        CustTransListContract            rdpContract = new CustTransListContract();
        SRSPrintDestinationSettings     settings;

        try
        {
            // Define report and report design to use
            controller.parmReportName(ssrsReportStr(CustTransList, Report));
            // Use execution mode appropriate to your situation
            //  controller.parmExecutionMode(SysOperationExecutionMode::ScheduledBatch);
            // Suppress report dialog
            controller.parmShowDialog(false);

            // Explicitly provide all required parameters
            controller.parmReportContract().parmRdpContract(rdpContract);

            // Change print settings as needed
            settings = controller.parmReportContract().parmPrintSettings();
            settings.printMediumType(SRSPrintMediumType::File);
            settings.fileFormat(SRSReportFileFormat::PDF);
            settings.fileName(@'d:\SSRS\CustTrans_SSRS.pdf');

            // Execute the report
            //controller.startOperation();
            controller.runReport();
        }
        catch( Exception::Error)
        {
            error("Conversion error");
        }
    }

Tuesday, February 14, 2017

X++ code to browse only Excel File type in browser from AX365 form:



** Need to create a class and extend the FileUploadTemporaryStorageStrategy class.

/// <summary>
/// File upload strategy for Excel files.
/// </summary>

class ExcelFileUploadTemporaryStorageStrategy extends FileUploadTemporaryStorageStrategy
{
    public str allowedFileTypes()
    {
        return ".xlsx,.xls";
    }

}


** Add this class as parameter in FileUploadTemporaryStorageResult class.


FileUploadTemporaryStorageResult result = File::GetFileFromUser(classStr(ExcelFileUploadTemporaryStorageStrategy)) as FileUploadTemporaryStorageResult;

Thursday, February 9, 2017

X++ Code to upload and read the Excel File in Dynamics 365 (Excel Import)

// <summary>
/// Upload and Read the Excel File in Dynamics 365
/// </summary>

        public void uploadAndReadExcelFile()
        {
            FileUploadTemporaryStorageResult result = File::GetFileFromUser() as FileUploadTemporaryStorageResult;

            if (result && result.getUploadStatus())
            {
                str ret;

                using (var package = new OfficeOpenXml.ExcelPackage(result.openResult()))
                {
                    var worksheets = package.get_Workbook().get_Worksheets();
                    var worksheet = worksheets.get_Item(1);
                    var cells = worksheet.get_Cells();
                    var cell = cells.get_Item(1,1);
                    ret = cell.get_Value();
                }

                info(ret);
            }

        }

X++ Code to create and write the Excel File in Dynamics 365 (Excel Export)


/// <summary>
/// Create and Download the Excel file.
/// </summary>

        public void createAndDownloadExcelFile()
        {
            DocuFileSaveResult saveResult = DocuFileSave::promptForSaveLocation("@ApplicationPlatform:OfficeDefaultWorkbookFileName", "xlsx", null, "Testing excel export");
         
            if (saveResult && saveResult.parmAction() != DocuFileSaveAction::Cancel)
            {
                saveResult.parmOpenParameters('web=1');
                saveResult.parmOpenInNewWindow(false);

                System.IO.Stream workbookStream = new System.IO.MemoryStream();
             
             
                System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();

                using (var package = new OfficeOpenXml.ExcelPackage(memoryStream))
                {
                    var worksheets = package.get_Workbook().get_Worksheets();
                    var worksheet = worksheets.Add("First sheet");
                    var cells = worksheet.get_Cells();
                    var cell = cells.get_Item(1,1);
                    cell.set_Value("MyColumnTitle");

                    package.Save();
                }

                memoryStream.Seek(0, System.IO.SeekOrigin::Begin);

                DocuFileSave::processSaveResult(memoryStream, saveResult); // Download the file.
            }
        }

Thursday, February 2, 2017

Download the file into Specific local system directory from file management URL

public static void main(Args _args)
{
        DocuRef                     docuReference;
        DocuValue                   docuValue;
        DocuAction                  docuActionClass;
        str                               url;
        Browser                     br = new Browser();
        var                         generator = new Microsoft.Dynamics.AX.Framework.Utilities.UrlHelper.UrlGenerator();

       
       docuReference = DocuRef::find(curExt(), RefRecId) // select the DocuRef table buffer record.

        if(docuReference)
        {
                docuValue = docuReference.docuValue();               
                 url = docuValue.Path;

                if (!url || docuValue.Type == DocuValueType::Others)
                {
                    str accessToken = DocumentManagement::createAccessToken(docuReference);
                    url =           Microsoft.Dynamics.AX.Framework.FileManagement.URLBuilderUtilities::GetDownloadUrl(docuValue.FileId, accessToken);
                } // getting only file management URL without Host.

                var currentHost   = new System.Uri(UrlUtility::getUrl());

                generator.HostUrl = currentHost.GetLeftPart(System.UriPartial::Authority);  
               // this above code is used to find the Host URL; for example, url = "https:usnconeboxax1aos.cloud.onebox.dynamics.com/"; 

                url = generator.HostUrl+"/"+ url;
  
                System.Net.WebClient wc = new System.Net.WebClient();

                wc.DownloadFile(url, @"C:\myfile.xlsx"); // specify the file path in second parameter.


If you want to convert this file into IO Stream (Memory stream): Use below code.

               System.IO.Stream        stream = File::UseFileFromURL(url);

Convert this stream into file again:

              var fileStream = new System.IO.FileStream(@"C:\myfile1.xlsx.", System.IO.FileMode::Create, System.IO.FileAccess::Write);
                stream.CopyTo(fileStream);

          }
}

X++ code to create file management URL and download the file from Browser

public static void main(Args _args)
{
        DocuRef                     docuReference;
        DocuValue                   docuValue;
        DocuAction                  docuActionClass;
        str                         url;
        Browser                     br = new Browser();
         

        docuReference = DocuRef::find(curExt(), RefRecId) // select the DocuRef table buffer record.

        if(docuReference)
        {
                docuValue = docuReference.docuValue();              
                 url = docuValue.Path;

                if (!url || docuValue.Type == DocuValueType::Others)
                {
                    str accessToken = DocumentManagement::createAccessToken(docuReference);
                    url =           Microsoft.Dynamics.AX.Framework.FileManagement.URLBuilderUtilities::GetDownloadUrl(docuValue.FileId, accessToken);
                }

               if(url)
              {
                     br.navigate(url, false, false); // This code is used to download the file from browser.
              }

Wednesday, February 1, 2017

Code to Convert Binary Stream into PDF file


    /// <summary>
    /// base64 (Binary) to PDF Converter
    /// </summary>

    public static void base642PDFConverter(Str _baseContent)
    {
        System.Byte[] pdfDocBuffer;
        System.IO.FileInfo fi_pdfDoc;
        System.IO.FileStream fs;
        str Content;
        ;
        // Grant clrinterop permission.
        new InteropPermission(InteropKind::ClrInterop).assert();

        pdfDocBuffer = System.Convert::FromBase64String(_baseContent);

        fi_pdfDoc = new System.IO.FileInfo(@'d:/SSRS/TestConversion.pdf');

        fs= new System.IO.FileStream(fi_pdfDoc.get_FullName(), System.IO.FileMode::Create,
        System.IO.FileAccess::Write);

        fs.Write(pdfDocBuffer, 0, pdfDocBuffer.get_Length());

        info("PDF is created in specified folder path.");

        fs.Close();

        //Revert the access
        CodeAccessPermission::revertAssert();
    }

Code to convert PDF file into Binary Stream


     /// <summary>
    /// PDF to base64 (Binary) Converter
    /// </summary>

    public static void main(Args args) //PDF2base64Converter
    {
        System.Byte[] pdfDocBuffer;
        System.IO.FileInfo fi_pdfDoc;
        System.IO.FileStream fs;
        str Content;
 
        // Grant clrinterop permission.
        new InteropPermission(InteropKind::ClrInterop).assert();

        //Load the file
        fi_pdfDoc = new System.IO.FileInfo(@'d:/SSRS/CustTrans_SSRS.pdf');

        //Initiallize the byte array by setting the length of the file
        pdfDocBuffer= new System.Byte[int642int(fi_pdfDoc.get_Length())]();

        // Stream the file
        fs= new System.IO.FileStream(fi_pdfDoc.get_FullName(), System.IO.FileMode::Open,        
        System.IO.FileAccess::Read);

        fs.Read(pdfDocBuffer, 0, pdfDocBuffer.get_Length());

        // Convert the file into a base64 string
        Content = System.Convert::ToBase64String(pdfDocBuffer, 0, pdfDocBuffer.get_Length());

        //Revert the access
        CodeAccessPermission::revertAssert();

        info(Content);
   }