New IBM Resources

Hello;

As I noticed yesterday IBM published some new materials for Maximo 7.x
Here is the development guide for Maximo 7:
http://www-01.ibm.com/software/brandcatalog/portal/opal/details?catalog.label=1TW10MA2K

Here is the javadocs for Maximo 7.1.1.5 (Different than 7.1.1.1)
http://www-01.ibm.com/software/brandcatalog/portal/opal/details?catalog.label=1TW10MA1Z

Have a good day…

read comment here

Stop Workflow of a Closed Record

Hello;

Many people have records those are closed automatically via automation tools like Omnibus, or escalations. And these records remain in workflow even they are closed. So there is a little piece of code which can resolve this problems..
First go to the database configuration and create a relationship called “ACTIVEWORKFLOW” which can get you active workflows on the record. An example of ticket should be like this:
Name: ACTIVEWORKFLOW
Child Object: WFINSTANCE
Where Clause: ownerid=:ticketuid and ownertable=:CLASS and active=1
Remarks: Gets the related active workflow instances

Now create the class and rebuild redeploy maximo.ear..
Now all you have to do is to create an escalation which runs every 10 minutes.(Or whatever you want) Make sure you have stated closed records in where clause.. (Write historyflag=1 for workorder or ticket objects)
And make it run…

Note: You can run this code for every object. Because the code is written for Mbo Object.

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
package custom.common.action;
 
import java.rmi.RemoteException;
 
import psdi.mbo.MboRemote;
import psdi.util.MXException;
import psdi.workflow.WFInstanceRemote;
import psdi.workflow.WFInstanceSetRemote;
 
public class stopWFonClosedRecords implements
psdi.common.action.ActionCustomClass {
 
public void applyCustomAction(MboRemote mbo, Object[] arg1)
throws MXException, RemoteException {
// TODO Auto-generated method stub
WFInstanceSetRemote wfInstanceSet=(WFInstanceSetRemote) mbo.getMboSet("ACTIVEWORKFLOW");
if(!wfInstanceSet.isEmpty()){
for(int i=0;i<wfInstanceSet.count();i++){
WFInstanceRemote wfInst=(WFInstanceRemote) wfInstanceSet.getMbo(i);
wfInst.stopWorkflow("Auto Stop");  // Memo of the transaction...
wfInstanceSet.save();
}
}
 
}
}

make a comment

Route workflow from a table row

Hello;

Sometimes you need to start workflow of child records from the parent record… For example you have a problem record and there are 5 child activities. Normally you have to start workflow by going to the related record. With this piece of code you can start workflow from the Activities table of the parent problem record.
First create a ROUTEWF Button in the table. To do this drop a new tablecol to the table. And select Event as type. Select a route image. And enter ROUTEWF as event name.
Then change the bean class name to your class which you are creating now. (Be careful; I extended Problem activities table bean class here, you should extend whatever you need.)
Write your workflow name to the WFNAME in the code.

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
package custom.beans.app.problem;
 
import com.ibm.tsd.pmcom.webclient.beans.PmActivitiesBean;
import psdi.app.workorder.WOActivityRemote;
import psdi.server.MXServer;
import psdi.webclient.system.controller.SessionContext;
import psdi.workflow.WorkFlowServiceRemote;
 
public class problemActivitiesBean extends PmActivitiesBean
{
public int ROUTEWF()
{
MXServer mxs;
try
{
mxs = MXServer.getMXServer();
WorkFlowServiceRemote wsrmt = (WorkFlowServiceRemote)mxs.lookup("WORKFLOW");
 
WOActivityRemote mbo = (WOActivityRemote)getMbo();
wsrmt.initiateWorkflow("WFNAME", mbo);
fireStructureChangedEvent();
refreshTable();
this.sessionContext.queueRefreshEvent();
}
catch (Exception e)
{
e.printStackTrace();
}
return 1;
}
}

You’re good to go now;

Have a good day…

read comment here

Consume Web Services with VB.Net 2005

Hello;

Here is an example of consuming web services with VB 2005.. IT creates a new SR with authentication.

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
Dim maximoSvc As New Maximo.MXSR()
        Dim maximoSRArr(0) As Maximo.MXSR_SRType
        Dim maximoSR As New Maximo.MXSR_SRType()
        Dim changeDate As New Maximo.MXDateTimeType
        Dim DESCRIPTION_LONGDESCRIPTION As New Maximo.MXStringType
        Dim REPORTEDBY As New Maximo.MXStringType
        Dim IMPACT As New Maximo.MXLongType
        Dim reply(0) As Maximo.SRKeyType
        Dim cred As New System.Net.NetworkCredential
 
        Dim actLabCost As New Maximo.MXDoubleType
 
        cred.UserName = "maxadmin"
        cred.Password = "maxadmin"
        maximoSvc.Credentials = cred
 
 
        DESCRIPTION_LONGDESCRIPTION.Value = "longdesc"
        REPORTEDBY.Value = "USER"
        IMPACT.Value = 4
 
 
        maximoSR.DESCRIPTION_LONGDESCRIPTION = DESCRIPTION_LONGDESCRIPTION
        maximoSR.REPORTEDBY = REPORTEDBY
        maximoSR.AFFECTEDPERSON = REPORTEDBY
        maximoSR.IMPACT = IMPACT
        changeDate.Value = System.DateTime.Now
        maximoSR.CHANGEDATE = changeDate
        maximoSR.URGENCY = IMPACT
        actLabCost.Value = 0
        maximoSR.ACTLABCOST = actLabCost
        maximoSRArr(0) = maximoSR
        reply = maximoSvc.CreateMXSR(maximoSRArr, System.DateTime.Now, True, "", "EN", "11111", "7.0")
        Dim MaximoTicketid As String
        MaximoTicketid = reply(0).TICKETID.Value

Have a good day…

make a comment

Flow Action in Workorder

There is a new feature called Flow action in Maximo 7.1
It lets you to change status of activities,workorders and task according to the related records..

Here is the detailed explanation of this feature:
http://www-01.ibm.com/support/docview.wss?uid=swg21327119&myns=swgtiv&mynp=OCSSWK4A&mynp=OCSSLKT6&mync=R

Have a good day..

make a comment

Search Functions in Maximo

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..

read comments here

Show Workorder on Google Map

Google Map in Workorder Tracking

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&amp;v=2&amp;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…

read comments here

Set new Fields Null on Duplicate

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…

read comments here

Restricting Status List on List tab

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…

make a comment

Set Inbox Order

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…

read comment here