Showing posts with label AX 2012. Show all posts
Showing posts with label AX 2012. Show all posts

Monday, February 9, 2015

In Ax 2012 EP "You cannot view data on this page because you are not a registered user in Microsoft Dynamics AX.Contact your Microsoft Dynamics AX administrator."

In Ax 2012 EP 

"You cannot view data on this page because you are not a registered user in Microsoft Dynamics AX.Contact your Microsoft Dynamics AX administrator."

My resolution:
- Import .net bc in all partition in dynamics ax with system user permission
- Set .net bc in all partition in dynamics ax in system service account
- Go to "System administration \ Set up \ Enterprise portal \ Web site". Check the site url is correct: http:///sites/DynamicsAx.  

Thursday, November 27, 2014

Multiple report design association in Dynamics AX 2012 SSRS using X++

It is obvious that we customize many document reports e.g. Sales order, Purchase order, Quotation, Projects for a new report design and call the report from different journal accordingly. There are few ways to specify the new report design, using Print management document or setting this new report design as a system report in the table "PrintMgmtReportFormat".

In most of the cases, AX SSRS report controller class call for the system report from PrintMgmtReportFormat table using the following method:


PrintMgmtReportFormat::findSystem(this.getPrintMgmtDocumentType()).Name);


The controller class has a method  "runPrintMgmt" which is responsible for defaulting the system report. In this method, the class object FormLetterReport does the actual job for calling and assigning system report with printer setting.

formLetterReport.loadPrintSettings(custQuotationJour, custQuotationJour.salesQuotationTable(), this.quoteLanguageId());

So here my code goes. I write a method and call this after the above line of code in the controller class. This custom method basically initializes the PrintMgmtPrintSettingDetail object and conditionally, I am passing my custom report design. In this way, it overrides the print setting with my new report design.

void customPrintSettings()
{
    PrintMgmtDocInstanceType        type;
    PrintMgmtPrintSettingDetail     printSettingDetail      = new    
    PrintMgmtPrintSettingDetail();
    SRSPrintDestinationSettings     defaultSettings         = 
    formLetterReport.parmReportRun().parmDefaultOriginalPrintJobSettings();
    PrintMgmtReportFormatName       reportFormatName        = 
    ssrsReportStr(PSAQuotations, CustomReportSG); //Passing custom report design

    if (formLetterReport.parmPrintType() == PrintCopyOriginal::Original)

    {
        type =  PrintMgmtDocInstanceType::Original;
    }

    if (formLetterReport.parmPrintType() == PrintCopyOriginal::Copy)

    {
        type =  PrintMgmtDocInstanceType::Copy;
    }

    printSettingDetail.parmReportFormatName(reportFormatName);


    printSettingDetail.parmType(type);


    printSettingDetail.parmInstanceName(enum2str(type));


    // Since this will be reported to the screen, one copy is the only thing that makes sense

    printSettingDetail.parmNumberOfCopies(1);

    printSettingDetail.parmPrintJobSettings(defaultSettings);


    if (!formLetterReport.parmUseUserDefinedDestinations())

    {
        printSettingDetail.parmPrintJobSettings().printMediumType(
        SRSPrintMediumType::Screen);
    }

    formLetterReport.parmReportRun().loadSettingDetail(printSettingDetail);

}

Cheers !!!

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, 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 !!

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 !

Friday, January 17, 2014

Vendor aging report field length issue

Some time, Vendor aging report throws an unexpected error as follows due to mismatch of field length while inserting record in few temporary tables.


 To resolve this, make sure the following fields has the same length respectively. e.g. 100 char in these tables.
- Name
- Txt

Tuesday, November 5, 2013

Exception logging

Log any exception for reference using the following code snippet.

Write a static method in the table "YourTableName".

public static void logExceptionData(InfologData _infologData, RefRecId yourTableRecId)
{
    str                                                    exceptionLogMsg;
    SysExceptionTable                           sysExceptionTable;
    SysInfoLogEnumerator                     sysInfoLogEnum;
    SysInfologMessageStruct                  infoMessageStruct;
    YourTableName yourTableName =  YourTableName ::findRecId(yourTableRecId,true);


    sysInfoLogEnum = SysInfoLogEnumerator::newData(_infologData);

    while(infoLogEnum.moveNext())
    {
        sysInfoMessageStruct  = SysInfologMessageStruct::construct(sysInfoLogEnum.currentMessage());
        exceptionLogMsg      += exceptionLogMsg? "\n" + infoMessageStruct.message() infoMessageStruct.message();
    }

    if (yourTableName.RecId)
    {
        ttsBegin;
        yourTableName.Log = exceptionMessage;
        yourTableName.LogDate = DateTimeUtil::utcNow();
        yourTableName.update();
        ttsCommit;
    }
}

After than, call this method as follows:

public void job ()
{
      AifInfoLog              aifInfoLog;
     Container                 infologCon;

    try
    {
        aifInfoLog = new AifInfoLog();
        ........................................
        ........................................
     }
     catch (Exception::Error)
    {
         infologCon= aifInfoLog.getInfoLogData();
        YourTableName::LogExceptionData(infologCon,this.parmYourTableRecId());
}

Tuesday, June 25, 2013

Calling control between form objects in Dynamics AX

Get caller form name from current form:

FormRun                    formRun;
formRun= element.args().caller();

info(strFmt('%1',formRun.args().name()));

//to perform actions on current form datasource based on the caller form name
if(formRun.args().name() == formStr("CallerFormName"))
{
        currentForm_ds.allowCreate(false);   
        currentForm_ds allowDelete(false);   
}

Get value from caller form

Object                  callerObject;
if (args.caller() &&  formHasMethod(args.caller(), identifierstr()))
{
        callerObject= args.caller();
        callerObject.();    
}

Wednesday, December 21, 2011

Version Control System [AX 2012]


MorphX, the Microsoft Dynamics AX Integrated Development Environment (IDE), can integrate various Version Control Systems (VCS). You can integrate: