Friday, November 1, 2013

How to use entry point security in x++ based on a record

I had one requirement where in Sales order form the records which are confirmed must not be allowed to edit for a user role. This can be resolved by two ways:


1. To check the current user role and making the edit button as false on a condition,override active method of datasource and code as below:

select role
        where role.Name == 'RoleName'
    join userRole
        where userRole.SecurityRole == role.RecId
            && userRole.User == curUserId();
    if(userRole && SalesTable.DocumentStatus == DocumentStatus::Confirmation)
    {
    editButtonAllow= false;
    }

2. To avoid hard coding the Roles, we can use an entry point and check users access to the entry point

we need to create a menu item with a privilege and duty assigned to a role, override active method of datasource and use the menu item as below:

SecurityRights      sr;
AccessRight         accessRight = AccessRight::View;
sr = SecurityRights::construct();

accessRight = sr.menuItemAccessRight(SecurableType::MenuItemAction,menuitemActionstr(MenuItemName));
if(accessRight == AccessRight::View && SalesTable.DocumentStatus == DocumentStatus::Confirmation)
{
    ButtonName.enabled(false);
}
 else
 {
    ButtonName.enabled(true);
  }

Thursday, August 22, 2013

Modify XML using XSL outbound transform AX 2012



Once I got a client requirement to make changes into the outbound XML generation of electronic VendPayment. Since their bank was not able to accept the current format of the XML generated from AX.
The XML includes Envelope and Header tags with output XML which sometimes needs to be truncated so that the third party applications can read the output XML.
To resolve this I started fresh by configuring the VendPayment using AIF outbound port setup using following Link.
The only change in the above configuration I did is I included the XSL file generated from the resources to outbound pipeline, no changes here,
I created a second XSL and added it into the outbound transformation(see below)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:wt="schemas.microsoft.com/.../Message" xmlns:xsl="www.w3.org/.../Transform">
            <xsl:output version="1.0" omit-xml-declaration="no" indent="yes" encoding="UTF-8" method="xml"/>
           
<!--Copy all nodes from source-->
-<xsl:template match="@*|node()">-<xsl:copy>
                                    <xsl:apply-templates select="@* | node()"/>
                        </xsl:copy>
            </xsl:template>
           
            <!--Remove header, message parts, body and envelope tags-->
            <xsl:template match="wt:Envelope/wt:Header"/>-<xsl:template match="wt:Envelope/wt:Body/wt:MessageParts">
                        <xsl:apply-templates/>
            </xsl:template>-<xsl:template match="wt:Envelope/wt:Body">
                        <xsl:apply-templates/>
            </xsl:template>-<xsl:template match="wt:Envelope">
                        <xsl:apply-templates/>
            </xsl:template>
</xsl:stylesheet>

This gave me XML document without Envelope, Message part, Body and Header

Reference: http://community.dynamics.com/ax/f/33/t/102465.aspx#.Uhb2Uz_66qk


Thursday, July 18, 2013

Add new fields to existing service table


when adding a new field for exiting service, we need to perform following steps to make the new field available in Visual Studio
1. Update service

- in dev window, go to Tools, AIF, update Document service
- give the service name and put the service operation as required
- select Regenerate data object and AxBC classes

2. Register service check

- Right click service, go to Addins,Register service
- select service, click on service operation button,
- in service operation window click parameter schema
- in parameter schema window, click view schema and check if your new field is mentioned or not

3. Inbound port deactivate/activate

- go to system administration, setup, Services and Application Integration Framework, Inbound/Outbound port
- select the port name and click on deactivate button
- click on service operation button on the right
- check your service is listed or not
- activate the port

4.Refresh service reference in Visual studios

- go to solution explorer
- right click on service reference and select Update service reference
- Build the project

Monday, July 15, 2013

how to handle visibility of controls in SSRS report

Sometimes we wish to hide the control(in order to reduce space) if the control field value is null or empty. Use the below steps:

1. Open the report project in Visual Studios
2. Go to report design
3. Right click on the control and go to properties











4. select visibility tab and add the condition

=iif(Fields!fieldName.Value = "",True,False)

5. Save, rebuild and deploy report.

Tuesday, July 9, 2013

One or more conflicting model elements already exists in an installed model

If you get this error while importing AX model file, there is a simple work around for this to use  /conflict:Push

 
this will allow the model files to be imported.

axUtil import /file:"D:\DataMigrationFrameWork.axmodel" /conflict:Push

Monday, July 8, 2013

X++ LIKE operator

We can use like operator in x++ as below:


static void LikeTest()

    str str;
    ;
    str="expiry";

    if(str like "exp*")
       info('"like work ");
}

 

Microsoft Dynamics AX 2012 Build numbers


Dynamics AX iPhone app


Microsoft has released a new Dynamics AX iPhone app for use with Microsoft Dynamics AX 2012 R2.

 

Performance tip: Caching display method



One significant side-effect of using display methods can be the impact on performance. Particularly when complex methods are used to calculate values being shown on grids, a visible slow-down in form performance can be experienced. This is largely due to the fact that the methods are often run repeatedly even when no reason is apparent and the values are unchanged.

To alleviate this, display methods on tables can be cached by using the cacheAddMethod method of the datasource object. To enable caching of a display method, call cacheAddMethod() from the init method of the datasource. This ensures that the display will only be calculated when necessary and can result in a significant performance improvement.

 

public void init()

{

    super();

 

    // Enable caching of the document handling display fields

    dirPartyTable_ds.cacheAddMethod(tablemethodstr(DirPartyTable, primaryPhone));

}

how to set temporary table data based on the table type of the temporary table


§  For InMemory tables, by using either the setTmpData() method or by directly assigning the buffers to each other.

§  For TempDB tables, the linkPhysicalTableInstance() method replaces the setTmpData() call.

 

Thursday, July 4, 2013

how to delete a parameter from SSRS report

Follow below steps if you wish to delete a parameter from the SSRS reports

1. delete parm method from the Contract class
2. delete from the parameter node in the VS project
3. refresh the dataset
4. rebuild, deploy and add to AOT
5. restart SSRS services
6. Delete cache

Wednesday, July 3, 2013

Cannot debug SSRS reports in AX 2012

Sometimes we need to debug SSRS reports, in my case I had added a new param method in contract class to display a new test box in report dialog window, which I needed to debug as  the data was not getting displayed in report.

I changed the class I was extending my report from SRSReportDataProviderBase to SrsReportDataProviderPreProcess, and changed back to the original class when the debug was complete.

This is not a clean way to do debugging, however it helped me with many of my SSRS reports in AX 2012.
 

 

Thursday, May 16, 2013

Duplicate type with name in assembly



Sometimes we need to delete and recreate the service, we might face some issues with duplicate type error. Here is the solution:


  1. Delete classes and service from AOT
  2. After this we need to delete the service from the inbound or outbound port
          a. Go to system Administration-> Setup-> Inbound/Outbound ports.     
          b. Select the Port the service is using and Deactivate it.
          c. Go to 'Service operation' button and remove the service you deleted from AOT.
          d. Reactivate port.
     3. Stop AOS services
     4. Delete XppIL directory
         (c:\Program Files\Microsoft Dynamics AX\60\Server\InstanceName\bin)
     5. Restart AOS
     6. Run CIL compile

After this we need to add the new service into the inbound or outbound port:

        a. Go to system Administration-> Setup-> Inbound/Outbound ports
        b. Select the Port the service is using and Deactivate it.
        c. Go to 'Service operation' button and add the new service.
        d. click on Activate button after selecting the port.

If you have a Service reference in your VS project follow below steps to update services:

        a. In solution explorer right click on service reference
        b. select 'Update Service Reference'

Thursday, May 2, 2013

Store address and contact information using dirPartyTable

 

   //address

    dirParty = DirParty::constructFromCommon(custTable);
    dirPartyPostalAddressView.Street = intCustTable.Street;
    dirPartyPostalAddressView.County= intCustTable.County;
    dirPartyPostalAddressView.party = custTable.Party;
    dirPartyPostalAddressView.CountryRegionId = IntCustTable.CountryRegionId;
    dirPartyPostalAddressView.ZipCode = IntCustTable.ZipCode;
    dirPartyPostalAddressView.State   = IntCustTable.State;
    dirPartyPostalAddressView.City   = intCustTable.City;
    dirPartyPostalAddressView.Location   = DirPartyLocation::findPrimaryPartyLocation(custTable.Party).Location      
   dirParty.createOrUpdatePostalAddress(dirPartyPostalAddressView);

  

// Contact information

    logisticsLocation.clear();
    logisticsLocation  = LogisticsLocation::create('Phone', NoYes::No);
    dirPartyContactInfoView.LocationName = 'Primay Phone 1';
    dirPartyContactInfoView.Locator  = intCustTable.Phone;
    dirPartyContactInfoView.Type  = LogisticsElectronicAddressMethodType::Phone;
    dirPartyContactInfoView.Party = custTable.Party;
    dirPartyContactInfoView.IsPrimary = NoYes::Yes;
    dirPartyContactInfoView.Location  = PostalAddress.Location;
    dirParty.createOrUpdateContactInfo(dirPartyContactInfoView);