Wednesday 21 October 2015

AX 2012 Label ids are being displayed in Security roles form instead of text?

Hi,
I recently faced this issue where labels were appearing in the security roles form.
And surprisingly, those labels existed in AX.

To investigate further, I opened up my SecurityRole table and found out that AX had got Label ids in the Name and Description column instead of actual text. To fix this, I simply ran an X++ job that updated the table.

static void updateSecurityTableLabels(Args _args)
{
   SecurityRole role;
   SecurityTask task;
   LanguageId LanguageId = CompanyInfo::find().LanguageId;
   LanguageId fallBackLanguageId = "en-us";
   str newLabelStr;
   #define.LabelPrefix('@DMF*')
   ttsBegin;
   while select forUpdate role
   {
       if(role.Description like #LabelPrefix)
       {
           newLabelStr = new Label(LanguageId).extractString(role.Description);
           if(newLabelStr like #LabelPrefix)
           {
               newLabelStr = new Label(fallBackLanguageId).extractString(role.Description);
           }
           role.Description = newLabelStr;
           role.doUpdate();
       }
       if(role.name like #LabelPrefix)
       {
           newLabelStr = new Label(LanguageId).extractString(role.name);
           if(newLabelStr like #LabelPrefix)
           {
               newLabelStr = new Label(fallBackLanguageId).extractString(role.name);
           }
           role.name = newLabelStr;
           role.doUpdate();
       }
   }
   ttsCommit;
   info("Done");
}


Sunday 9 August 2015

Microsoft Dynamics AX 7 (Rainier) What's new?

Microsoft Dynamics AX is a multi-language, multi-currency enterprise resource planning (ERP) business solution with comprehensive global business management features for financial, human resources, and operations management as well as additional industry capabilities for retailers, professional service industries, financial service businesses, manufacturers, and public sector organisations.
Dynamics AX 7.0 or AX2015, also known under the code name ‘Rainier,’ promises to impress AX users by delivering a new platform for AX deployments including on premises, public and private clouds options. It mainly focuses on offering customers precisely what they need, exactly when they need it, simultaneously providing a better understanding of the business operations and its processes.
The product strategy followed for Microsoft Dynamics AX 7 will be mobile first – cloud first.
  • Mobile first – the new enhancements ensure that the application experience, regardless of the device platform it’s accessed on, remains the same for the user.
  • Cloud first – is focused on AX 7’s new optimised platform which is suitable for both public and private cloud deployments with a “what you need, when you need it” approach on Windows Azure.

Key features in Dynamics AX 7:
1) Improved cloud access and mobility
As mobile devices begin to take the place of the traditional office tools, employees are increasingly using them to access data, offer sales quotes, check inventory and financial data and more. Dynamics AX 7 will include the enhancements to improve cloud access and mobility.
2) New browser-based interface
A browser-based interface will replace the current Windows Client making Dynamics AX capabilities available via new “work spaces,” promoting remote access across a variety of device platforms for enhanced collaboration.
3) Next generation user experience
Superior user experience will be delivered via the context-sensitive Windows 8 framework, based on the HTML5 technology.
4) Life-cycle management
Excellent life-cycle management will be offered – regardless of deployment choice from on premise, hybrid to full cloud.
Besides these, there will be other architectural enhancements that started in Dynamics AX 2012 R3 to make AX more customization in the cloud with smoother integration.

Courtesy: http://www.sysco-software.com/dynamics-ax-7-rainier/


Thursday 9 July 2015

Exception has been thrown by the target of an invocation.AX 2012 Purchase order invoicing.

Hi,
This is a Microsoft bug.
This error occurs when you try to Invoice a Purchase order that has attachments such as Notes, etc.

If you uncheck 'Execute business logic in IL' you will get this error:

RecordInsertList object not initialized Error while posting invoice with prepayment


To fix this, simply add this line of code(see image):

Class: PurchAdvanceApplicationJournalPost
Method: init()




Monday 22 June 2015

Getting DMF/DIXF missing dll error when running through Remote desktop service?

Sometimes you get missing dlls/assembly errors when running DIXF.

The dlls could be one of the following:

  • Microsoft.Dynamics.AX.DMF.Mapper.dll
  • Microsoft.Dynamics.AX.DMF.PreviewGrid.
  • Microsoft.Dynamics.AX.DMF.ServiceProxy.dll
  • DMFConfig.xml
  • Microsoft.Dynamics.AX.DMF.DriverHelper.dll
Resolution:

Copy the DLLs from the installation location (C:\Program Files\Microsoft Dynamics AX 2012 Data Import Export Framework Client Component) to the C:\Program Files (x86)\Microsoft Dynamics AX\60\Client\Bin folder.

What if you are getting error only when using Remote desktop service(RDS)?


In order to fix that, you need to make sure that the client folder in the RDS server has these dlls. Simply copy these dll files from your server bin location and paste that into RDS server in the following location:

C:\Program Files (x86)\Microsoft Dynamics AX\60\Client\Bin


Tuesday 12 May 2015

Temporarily disable XDS in AX 2012?

Use the following code as an example:



public void lookup(FormControl _formControl, str _filterStr)
{
    XDSServices XDS = new XDSServices();

    XDS.setXDSState(0); // Disable XDS
    super(_formControl, _filterStr);
    XDS.setXDSState(1); // Enable XDS
}


Monday 13 April 2015

Methods that can be used in AOT Query ranges?

Many times in AOT queries we add ranges that are dependent on current time, user id, company, etc. To facilitate this behavior, the "SysQueryRangeUtil" should be used. This class contains some bunch of methods that help fulfill this requirement.

Monday 30 March 2015

Important step when adding a new field in DIXF entity?

Whenever you add a new field in the DIXF entity lets say, Customer. Make sure that the new target field appears in the Target fields list.

If it does not, you need to go to the target AOT Query for that entity and make sure the new field is there in the list of fields.

Now simply go and regenerate the mapping.

Thursday 5 February 2015

AX 2012 default Print management settings using X++ job to Email?

First get the RECID of the Report for which you want to update the print management settings. Just go to table : PrintMgmtReportFormat and select the report for which you want to import settings. Next get the RecID and replace it in the job below. In my case the RecId is 5637144843. But you need to replace that with your respective RecID.














Next prepare your CSV file, it should look like the following:


Finally use the following job to get the desired settings. Please update the subject as desired. You can also import the email subject from the file but that would require a developer to make the required changes in the job.


static void SOInvoice_Settings(Args _args)
{
#File
    CommaTextIo        commaTextIo;
    FileIOPermission   permission;
    container          containFromRead;
    Query query;
    int                x;
    int                cols;
    int rowNum;

    str Customer,Email;
    int Done,UnDone;

    CustTable custTAble;
    SRSPrintDestinationSettings     destination;
    PrintMgmtSettings               settings1;
    PrintMgmtDocInstance            instance;
    SysDictEnum dictEnum;
    int         enumValue;

    permission = new FileIOPermission(@'C:\Users\Bilal\Desktop\CustEmail.csv',#io_read);


    permission.assert();

    commaTextIo = new CommaTextIO(@'C:\Users\Bilal\Desktop\CustEmail.csv','R');

   // Enter your file path here.

    rowNum = 0;
    Done= 0;
    UnDone= 0;

    containFromRead = commaTextIo.read();

    dictEnum = new SysDictEnum(enumNum(LogisticsElectronicAddressMethodType));

    While(containFromRead)
    {
        if(rowNum>0)
        {
            Customer= any2str(conpeek(containFromRead,1));
            Email= any2str(conpeek(containFromRead,2));

            custTable =CustTable::find(Customer);

    if(custTable)
        {
            destination = new SRSPrintDestinationSettings();
            destination.emailTo(Email);
            destination.printMediumType(SRSPrintMediumType::Email);
            destination.numberOfCopies(1);
            destination.emailSubject("Sales Invoice"); // enter email subject here
            destination.emailAttachmentFileFormat(SRSReportFileFormat::PDF);

            ttsBegin;
            instance = PrintMgmtDocInstance::find(CustTable.RecId, CustTable.TableId, PrintMgmtNodeType::CustTable, PrintMgmtDocumentType::SalesOrderInvoice, 1);

            if(instance)
                instance.selectForUpdate(true);

            instance.DocumentType = PrintMgmtDocumentType::SalesOrderInvoice;
            instance.NodeType = PrintMgmtNodeType::CustTable;
            instance.PrintType = PrintMgmtDocInstanceType::Original;
            instance.PriorityId = 1;
            instance.ReferencedTableId = CustTable.TableId;
            instance.Suppress = NoYes::Yes;
            instance.ReferencedRecId =custTable.RecId ;

            if(instance)
                instance.update();
            else
                instance.insert();

            select firstOnly settings1 order by PriorityId desc where settings1.ParentId == instance.RecId ;

            query = new Query(queryStr(CustInvoiceJour));
            Query.dataSourceTable(tableNum(CustInvoiceJour)).addRange(fieldNum(CustInvoiceJour, InvoiceAccount)).value(CustTable.AccountNum);
            Query.pack();

            settings1.ParentId = instance.RecId;
            settings1.ReportFormat = 5637144843; // enter the recid of the email format here.
            settings1.PrintJobSettings = destination.pack();
            settings1.PriorityId = settings1.PriorityId + 1;
            settings1.NumberOfCopies = 1;
            settings1.Description = strFmt('%1  %2', CustTable.AccountNum, CustTable.name());
            settings1.QueryPacked = Query.pack();
            settings1.insert();

            ttsCommit;
            Done++;
        }
        else
        {
            info("Customer not found " + Customer);
            UnDone++;
        }

        }
        containFromRead = commaTextIo.read();
        rowNum++;
    }
    commaTextIo = null;

    info(strFmt("Inserted : %1 Not inserted: %2", Done, UnDone));
}

Friday 30 January 2015

AX 2012 - how to evaluate mathematical expressions using code?

Many times its required to evaluate a mathematical expression using the order of execution.
For example, we have a string '((2+3)*4)'. We want to evaluate this expression and return the result.
Such expressions can be validated and evaluated using the X++ class 'XPPCompiler'.




Following is the code snippet:


static void calculateExpression(Args _args)
{
    XppCompiler comp;
   
    str expr;
   
    expr = "(((1+2)*6)/5)";
   
    comp = new XppCompiler();
   
    info(strFmt('%1',comp.compileExpr(expr)));//this validates the expression
   
    info(strFmt('%1',comp.execute(expr)));//this returns the result.
}

AX 2012, X++ expression, BODMAS in AX 2012, validate mathematical expressions, validate formula in AX, formula validation, XPPCompiler, Dynamics AX 2012, Formula calculation, string to mathematical expression, Paranthesis in AX 2012