Author: admin Post Date: June 6 2009
Hello;
After a long time I can write again…Meanwhile I changed my job. I am not a technical consultant anymore. I started to work in IS BANK (the biggest bank of Turkiye) as IBM CCMDB Developer. Now I prepared a flash to show you about maximo search functions. Most of you already know these stuff. But I think it will be good for someone. Hope you like it… If you like this kind of flash movies I will prepare more..
You can reach flash from here
Have a good day..
Author: admin Post Date: March 31 2009

Google Map in Workorder Tracking
Hello;
If you store coordinates in your workorders or location etc. you can show the places on google maps in Maximo. I implemented this on Maximo 6. There are many steps to accomplish this task.. I will tell you about it step by step…
1-You have to get a Google Map api key from this address: http://code.google.com/apis/maps/signup.html .. Write your maximo server address to the textbox and click Generate Key.. Note your key.. We will use it later…
2-Create iframe control: Go to %MAXIMOROOT%\applications\maximo\maximouiweb\webmodule\webclient\controls and create a folder named: iframe. We will send data to google map script from this control. I assume that longitude and latitude are stored in Workorder object as Longitude and Latitude attributes…
Create a jsp file named control.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
| <%@ include file="../../common/controlheader.jsp" %>
<%--
PROPERTY GLOBAL VALUES
id true ...
height false ###
width false ###
url false ...
--%>
<mro:handleevent eventtype="loadinit">
<mro:loadglobalproperties />
<%
int height = controlProperties.getInt("height", 100);
int width = controlProperties.getInt("width", 100);
String url = controlProperties.getString("src");
%>
</mro:handleevent>
<mro:handleevent eventtype="render">
<%
int height = controlProperties.getInt("height", 100);
int width = controlProperties.getInt("width", 100);
String url = controlProperties.getString("src");
String apptitle = sessionContext.getCurrentApp().getAppTitle();
psdi.util.MXSession mxs=sessionContext.getMXSession();
psdi.mbo.MboSetRemote woSet=mxs.getMboSet("WORKORDER");
woSet.setWhere("WOCLASS in ('WORKORDER', 'ACTIVITY') and istask=0 and boylam is not null and enlem is not null");
System.out.println("WO Count: "+woSet.count());
java.util.ArrayList coordinateList = new java.util.ArrayList(woSet.count());
for(int i=0;i<woSet.count();i++){
java.util.ArrayList coordinate=new java.util.ArrayList(5);
psdi.mbo.MboRemote wo=woSet.getMbo(i);
coordinate.add(0,wo.getString("WONUM"));
coordinate.add(1,wo.getString("DESCRIPTION"));
coordinate.add(2,wo.getString("STATUS"));
coordinate.add(3,wo.getString("LONGITUDE"));
coordinate.add(4,wo.getString("LATITUDE"));
coordinateList.add(coordinate);
}
session.setAttribute("CoordinatesList",coordinateList);
%>
<iframe src="<%=url%>" height="<%=height%>" width="<%=width%>"> </iframe>
</mro:handleevent>
<%@ include file="../../common/controlfooter.jsp" %> |
Here we defined iframe control and we added the workorder information to the CoordinatesList variable of session.
Now create another file called allwoongmaps.jsp in the same folder..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title></title>
<script src="http://maps.google.com/maps?file=api&v=2&key=<strong>KEY</strong>"
type="text/javascript"></script>
<script type="text/javascript">
function initialize() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map_canvas"));
GEvent.addListener(map, "click", function(overlay, point){
if (point) {
map.addOverlay(new GMarker(point));
var msg = "Latitude: "+point.lat()+"<br>"+"Longitude: "+point.lng();
document.getElementById("mypoint").innerHTML = msg;
} //close if(point)...
}); //close GEvent...
var yellowIcon = new GIcon();
yellowIcon.image ="http://esa.ilmari.googlepages.com/markeryellow.png";
yellowIcon.iconSize = new GSize(20, 34);
yellowIcon.iconAnchor = new GPoint(9, 34);
var turqIcon = new GIcon();
turqIcon.image = "http://www.google.com/uds/samples/places/temp_marker.png";
turqIcon.iconSize = new GSize(20, 34);
turqIcon.iconAnchor = new GPoint(9, 34);
<%
java.util.ArrayList CoordinateList=(java.util.ArrayList) session.getAttribute("CoordinatesList");
for(int i=1;i<CoordinateList.size()+1;i++){
java.util.ArrayList Coordinate=(java.util.ArrayList)CoordinateList.get(i-1);
String wonum=(String)Coordinate.get(0);
String description=(String)Coordinate.get(1);
String status=(String)Coordinate.get(2);
String enlem=(String)Coordinate.get(3);
String boylam=(String)Coordinate.get(4);
double boydouble=Double.parseDouble(boylam);
double enlemdouble=Double.parseDouble(enlem);
String marker="marker"+i;
String point="point"+i;
String icon;
if(wonum.equalsIgnoreCase("1000"))
icon="yellowIcon";
else icon="turqIcon";
if(i==1){ %>
map.setUIToDefault();
map.setCenter(new GLatLng(<%=boydouble%>,<%=enlemdouble%>), 5);
<%}%>
var <%=point%> = new GLatLng(<%=boydouble%>,<%=enlemdouble%>);
var <%=marker%>=new GMarker(<%=point%>,{icon:<%=icon%>});
map.addOverlay(<%=marker%>);
<%
}%>
}
}
</script>
</head>
<body onload="initialize()" onunload="GUnload()">
<div id="mypoint"></div>
<div id="map_canvas" style="width: 470px; height: 200px"></div>
</body>
</html> |
On line 7 we add our own Google api key that we noted before… and we create our own map from longitude and latitude information on Workorder…
Now open Application Designer and export your application as xml file.Save it and back it up. then add this line to whereever you want.
<iframe src="http://localhost:7001/maximo/webclient/controls/iframe/allwoongmaps.jsp" height="200" width="500" id="genid_headera_4_child_1" />
localhost should be your servers ip…;
Save it and import from application designer.. Rebuild and redeploy… You’re going to see map like this…
Author: admin Post Date: March 9 2009
Hello;
Sometimes you add new fields to the maximo mbo’s. And when you duplicate the mbo new fields are filled automatically… You should customize java to prevent this.. I will use ITEM object in this example….We are extending psdi.webclient.beans.item.ItemAppBean class in bean classes. Then we put this class into %MAXIMOROOT%\applications\maximo\maximouiweb\webmodule\WEB-INF\classes\com\item
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| package com.item;
import java.rmi.RemoteException;
import psdi.util.MXException;
public class newItem extends psdi.webclient.beans.item.ItemAppBean
{
public newItem()
{
}
public int DUPLICATE() throws MXException, RemoteException
{
super.DUPLICATE();
getMbo().setValueNull("NEWFIELD",2L);
getMbo().fireStructureChangedEvent();
sessionContext.queueRefreshEvent();
return 1;
}
} |
Here we first duplicate the item object.. Then set NEWFIELD nulll.. Then we refresh the page…
After compile,build/deploy, we should open application designer…
From “Select Action” menu click “Toggle show all controls” Then on the page we select presentation.. Then we write com.item.newItem to the bean class field… We save the application… Then test it…
Have a good day…
Author: admin Post Date: March 5 2009
Hello;
You may want to restrict status list on some applications. For example in wotrack, on the list table you may want that the user can get status to ‘WAPPR’ . So other statuses like COMP,INPRG must be restricted from the list..
Here you should extend psdi.webclient.beans.workorder.WOChangeStatusBean class. And you must override public synchronized MboSetRemote getList(int nRow, String attribute) method. Here is how it can be done…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
package com.custom.workorder;
import java.rmi.RemoteException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import psdi.app.workorder.WORemote;
import psdi.mbo.*;
import psdi.security.UserInfo;
import psdi.server.MXServer;
import psdi.util.*;
import psdi.webclient.beans.common.ChangeStatusBean;
import psdi.webclient.system.beans.DataBean;
import psdi.webclient.system.beans.ResultsBean;
import psdi.webclient.system.controller.*;
public class newWOChangeStatusBean extends psdi.webclient.beans.workorder.WOChangeStatusBean
{
public void initialize()
throws MXException, RemoteException
{
super.initialize();
}
public synchronized MboSetRemote getList(int nRow, String attribute)
throws MXException, RemoteException
{
if(app.getApp().equalsIgnoreCase("WOTRACK") && app.onListTab()){
MboSetRemote currentList=super.getList(nRow,attribute);
currentList.setWhere("value in ('WAPPR') and domainid='WOSTATUS'");
currentList.reset();
return currentList;
}
else return super.getList(nRow,attribute);
}
} |
Here currentList is the list of statuses. We restrict it to show only WAPPR…
Now compile it rebuild, redeploy…
Now you have to tell maximo about new class. Go to the application designer..
From select action menu click export system xmls…
Click the arrow next to the LIBRARY.xml… New internet explorer window opens…
From File menu select “Save As”… Now take a back up of the original file in case of any accident…
Open it with a text editor like notepad++ …
Find the string with dialog id=”list_status” and replace psdi.webclient.beans.workorder.WOChangeStatusBean with com.custom.workorder.newWOChangeStatusBean
Import Library.xml to the system… Go to the application and test it…
Have a good day…
Author: admin Post Date: March 5 2009
Hello;
Our clients always have problems with their inboxes. One of the major problem is that the inbox is not sorted. To sort inbox in Maximo we have to modify a jsp file. Here is how it is done.. This is done for Maximo 6.2.2
First we open %MAXIMOROOT%\applications\maximo\maximouiweb\webmodule\webclient\controls\startcenter\portlets\inbxconfig.jsp file. Take a backup of this file…
Then we should find
1
2
3
4
| else
{
portletBean = (InboxPortletBean)sessionContext.getCurrentApp().get(portletId);
} |
After these lines add these…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| boolean allowsort = true;
if (portletBean.isPropertyDefined("allowsort") && portletBean.getPortletInfoValue("allowsort") != null )
{
if ( ((String)portletBean.getPortletInfoValue("allowsort")).equals("true"))
{
allowsort = false;
}
}
if (allowsort)
{
portletBean.setPortletInfoValue("sortattribute","startdate");
portletBean.setPortletInfoValue("sorttype","desc");
} |
On line 12,13 we ordered inbox to startdate descending… Then save the file… Rebuild and redeploy..
Have a good day…
PS: Test before taking it to the live system…
Author: admin Post Date: March 5 2009
Hello;
Now I am going to tell about custom action classes…
These classes help us to add custom actions to workflows…
We must write these classes in the psdi.common.action package.. We extend ActionCustomClass and override applyCustomAction method to make maximo do what we want to do…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| package psdi.common.action;
import java.io.PrintStream;
import java.rmi.RemoteException;
import psdi.mbo.MboRemote;
import psdi.server.MXServer;
import psdi.util.MXApplicationYesNoCancelException;
import psdi.util.*;
import com.custom.workorder.*;
public class newFlowAction
implements ActionCustomClass
{
newFlowAction()
{
}
public void applyCustomAction(MboRemote mboremote, Object aobj[])
throws MXException, RemoteException
{
com.custom.workorder.newWORemote mbo=(com.custom.workorder.newWORemote)mboremote;
if(mbo.getString("STATUS").equalsIgnoreCase("INPRG")){
mbo.getMboSet("OTHEROBJECT").deleteAll();
}
}
} |
Here on line 23 we cast our mbo to custom Workorder object. Now we are able to use workorder’s methods on mbo object. On line 24 we check if the status is INPRG or not…
And on line 25 if the status is INPRG we select the OTHEROBJECT relationship and delete all mbo’s that came with OTHEROBJECT relationship…
Then we compile the code… Rebuild Maximo.ear.. Redeploy it… Now you can use it in the related workflow..
Have a good day…
Author: admin Post Date: March 2 2009
One of the best improvements in Maximo 7.x is conditional user interfaces. You can create your conditions in Conditional Expression Manager application. But sometimes there are some issues that you can not write sql sentences. For these cases we can write our own condition class. We must extend psdi.common.condition.CustomCondition class to write the new class. And we need to override evaluateCondition(MboRemote mbo, Object arg1) method. Here is an basic example..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| package com.custom.workorder;
import java.rmi.RemoteException;
import psdi.mbo.*;
import psdi.common.condition.CustomCondition;
import psdi.util.*;
public class TipCondition implements CustomCondition {
public boolean evaluateCondition(MboRemote mbo, Object arg1) throws MXException, RemoteException {
newWORemote wo = (newWORemote) mbo;
if (wo.getString("ISSUETYPE").equalsIgnoreCase("PROBLEM")) {
psdi.server.MXServer mxs = psdi.server.MXServer.getMXServer();
MboSetRemote loc_set = mxs.getMboSet("LOCATIONS", wo.getUserInfo());
loc_set.setWhere("location in('"+wo.getString("CENTER1")+"')");
loc_set.reset();
if (loc_set.count() > 0) {
String kanal = loc_set.getMbo(0).getString("CAPACITY");
if (kanal.startsWith("4")) {
return true;
}
}
return false;
} else {
return false;
}
}
public String toWhereClause(Object arg0, MboSetRemote arg1) throws MXException, RemoteException {
return "";
}
} |
Have a good day…
Author: admin Post Date: March 1 2009
Hello;
Now I will explain a bit about importing from excel sheet. Here I will use Jexcel Api to read excel files. This script was written for Maximo 6.2.1, and I will use Jexcel Api 2.6.9 which can be downloaded from here.
Here is the code:
/*
* addAlnDomain.java
*
* Created on September 2, 2008, 4:00 PM
*/
import java.io.File;
import java.io.PrintStream;
import jxl.*;
import psdi.app.system.*;
import psdi.mbo.MboRemote;
import psdi.util.MXSession;
/**
*
* @author bbolek
*/
public class addAlnDomain {
/** Creates a new instance of addAlnDomain*/
public addAlnDomain() {
}
public void add(String filename) {
try {
MXSession s;
s = MXSession.getSession();
s.setHost("localhost:9898/MXServer"); //Server Name
s.setUserName("wilson");
s.setPassword("wilson");
s.connect();
Workbook workbook = Workbook.getWorkbook(new File(filename + ".xls"));
Sheet sheet = workbook.getSheet(0);
int k = 1;
String description, value;
MaxDomainSetRemote maxdomain=(MaxDomainSetRemote) s.getMboSet("MAXDOMAIN");
maxdomain.setWhere("DOMAINID='DOMAINNAME'");
maxdomain.reset();
MboRemote maxDomain=maxdomain.getMbo(0);
while (sheet.getCell(0, k).getContents().length() > 1) {
value = sheet.getCell(0, k).getContents().toString();
description = sheet.getCell(1, k).getContents().toString();
System.out.println("VALUE :"+value+ " DESCRIPTION: "+description );
ALNValueSetRemote alnSet =(ALNValueSetRemote) maxDomain.getMboSet("ALNDOMAINVALUE");
ALNValueRemote aln = null;
aln = (ALNValueRemote) alnSet.addAtEnd();
aln.setValue("VALUE", value);
aln.setValue("DESCRIPTION", description);
alnSet.save();
k++;
}
} catch (Exception E) {
E.printStackTrace();
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
addAlnDomain new_AlnDomain = new addAlnDomain();
new_AlnDomain.add("Example");
}
}
In here; between line 28-32 server settings are set. Then on line 34 excel workbook is opened.
On line 35 first sheet is selected. On line 39 the domain with name “DOMAINNAME” is selected.
Line 42 shows that the loop will continue if there is a value on the first column of excel.
Line 43 and 44 reads the excel and sets the variables. And on line 48 we create a new ALNDomain mbo. And on 49 we added it to the AlnDomainSet.
Then we bind the variables and save the MboSet…
On line 62 we set the excel filename…Here it is Example.xls
All Mbo’s can be read from excel and imported to Maximo in this way. It is quite easy and customizable…For example you can set some rules to import in java like
-import data that starts with 1,
-import data which is like ‘%10%’
-etc…
Have a good day…
Author: admin Post Date: February 24 2009
Hello;
Another basic java functionality is to create a field class. Assume that you have a field. And if it is filled you have to make it readonly to prevent anyone changing the field. I’ll assume this field is WORKORDER.ASSETNUM… To do this we have to extend psdi.app.workorder.FldWOAssetnum class which is default class for this field. Here is the basic code..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| package custom.workorder;
import psdi.mbo.*;
import psdi.util.*;
import psdi.app.workorder.FldWOAssetnum;
import java.util.*;
import java.rmi.*;
public class newFldWOAssetnum extends psdi.app.workorder.FldWOAssetnum
{
public newFldWOAssetnum (MboValue mbovalue) throws MXException, RemoteException
{
super(mbovalue);
}
public void init() throws MXException {
super.init();
if(!getMboValue().isNull()) //If the value is not null
{
getMboValue().setReadOnly(true); //make it readonly
}
}
} |
After this you have to write ‘custom.workorder.newFldWOAssetnum’ to the class field of WORKORDER.ASSET in database configuration.
Run configdb
Build maximo.ear
Redeploy maximo.ear
Have a good day…
Author: admin Post Date: February 24 2009
Hello;
One of the basic java functionality is to create new mbo’s and changing its default behaviour. For example we can create a new mbo as the child of Workorder. And assume there is a relationship between workorder and newMbo as wonum=:wonum. When we add a new record from the user interface, new record’s wonum is not populated automatically. So we have to extend psdi.mbo.Mbo to automate this. Here is how it is done….
File :custom.newMbo.newMbo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| package custom.newMbo;
import psdi.util.*;
import java.util.*;
import psdi.mbo.*;
import java.rmi.*;
import psdi.server.MXServer;
public class newMbo extends Mbo
implements newMboRemote {
/**
* Constructor
*/
public newMbo(MboSet ms) throws MXException, RemoteException {
super(ms);
}
public void add() throws MXException, RemoteException {
super.add();
MboRemote mboremote = getOwner();
setValue("WONUM", mboremote.getString("WONUM"), 2L);
}
} |
File :custom.newMbo.newMboSet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| package custom.newMbo;
import psdi.mbo.*;
import psdi.util.*;
import java.util.*;
import java.rmi.*;
public class newMboSet extends MboSet
implements newMboSetRemote
{
/**
* Constructor
*/
public newMboSet(MboServerInterface ms)
throws MXException, RemoteException
{
super(ms);
}
protected Mbo getMboInstance(MboSet ms)
throws MXException, RemoteException
{
return new newMbo(ms); // this is the key line ...
}
} |
File :custom.newMbo.newMboRemote
1
2
3
4
5
6
7
8
9
| package custom.newMbo;
import psdi.mbo.*;
import psdi.util.*;
import java.rmi.*;
public interface newMboRemote extends MboRemote
{
} |
File :custom.newMbo.newMboSetRemote
1
2
3
4
5
6
7
8
9
| package custom.newMbo;
import psdi.mbo.*;
import psdi.util.*;
import java.rmi.*;
public interface newMboSetRemote
extends MboSetRemote
{
} |
Then you have to compile and rmic these files. Then Go to the database configuration find your object. Enter ‘custom.newMbo.newMboSet’ to the class…
Configure DB
Build Maximo.ear
Deploy Maximo.ear
Tip: It is better to make Wonum field readonly on user interface. Users must not change the field from the user interface
Then you’re good to go….
Have a good day…