D365fo custom dimension defaulting in segmented entry controls

D365fo custom dimension defaulting in segmented entry controls

The below outlines how to code a custom dimension defaulting logic directly into the segmented entry controls such that the user views the changes in real time. Base D365fo has "Derived dimension" logic, which does not allow for full control over potential defaulting requirements. However, we tap into that business logic to ensure the dimensions are updated at the right time. I created this article since I could not find anything similar when googling this problem. It took a while to sort through all the possible base classes related to the segments. Note - Microsoft code comments in these various classes recommend against customization here.

This article is for segmented entry controls which is distinctly different from DimensionEntryControls. For those types of controls, just use COC on class DimensionEntryControl, method modifyingDimensionValue. Call base method setDimensionAttributeValue to set other dimension values.

Pictured is what a standard segmented entry looks like. Note this contains the main account, you may need to change the approach slightly for defaultDimensions (no main account).

Consider a scenario where when the user selects BusinessUnit, Department should default its value based on the Currency, Main Account, company, salesTax amounts, or other variables. And you only want this to happen for manual user inputs on specific forms / controls. Or let's say you turned your VendTable into a Dimension. And when the Vendor dimension is selected, Department should default based on the vendor transaction dollar volume. This allows for full control of the dimension values.

  1. First you need a new class extension of LedgerDimensionAccountController.

a. Use chain of command on method applyDerivedDimensions. (ret = next .... return ret || this.customProcessDerivedDimensionForSegment)

b. Copy the base method processDerivedDimensionForSegment and rename in your extension class (this method is private, otherwise this would have been more ideal to use without applyDerivedDimensions). Have applyDerivedDimensions call your processDerivedDimensionForSegment. You will want to remove the conditions related to derived dimensions since that is specific to certain configuration, but it is critical to keep the other logic which updates the segment and the return value derivedDimensionsDefaulted needs to return true if you set any dimension values. You may also want to remove the strLen(segment.parmValue()) != 0 if you would like to still run your logic, such as intentionally blank out other dimension values when this segment is blank.

c. Review the base method DimensionAttributeValueDerivedDimensions.getDimensionAttributeValueMap to see how to properly build the Map of dimensions used by the base class. Create your own method and call it from processDerivedDimensionForSegment. Then this map is used in the call to applyDimensionSpecifiers from processDerivedDimensionForSegment - just replace what the base code had when you copied the method.

d. Copy base method updateCurrentSegmentIndexes. Call your copy of this method from processDerivedDimensionForSegment (base method is private).

e. (Optional) Create a new class variable FormControl callerControl. Create a parm method for this control. We will set this control so you can reference the caller formControl, and related Form, formDataSources, etc. This is only needed if your logic depends on data outside of the dimension values themselves or if the logic is only for certain controls/forms. For example, in your method applyDerivedDimensions, you may only run your logic if (callerControl && callerControl.formRun().name() == formControlStr(myForm)). Or if you need form data you could use it as LedgerJournalTrans ljt = callerControl.formRun().dataSource(formdatasourcestr(LedgerJournalTransDaily, LedgerJournalTrans)).cursor();

If you don't need to reference the calling control or form, this is all the code you need. If you need to reference the caller, here is how you set that value:

2. Create an extension class of DimensionDynamicAccountController. Create one method which just returns LedgerDimensionAccountController. This is needed because this variable is protected and the base get method has other logic we don't want.

3. Create an extension of class SegmentedEntryControl. Here is the code you need in this:

public ClassName parmControllerClassName(ClassName _controllerClassName)
{
  boolean controllerCreating;
  if(controllerClassName != _controllerClassName)
  {
    controllerCreating = true;
  }

  ClassName ret = next parmControllerClassName(_controllerClassName);

  if(controllerCreating && _controllerClassName == classStr(DimensionDynamicAccountController)
  {
    DimensionDynamicAccountController controller = dimensionController;
    LedgerDimensionAccountController ledgerController = controller.<your method from 2 above>();
    LedgerController.parmCallerControl(this); //This method you created in 1e above.
  }
  return ret;
}


要查看或添加评论,请登录

Michael Schiermeyer的更多文章

  • AWS authentication in X++ for Vendor Central & others

    AWS authentication in X++ for Vendor Central & others

    The authentication step to AWS is rather complicated. A client had asked me to code the authentication step and they…

  • Default batch retry to 0

    Default batch retry to 0

    Microsoft introduced batch retry in 2021. This causes many unexpected results covered in many other articles.

    2 条评论
  • Refresh certificates on onebox dev machines

    Refresh certificates on onebox dev machines

    If you follow the onebox VHD setup, you have had to use the self signed certificate for a few years now during setup:…

    3 条评论
  • Force progress bar in X++

    Force progress bar in X++

    There are several standard, best practice approaches to showing your user a wait indicator. Such as…

  • D365 SSRS Checkboxes using wingdings

    D365 SSRS Checkboxes using wingdings

    This article is more of a reminder that this is an option when developing SSRS reports in d365. In my twelve years of…

    1 条评论
  • Server certificates and production D365fo

    Server certificates and production D365fo

    Many integrations require certificates to authenticate the identify of the caller, in this case D365fo. Most…

    2 条评论
  • D365fo join table as csv column in view/data entity

    D365fo join table as csv column in view/data entity

    Below is some sample code for joining a table to a view as a calculated field. Useful when you have data represented as…

社区洞察

其他会员也浏览了