April 19, 2016

Display bullettin board messages opened by default

A common requirement is to display the bulletin board messages in a more visible way.
A simple solution is to display the formatted message opened by default.

To achieve this you can edit the following JSP file: [SMP]\applications\maximo\maximouiweb\webmodule\webclient\components\bulletinboard.jsp

On my Maximo i have this line of code at row 335:


If you change the display attribute to 'inline' it will show the full message without clicking.


Rebuild and redeploy maximo.ear file and you are done.

April 6, 2016

Maximo Anywhere API Reference

The configuration and customization chapters of the Maximo Anywhere documentation is great for many scenarios but sometimes you need to work with Dojo scripting and Anywhere platform to implement changes to standards screens and business rules.

I have developed my own Anywhere API Reference with the objective of helping myself and the Anywhere technical community out there.

Feedback is welcome but please do not post comments with generic questions I don't have time to answer to all of you.


Package platform.model

Package ui.control

April 5, 2016

Restricting status changes in Maximo Anywhere

A common requirement in Maximo projects is to restrict work order status changes based on some internal business rules. This can be achieved on Maximo with the technique described in this article.
Unfortunately the rules set in the WOSTATUS domain on the server are not applied automatically to the Anywhere mobile applications so we need to customize the mobile apps to follow the same rules.

Lets first analyze how the status changes are managed in the Work Execution app.
The application.business.WorkOrderStatusHandler script implements a state machine where the matrix of allowed status changes are defined (state machine).

init: function(modelDataSet){
var settings = {};
settings.resourceName = "workOrder";
settings.stateToAlias = {};
settings.configuration = {
"WAPPR": ["WAPPR", "APPR", "INPRG",         "WMATL", "COMP",         "CAN"],
"APPR" : ["WAPPR", "APPR", "INPRG",         "WMATL", "COMP",         "CAN"],
"INPRG": ["WAPPR",         "INPRG",         "WMATL", "COMP"               ],
"WSCH":  ["WAPPR", "APPR", "INPRG", "WSCH", "WMATL", "COMP"               ],
"WMATL": ["WAPPR",         "INPRG",         "WMATL", "COMP",         "CAN"],
"COMP":  [                                           "COMP"               ],
"CLOSE": [                                                   "CLOSE"      ],
"CAN":   [                                                           "CAN"]

Unfortunately this script is referenced in many other scripts so the simplest may of overriding it is modifying it. This is not a best practice since this file may be overridden in an Anywhere fixpack but is a quick and dirty solution.
Another limitation of this solution is that it works only based on the domain internal values (SYNONYMDOMAIN.MAXVALUE).

Now imagine the following scenario. I have two aliases of the INPRG status: INPRG1 and INPRG2. I want to avoid a direct transition to INPRG2. Only INPRG1 to INPRG2 must be possible.

Another place where status changes are handled is the filtering rule in the WorkExecution.statusLookup lookup.

<lookup id="WorkExecution.statusLookup" label="Work Order Status" resource="domainwostatus"

If you look at the application.handlers.StatusChangeHandler.filterWOStatus(evenHandler) method you will notice it handles some logic and filters the visible status in the lookup. We can now override this method to implement our logic.

First of all create a new script custom.handlers.MyStatusChangeHandler.

[ "dojo/_base/declare",
  "application/business/WorkOrderStatusHandler" ],
function(declare, ApplicationHandlerBase, StatusChangeHandler, WorkOrderStatusHandler) {
return declare( [ApplicationHandlerBase, StatusChangeHandler], {

  // dummy method required only to ensure script loading
  dummyMethod: function(eventContext) {
  // Filter WO statuses to those available for selection
  filterWOStatus: function(eventContext) {
    // call the original filterWOStatus method

    // retrieve current status
    var currWO = eventContext.application.getResource("workOrder").getCurrentRecord();
    var currStatus = currWO.get("status");

    // retrieve wodomain resource
    var woStatusDomain = this.application.getResource('domainwostatus');

    // sets the additional filter if necessary
    if(woStatusDomain.isFiltered() && currStatus!="INPRG1"){
      woStatusDomain.filter("value!=$1", "INPRG2");


There are two important things to note here.
  1. How the original StatusChangeHandler script is extended using the (see Dojo declare tutorial for details)
  2. How the additional filter value!='INPRG2" is applied to the existing filter already set in the woStatusDomain resource.
  3. The filter is specified using JavaScript syntax not SQL (JavaScript conditions syntax).
Now you need to modify the app.xml to include your customized transition rule.
Modify the WorkExecution.statusLookup filterClass from application.handlers.StatusChangeHandler to custom.handlers.MyStatusChangeHandler.

It seems also this is not enough because the custom script is not loaded by just referencing it in the filterClass.To circumvent this problem you can add a dummy eventhandler like this.

<eventHandler event="render" 
class="custom.handlers.MyStatusChangeHandler" method="dummyMethod" />

March 25, 2016

Remove the 200 record limit in Anywhere simulator

The mobile app simulator is a great tool when developing mobile applications with Maximo Anywhere. Obviously it does not replace a good test on the real device but it is essential during development especially when the browser development tools are used to inspect and debug the app.
One limitation of the simulator is the 200 records limit when downloading lookup data so the following message is displayed: When running in a browser, a maximum of 200 records are downloaded per lookup.

Set debug="true" attribute to the app element at the beginning of the app.xml file.

However, if you have a lot of data to download this may cause a hang during the lookup data download in the web browser. This is because the mobile browser storage is limited to few megabytes.

To circumvent this problem you can try to modify
WorkExecution\common\js\platform\store\_ServerDataDownloadManager.js file.
Search for '200' and you should see something like this.

if (limitData && pageSize > 200) {
  pageSize = 200;

Change both numbers to 500 or whatever number fits your needs.