Wednesday, December 09, 2020

Budgeting at Totals

The AX system has two level check for budget. 

  • Level 1: Budget control rule which works at the individual account + dimension combination level.  
  • Level 2: The budget group rule executes a secondary budget check. This is applied after the level 1 check is failed. This is performed at a summary of 1 or more accounts which is created using an entity called budget groups. 
To budget for a group of accounts as a block, we need to create budget group. The budget groups must be created on the **Budget control configuration ** page. The criteria that you specify must include the total main account and the range of accounts. The criteria can further be nested to accommodate multiple queries and when a group is considered then all the queries nested below it are accumulated before the check is performed. This provides enough flexibility to create complex budget groups.

It is also important to note here that sometimes when the budget registers are posted before the budget configurations are enabled, the budget control statistics might not be udpdate. AX now provided a period job to process any such budget register entries that have not been processed or were posted before the budget controls were enabled. 

To process any pending budget register entries we need to do the following: 

  1. We need to ensure that all the financial periods with the budgets are open. To open the financial periods you can go to General Ledger-> Ledget Setup -> Ledger Calender option. 
  2. Once the periods are opened then any pending registers can be processed using the periodic job in Budgeting -> Periodic-> Budget control data maintenance 
Please ensure that the budget control is enabled before the budget control data maintenance is initiated. 

Sunday, September 06, 2020

Outlook out of memory

When you get out of memory error on the outlook client. One of the solutions that worked is as follows:-

1. Goto the below folder and delete all the xml files in there

%appdata%\Local\Microsoft\Outlook\16

2. Start the Microsoft outlook client in safe mode to reconfigure the mails. 


Wednesday, September 02, 2020

AX Dialog : Override controls

 Dialog is a another important framework in AX 2012. When a dialog is created using classes it demands a good understanding of what happens under the hood. 

Each dialogField that is added using the dialog classes is internally given a system name and this name can then be used to attach events to the runtime Field. The fieldName method in the dialog class creates the name for a field being added. 

We can find the systemName that a control has been assigned by calculating it from the sequence it was added in or alternatively we can run the dialog and check the name from the personalization form. 

Once we have the name we can write the extension methods for the control in the class. Follow the following steps for the same

//To allow the system to do Overloading of the function :
public void dialogPostRun(DialogRunbase _dialog)
{
;
super(_dialog);
// allow the dialog infrastructure to raise dialog field events _dialog.dialogForm().formRun().controlMethodOverload(true); _dialog.dialogForm().formRun().controlMethodOverloadObject(this);
}


// To override the lookup method of a field. (For the third field)
private void fld3_1_lookup(FormControl _formControl, str _filterStr)
{
Object control;
;
control = dialog.formRun().controlCallingMethod();
WMSLocation::lookupLocationId(control, DlgFromWrhs.value(),InventLocation::find(DlgFromWrhs.value()).InventSiteId,true);
}

//modified
// To override the modified method of a field. (For the second field)

public boolean fld2_1_modified()
{
boolean                     ret;
Object                      control = dialog.formRun().controlCallingMethod();

WMSLocationIdDefaultIssue   WMSLocationIdDefaultIssue;
;
ret = control.modified();

if (ret)
{
    WMSLocationIdDefaultIssue = InventLocation::find(DlgFromWrhs.value()).WMSlocationIdDefaultIssue;

if (WMSLocationIdDefaultIssue)

DlgFromLocation.value(WMSLocationIdDefaultIssue);

else

DlgFromLocation.value('');

}

return ret;

}


There is a second method which is more concise in cases where we directly want to overload the runtime control properties 


–> A lookup method is required in the first place. Below is the sample code to lookup the exchange rates.

private void journal_Lookup(FormStringControl _control)

{    

    SysTableLookup sysTableLookUp;

    QueryBuildDataSource qbds;


    Query query = new Query();


    qbds = query.addDataSource(tableNum(LedgerJournalTable));    


    qbds.orderMode(OrderMode::OrderBy);

    qbds.addSortField( fieldNum( LedgerJournalTable , JournalNum), SortOrder::Descending);    


    query.allowCrossCompany(true);

    query.addCompanyRange( dlgLegalEntity.value() );        


    sysTableLookUp = SysTableLookup::newParameters(tableNum(LedgerJournalTable), _control, true);

    sysTableLookUp.addLookupfield(fieldNum(LedgerJournalTable, JournalName), false);


    sysTableLookUp.addLookupfield(fieldNum(LedgerJournalTable, JournalNum), true);

    sysTableLookUp.addLookupfield(fieldNum(LedgerJournalTable, Name));

    sysTableLookUp.addLookupfield(fieldNum(LedgerJournalTable, OriginalJournalNum));

    sysTableLookUp.addLookupfield(fieldNum(LedgerJournalTable, OriginalCompany));


    sysTableLookUp.parmQuery(query);

    sysTableLookUp.performFormLookup();


}

–> The above method can then be called in the dialog method of the runbase class


public Object dialog()

{

FormStringControl control;

dialog = super();


    dlgPostPayrolldlg = dialog.addFieldValue( extendedTypeStr(JournalId),postPayrollJournalId, "Journal to split");


   sourceJournalControl = dlgSourceBatch.control();

    journalToSplitControl.registerOverrideMethod(methodstr(FormStringControl, lookUp),methodstr(AFZ_CostAllocChangeProcess, journalToSplit_Lookup),this);


return dialog;


}

Sunday, August 30, 2020

Getting rid of Unidentified Network

 Had a bad network experience for a few days. My network was slow on the machine and was i was losing the connection a no of times in a day. 

Luckily if found a quick fix for the problem. Start the cmd command on an elevated command prompt and enter the following command 

C:\>netsh winsock reset

After this command restart your computer and hopefully the problem would be resolved. 

Friday, May 15, 2020

X++ SysOperation Framework

Firstly, what is a framework:
To understand frameworks we first need to understand libraries. Libraries are a bunch of code that is pre-written and packaged to save our time. When we need to do a task, we just call the appropriate library and it does the job for us. We don’t need to know the details of how the functions inside the libraries work, we just need to know how to call them.

Frameworks are just like libraries in a way that they make our job easier, but we can't call frameworks in the same way as libraries. To use framework, we have to learn the framework, the framework gives us a structure to place and call our code, and not the other way round.

In simple terms framework is to structure what libraries is to code. Using library we reuse code, and using a framework we reuse a class structure.

When we work with X++ there are these set of framework classes that are used all over X++ development.

SysOperation framework:  
The SysOperation is used whenever there is a user interface which triggers a certain functionality. Its quite close to the MVC pattern and work on the similar principles of segregating code to remove dependencies. 

The Model : Data contract
Its the model class from the MVC pattern in which we define attributes we need for our operation, commonly set as parameters by the user in a dialog. A regular class is identified as a SysOperation Data Contract class by adding the DataContractAttribute attribute to its declaraion.

Additionally, if we want a set of methods to be available to us, we can also extend the SysOperationDataContractBase base class. With this class, we can define how our basic dialog will look like to the user. We can define labels, groups, sizes and types of the parameters.

The View : UI Builder
Its an optional class and is the view part from the MVC pattern. Generally AX creates the dialog for us with a standard view, however if are not happy with the standard view of we want to extend it we use the UI Builder class.

The Controller : Controller 
The controller orchestrates the whole operation. It holds information about the operation, such as if it should show a progress form, if it should show the dialog, and its execution mode - asynchronous or not. To create a controller class you should extend the SysOperationServiceController.

Service
While using the MVC we have to understand that not everything is a perfect MVC and as per OOP principles we have to ensure the dependencies between the classes is minimal. Technically one could put the business logic in the controller, however what if the same business logic has to be used outside the controller and without an interaction ? Hence, it a good idea to store the business logic outside the controller and hence we have the service classes. 

The service class stores the business logic. To create a service class we have to extend it from the SysOperationServiceBase class. When constructing your controller, you can indicate which class holds the operation that the controller will trigger.

Monday, April 27, 2020

Check for Localization

Localization needs can break our existing code. Sometimes its required to consider the localized configuration for a given region and then accordinlgy take some actions.

Given below is the example where we are expected to check if the current legal entity is the localized legal entity for India.

use the below macro in the declaration section of the object
#ISOCountryRegionCodes

Now the macro #isoIN would be available and can be used as follows:
SysCountryRegionCode::isLegalEntityInCountryRegion([#isoIN]);

Tuesday, April 07, 2020

Dimension Tables

Step 1: Lets take a simple scenario of creating 2 dimensions or Attributes.
  1. D1
  2. D2


Step 2: These attributes would then have values
    1.1  DXB
    1.2  IND

    2.1  SALES
    2.2  OPS
    2.3  ADMIN

Step 3: These attributes can be combined to create attribute sets. A set would have the individual dimensions and the sequence in which they are used as details
    3.1  SET1
          3.1.1  D1
          3.1.2  D2

    3.2   SET2
          3.2.1  D2
          3.2.2  D1


Step 4: Based on the sets defined above a combination of attribute values could be created
  4.1    SET1
     4.1.1   DXB+SALES
     4.1.2   DXB+OPS
     4.1.3   DXB+ADMIN


  4.2  SET2
    4.2.1    IND+SALES
    4.2.2    IND+OPS
    4.2.3    IND+ADMIN


When the above structure has to be stored in AX tables, it is divided in two parts. The part 1 takes care of storing the schema and the part 2 takes care of storing the values.

Part 1 : the details about the dimensions are stored in
  1. DimensionAttribute = this tables is the dimension master. Each dimension has 1 record in this table. (Step 1)
  2. DimensionAttributeSet = this table maintains the dimension set. (Step 3)
  3. DimensionAttributeSetItem = this table store the details of individual attributes in each set (Step 3.1.1 to 3.2.2)

 Part 2 : The *Value counterparts are :-
  1. DimensionAttributeValue : The individual values ( Step 1.1 to 2.3). There is a EntityInstance field in this table. That’s the relation to the value original table when the dimensions are not custom values.
  2. DimensionAttributeValueSet : The values corresponding to each set. There is a hash value generated for each combination of values. (a hash is a numeric equivalent of a string)  
  3. DimensionAttributeValueSetItem : The individual values for each of the attribute of the set.
  4. FinancialTagCategory: This table stores record of custom financial dimension.
  5. DimensionFinancialTag: this table stores custom financial dimensions value.

The combination of Ledger Account with the DimensionAttributes is stored in a new set of tables referred as ValueGroup Tables. As the name suggests the value group is a group that is created to store values (amounts)
  1. DimensionAttributeValueCombination: Stores combination of Ledger and DimensionAttributes
  2. DimensionAttributeValueGroup: Stores dimension group
  3. DimensionAttributeValueGroupCombination: Store relation of DimensionAttributeValueGroup and DimensionAttributeValueCombination
  4. DimensionAttributeLevelValue: Stores dimension value of ledger dimension