Thursday, September 18, 2014

The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state in Dynamics Ax 2012 R3

Service error related to communication in dynamics ax 2012: Have a look on the followings:
- Full compilation
- Full CIL
- Refresh AIF services from AOT form "AIFService"
- Register services from AOT under "Services" node
- Check your AOS host file under "Windows/System32/Driver/Etc/Host.Config for any wrong entry for the AOS machine name
------------------------------------Error Message--------------------------------------------------------
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> 

System.ServiceModel.CommunicationObjectFaultedException: The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication 

because it is in the Faulted state.Server stack trace:    at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)   at 

System.ServiceModel.Channels.ServiceChannel.System.IDisposable.Dispose()Exception rethrown at [0]:    at 

System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke

(MessageData& msgData, Int32 type)   at System.IDisposable.Dispose()   at Microsoft.Dynamics.AX.Framework.Workflow.Model.WorkflowModelCache.SetDataTypeCache()   

at Microsoft.Dynamics.AX.Framework.Workflow.Model.WorkflowModelCache.Create(IAxClient client, String templateName, String domainUser, String companyId, Boolean 

runtimeCache)   at Microsoft.Dynamics.AX.Framework.Workflow.Model.WorkflowModel.Create(String templateName, String companyId, String owner, String domainUser)   

--- End of inner exception stack trace ---   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)   

at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)   at System.Reflection.RuntimeMethodInfo.Invoke

(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)   at 

Microsoft.Dynamics.AX.ManagedInterop.ClrBridgeImpl.InvokeClrStaticMethod(ClrBridgeImpl* , Char* pszClassName, Char* pszMethodName, Char* assemblyName, Int32 

argsLength, ObjectWrapper** arguments, Boolean* argsAreByRef, Boolean* isException)
  

Thursday, August 21, 2014

Configuring Visual Studio 2010 for a specific AX 2012 R3 AOS instance in distributive environment

Recently, I try to configure Visual Studio 2010 for a specific AX 2012 R3 AOS instance out of multiple AOS instances installed in the same box. The scenario is as follows:

- Machine_1 : Running three Dynamics AX 2012 R3 AOS instance (AOS_1, AOS_2, AOS_3)

- Machine_2 : Running SQL server 2012 DB and three SSRS instance (SSRS_1, SSRS_2, SSRS_3).These three reporting service instance is configured as per three AOS(s) above consecutively.

- Machine_3 : Remote desktop server for AX client, Visual Studio 2010, MS Office 2013.

The requirement is to configure VS in order to work with AOS_3 for SSRS_3 developments in AX VAR layer from Machine_3 which remote desktop server for accessing AX client and VS.

I will not go details about installation and configuration of multiple AOS , multiple SSRS instance setup as these information are well documented in technet. The followings basically helps to sort out most of the issues with distributive setup with multiple instance while developing objects for SSRS and EP in VS.

Key points to be noted as follows:
- Validate Dynamics AX client successfully opens and points to VAR layer environment (AOS_3) from RD.
- Validate settings for reporting server in dynamics ax from RD. Expected result success.
- Validate Report Manager URL is working in RD.
- Validate to successfully deploy SSRS report from Dynamics AX client in RD

Checklist:
A. The domain account you are using for developing and deploying report must have the following roles in report manager URL:
1. Open report manager URL
2. Click on the "Folder Setting" or select "DynamicsAx" folder and lookup for "Security" and click
3. Key in domain group name or domain user id, assign the role as "Content manager" and "DynamicsAxBrowser". Click OK.
4. If you are setting users only for viewing Ax reports, choose "DynamicsAxBrowser" and "Browser" roles.
5. On the top right side of the page, click "Site settings" - "Security" and click "New role assignment". Key in domain group name or user name. Assign "System administrator" role and click OK.

B. Required setup for Internet Explorer in remote desktop server (Machine_3) (Version IE 11):
1.  Go to Tools - Internet Option - Advance (tab page). Scroll down to find "Enable integrated windows authentication". Select the check box next to it and click apply.
2. Go to tab page, "Security", select the zone "Local intranet", click on "Sites", click "Advance". Add the reporting manager URL and close.
3. In the same tab page, select "Custom level". Scroll down and under user authentication group, select the radio button "Automatic log on with current user name and password". Click OK and Apply and Close.

C. Dynamics ax client configuration utility in the remote desktop server (Machine_3):
1. Open client AX configuration utility.
2. Check the "Active configuration store".
# If this is set as registry, create a VAR layer configuration for AOS_3. In the connection tab page click "Refresh configuration". Export out the client configuration file and save this in a local drive.
# If this is not set as registry and points to a shared location in e.g.in Machine_1 as  \\Machine_1\AX2012Config\AOS_1_USR.axc). In this case, your local client will always points to this configuration by default as this is set a default in the local machine registry and as a result, your VS will points to this default entry.  In this case, go to Machine_1 where AOS_3 is installed, create a VAR layer configuration file (e.g. AOS_3_VAR.axc) for a AOS_3 instance you want to work with and save it in the same location  (\\Machine_1\AX2012Config\) . You may choose other location as well. In the Remote desktop machine, open the AX client configuration, click menu button "Manage" and select"Set configuration store". Browse for VAR layer configuration code (\\Machine_1\AX2012Config\AOS_3_VAR.axc). click OK and your active configuration store set accordingly. After this, create a VAR layer configuration for AOS_3. In the connection tab page click "Refresh configuration". Export out the client configuration file and save this in a local drive. Click Apply and OK to close the AX client configuration utility.

D. Visual Studio configuration setup:
1. We are going to use /AxConfig parameter to pass to VS in order to point VAR layer configuration file for AOS_3 you have just exported as above. E.g, the VAR layer configuration file has been exported out and saved in the location \\Machine_3\AX2012 config\
2. Create a shortcut of the visual studio in desktop in your remote desktop server (Machine_3)
3. Right click and open the property window
4. Set target location as follows: "C:\Program Files (x86)\Microsoft Visual Studio  
    10.0\Common7\IDE\devenv.exe" /AxConfig "\\Machine_3\AX2012 config\AOS_3_VAR.axc" . For more information, refer http://msdn.microsoft.com/en-us/library/gg889291.aspx

E. Required windows service
1. Go to list of windows services (Services.msc).
2. Select "RemoteRegistry"  service and start it.

Validate your setting as above. Hope this is helpful.

Cheers!






Thursday, May 29, 2014

Add dimension attribute value to a main account ledger dimension in dynamics ax 2012

You may have a set of dimension attribute values and you may want to assign these set of values to a main account ledger dimension. The following set of function will help you.

private RecId mergeSegmentValueInDimension(RecId             _modifiedDimension,
                                           DimensionValue    _businessUnit       = '',
                                           DimensionValue    _space              = '',
                                           DimensionValue    _function           = '',
                                           DimensionValue    _venue              = '')
{
    //Dimension attributes
    #define.businessUnit('BusinessUnit')
    #define.space('Space')
    #define.functions('TypesofFunctions')
    #define.venue('Venue')
 
    RecId                                               newDimension;
    DimensionAttributeValue                   attributeValue;
    DimensionAttributeValueSetStorage   dimStorage   = new DimensionAttributeValueSetStorage();


    if (_businessUnit)
    {
        attributeValue = this.getDimenionAttribute(#businessUnit, _businessUnit);
        dimStorage.addItem(attributeValue);
    }

    if (_space)
    {
        attributeValue = this.getDimenionAttribute(#space, _space);
        dimStorage.addItem(attributeValue);
    }

    if (_function)
    {
        attributeValue = this.getDimenionAttribute(#functions, _function);
        dimStorage.addItem(attributeValue);
    }

    if (_venue)
    {
        attributeValue = this.getDimenionAttribute(#venue, _venue);
        dimStorage.addItem(attributeValue);
    }

    newDimension = DimensionDefaultingService::serviceCreateLedgerDimension(_ledgerDimension, dimStorage.save());

    return newDimension; // This will return a new dimension associating main account with segmented value
}


Sub-function-1
private DimensionAttributeValue getDimenionAttribute(Name   _dimName,
                                                                                   str         _dimValue)
{
    DimensionAttribute                 dimAttribute =  DimensionAttribute::findByName(_dimName);
    DimensionAttributeValue         dimAttributeValue;

    if(_dimValue)
    {
        dimAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimAttribute, _dimValue, true, true);
    }

    return dimAttributeValue;
}

Cheers !!

Monday, May 19, 2014

Turn on IncludeExceptionDetailInFaults for service error in Dynamics AX

Good one for AIF troubleshooting reference:

http://mybhat.blogspot.sg/2013/10/turn-on-includeexceptiondetailinfaults.html

Tuesday, May 13, 2014

The value in field 'Record-ID' is not found in the related table 'Electronic payment - remittance'

I had an issue during update AIF service operation on project expense journal inbound interface. It says

The value '5637150577' in field 'Record-ID' is not found in the related table 'Electronic payment - remittance'

The error prompts when  LedgerJournalTrans fields are validated during AIF service. But, the unusual things is, when LedgerJournalTrans.RecID goes through the function validateField() in LedgerJournalTrans table, it calls the super() in following default switch statement code snippet and results such error:
              default:
                //
                if ((TaxParameters::checkTaxParameters_IN() || TaxWithholdParameters_IN::checkTaxParameters()) &&
                    (this.Company != this.OffsetCompany))
                {
                    // When Two different companies are involve in invoice and payment..
                    ret = true;
                }
                else
                {
                //

                    ret = super(field);
                //
                }
                //

As an workaround, I had to get this "RecID" field in the switch case statement as follows so that it results true and continues:

// Dip, HP ES
            case fieldNum(LedgerJournalTrans, RecId):  
                ret = true;
                break;
            //
            default:
                //
                if ((TaxParameters::checkTaxParameters_IN() || TaxWithholdParameters_IN::checkTaxParameters()) &&
                    (this.Company != this.OffsetCompany))
                {
                    // When Two different companies are involve in invoice and payment..
                    ret = true;
                }
                else
                {
                //

                    ret = super(field);
                //
                }
                //

Cheers !

Find segment value from one dimension and use in another dimension

The following set of function is used in the scenario as :
- Get one or more segment values from a dimension
- Set or merge one or more segment values  in another dimension and returns a new dimension

Main function:
///
///     Setting a new dimension value by using segment vales from other dimension
///
///
///     The segment values will be used from this dimension
///
///
///     The segment values will be incorporated in this dimension
///
///
///     After incorporating the segment values, function returns a new dimension
///

public RecId mergeSegmentValueInDimension(RecId  _getDimension, RecId _setDimension)
{
    #define.AccountingDim('Accounting')
    #define.DepartmentDim('Department')
    #define.BusinessUnitDim('BusinessUnit')
    #define.SpaceDim('Space')

    RecId       newDimension = _setDimension;
    Struct      s;
    String255   dimValue;
    container   c = this.getDimensionValueBySegmentName(_getDimension);

    s = Struct::create(c);

    dimValue = s.exists(#AccountingDim) ? s.value(#AccountingDim) : '';
    if (dimValue)
    {
        newDimension = this.setSegmentValueInDimension(newDimension, #AccountingDim, dimValue);
        dimValue = '';
    }

    dimValue = s.exists(#DepartmentDim) ? s.value(#DepartmentDim) : '';
    if (dimValue)
    {
        newDimension = this.setSegmentValueInDimension(newDimension, #DepartmentDim, dimValue);
        dimValue = '';
    }

    dimValue = s.exists(#BusinessUnitDim) ? s.value(#BusinessUnitDim) : '';
    if (dimValue)
    {
        newDimension = this.setSegmentValueInDimension(newDimension, #BusinessUnitDim, dimValue);
        dimValue = '';
    }

    dimValue = s.exists(#SpaceDim) ? s.value(#SpaceDim) : '';
    if (dimValue)
    {
        newDimension = this.setSegmentValueInDimension(newDimension, #SpaceDim, dimValue);
        dimValue = '';
    }

    return newDimension;
}


Sub-function-1:
public container getDimensionValueBySegmentName(RecId   _defaultDimension)
{
    Struct s = new struct();

    DimensionAttribute              dimAttr;
    DimensionAttributeValue         dimAttrValue;
    DimensionAttributeValueSet      dimAttrValueSet;
    DimensionAttributeValueSetItem  dimAttrValueSetItem;

    dimAttrValueSet = DimensionAttributeValueSet::find(_defaultDimension);

    while select dimAttrValueSetItem
        where   dimAttrValueSetItem.DimensionAttributeValueSet   == dimAttrValueSet.RecId
    {
        dimAttrValue        = DimensionAttributeValue::find(dimAttrValueSetItem.DimensionAttributeValue);
        dimAttr             = DimensionAttribute::find(dimAttrValue.DimensionAttribute);

        s.add(dimAttr.Name, dimAttrValue.getValue());
    }

    return s.pack();
}

Sub-function-2:
public RecId setSegmentValueInDimension(RecId  _defaultDimension,
                                        Name   _dimName,
                                        str    _dimValue)
{
    DimensionAttributeValueSetStorage  dimStorage   =   DimensionAttributeValueSetStorage::find(_defaultDimension);
    DimensionAttribute                 dimAttribute =  DimensionAttribute::findByName(_dimName);
    DimensionAttributeValue            dimAttributeValue;

    if(_dimValue)
    {
        dimAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimAttribute, _dimValue, true, true);
        dimStorage.addItem(dimAttributeValue);
    }
    else
        dimStorage.removeDimensionAttribute(DimensionAttribute::findByName(_dimName).RecId);

    return dimStorage.save();

}

Cheers !

Tuesday, April 22, 2014

Oracle virtual box - Custom resolution

Hi there,

Recently, I am having an issue in oracle VB(Virtual Box) whereas I am unable to set full screen mode even after installing guest additions. To have a full screen mode, the guest OS in VB must set the same resolution as per the host OS. I am using windows 8 as a host OS which has a resolution 1600x900. Guest OS Windows server 2012 64 doesn't have the same resolution. Therefore, it is required to set a custom resolution in the VB.  After goggling, I found a way to set the host OS with the required custom resolution.

- First, close your virtual box. Go to task manager and kill any process related to oracle virtual box.
- Go to "C:\Program Files\Oracle\VirtualBox" (Depends on your installation file path)
- Hold "Shift" and right click in any empty space (Not pointing or highlighting to any file or folder)
-  In the menu, select "Open command windows from here"
- paste the following command and hit enter:

VBoxManage.exe setextradata "NameOfVB" CustomVideoMode1 1600x900x32



Now open your VB and set the resolution in the guest OS as per your host OS. Go to virtual box title menu, click "View / Switch to full screen". Voila !

Wednesday, March 12, 2014

Data Migration Framework : Development consideration for custom entity

I have a issue while importing records using custom entity in Dynamics Ax 2012 data migration framework. The custom entity imports only one record from staging table to actual table out of many records.

I come across this blog which explains the resolution for the same:

AX2012R2 Data import/export framework (aka: DMF) import troubles

Tuesday, January 21, 2014

Check item for tracking dimension activation

    InventDimSearch dimSearch    = new InventDimSearch();
    ItemId             itemid               = "P50000000123";
    InventTable     table                 = InventTable::find(itemid);
    boolean           b;
    ;


    b = dimSearch.findActive(table.DimGroupId,fieldnum(InventDim,InventBatchId));
    print b;
    pause;