How To Create A Custom Dialog Box in Maximo Allowing User To Email BIRT Report
How To Create A Custom Dialog Box in Maximo Allowing User To Email BIRT Report
Maximo Version:
7.1.1.4
Pre-requisites:
o
o
o
o
File Download:
Right click or option-click the link and choose "Save As..." to download the file.
1. Custom dialog box (2KB)
2. Java source code (9KB)
This is a comprehensive tutorial on how to create a custom dialog box in Maximo allowing user to
email BIRT report as attachment. While this tutorial is about a specific function, the overall aim is to
use this example as a segue to introduce a few useful and common concepts to those who are new to
Maximo/MBO customization, such as:
Finished Product
Before we continue, let's take a sneak peek at the finished product (see both figure 1 and 2 below) so
that you are mindful of what we are trying to accomplish here.
Figure 1: What the custom dialog box looks like.
Tip: In this tutorial, I am adding the custom dialog box to the Purchase Orders application and attaching the PO
details report to the email. Theoretically, you can add the custom dialog box to one or more Maximo applications
and have each dialog box calling a different report.
Depending on your experience, you can either follow the entire tutorial step by step, or you can skip to
the section that requires your attention.
Maximo, at this point of writing, does not provide us a GUI to create a custom dialog box. Since the
dialog box is XML-based, you can create one using any text or XML editor you have. Once you have
added a custom dialog box to a Maximo application, you can actually modify the dialog box via
Application Designer. For those who prefers a GUI, you can always create a skeleton of your dialog
box, import it into Maximo and then leverage Application Designer to design your form that way.
Personally, I am comfortable designing my form with text editor and I always find Application Designer
buggy in Firefox browser.
In figure 1 above, you can see what the dialog box looks like graphically. The following figure shows
the XML code behind, which you may download from the File Download section.
Figure 3: The XML code behind the custom dialog box.
Before I dwell deeper into the XML, let me first mention that each XML element must have a unique
id. If not, you will experience problem importing your XML code into Maximo. Now, let's examine the
XML line-by-line:
Line # Comment
1
The "beanclass" attribute is how you associate a bean class (i.e., the AppBean class which
we will write later) to this dialog box. If you compile your AppBean class under a different
class path, be sure to specify your value here.
The "id" attribute here is the dialog box id. Typically, an element id has no length restriction,
but there is one here so beware! Later on, you will need to create a signature option for this
dialog box and the name of the signature option should match this dialog box id. Maximo only
allows a maximum of 25 characters for the name. Furthermore, when you try to associate a
signature option to a custom toolbar control (which we will also do), Maximo will throw an
error if your signature option is more than 10 characters long. In short, keep your dialog box
id to no more than 10 characters long to save yourself a ton of headache!
The "mboname" attribute is the name of the MBO which we want to associate our dialog box
to. Since our example is about emailing PO details report, the logical MBO to use is "PO". If
you want to add this tool to the Work Order Tracking application and allow user to email WO
details report, you should change the MBO to "WORKORDER".
Line # Comment
2
The "helpgrid" element is entirely optional. It is an excellent way for displaying long static
message on the dialog screen.
This line will require a bit of an explanation, so please bear with me.
Some background information first. Any XML element that is used to store/capture/display
data must be bound to an existing MBO attribute. An MBO attribute can be of persistent or
non-persistent type. If you want to store the data in the database, you have to use an
attribute that is of persistent type. In our example, we have 4 visible textbox controls on the
dialog box to capture email to, email cc, email subject and email message respectively. Since
it doesn't make sense for us to store these data in the database (we only need to store them
temporary somewhere, access them and dispose them thereafter), we need to use attributes
that are of non-persistent type. With that in mind, we now have a choice to make. We need
an MBO with non-persistent attributes which we can bound our controls to. So, we can either
create a custom MBO object or modify an existing one. It turns out that there is a third hidden
option. There is already an MBO object named "REPORTPARAMETER" in the system that
can fulfill all our needs just out-of-the-box. If you look up the object via Database
Configuration application, you can see that it has all the necessary attributes we need for
emailing purposes.
If you refer back to line #1, you can see that we'd already bound an MBO to the dialog box.
To introduce another MBO into the mix, we need to use a datasource element. As a matter of
fact, you can add as many datasource elements as you want or none at all if you only need to
work with one MBO.
Here, I am adding a datasource element with "REPORTPARAMETER" as the MBO. You will
see that all my textbox and defaultvalue controls referenced this datasource element (via the
"datasrc" attribute) and its attributes (via the "dataattribute" attribute). Needless to say, this is
important.
4, 5, 6 As the name implies, defaultvalue element is hidden element and is traditionally used for
setting default value for an MBO attribute. For instance, if you like to provide a default email
message, you can simply add the following line to the XML. Notice the value for
"dataattribute" attribute is the same as the multilinetextbox element's "dataattribute" value
which is "EMAILCOMMENTS".
<defaultvalue id="rptemail_emailmessage"
dataattribute="EMAILCOMMENTS" datasrc="RPTEMAIL_ds1"
defaulttype="insert" value="Type your message here."/>
Here, I am actually using these defaultvalue elements to store system variables. I want to
expose them here (instead of hardcoding them in the Java class) so that they can be easily
changed (by you) and not having to go through the lengthy deployment process. Later I will
show you how we can programmatically access these values from the AppBean class.
About these system variables:
1. Report Name
Use this variable to specify which report to run. You can look up a list of report
names from the Report Administration application. The only caveat is that the report
must be able to accept a simple where clause that matches records by record id. If
Line # Comment
your report expects other report parameter(s) to run, you may need to adjust the
AppBean class yourself.
2. Report Output Directory
Specify a report output directory on the server. The custom AppBean class, which we
will discuss later, will need to write out a temporarily PDF document on the server
and then it will delete the document after sending the email. Occasionally, it may fail
to delete for whatever reason. I am exposing this variable just so that we can control
the ouput and know where to clean up. The custom AppBean class will create the
directory structure if does not exist.
3. Default Email Subject Line
Specify a default email subject line. The is entirely optional of course. This particular
default value also supports substitution variables. If, for instance, you would like to
show the current record id on the subject line, find out what the proper MBO attribute
name is and then surround it with curly brackets, e.g., {ponum}, {wonum}, etc. These
variables will be replaced by actual values on run-time. In the example here, I want to
display the PO number and PO description on the subject line.
7
The section element is mainly a layout element. My example here doesn't really illustrate its
purpose because I am employing a single column layout. If you want to create a multi-column
layout, be sure to read up more on this.
This textbox element is for user to enter email to addresses. Email addresses must be
comma separated. This control is bound to the REPORTPARAMETER.EMAILTO attribute.
This textbox element is for user to enter email cc addresses. Addresses must be comma
separated. The current user's email will be added here by default. If you don't want this, you
need to remove the line from the AppBean class. This control is bound to the
REPORTPARAMETER.EMAILCC attribute.
10
This textbox element is for user to enter email subject line. This control is bound to the
REPORTPARAMETER.EMAILSUBJECT attribute.
11
This multilinetextbox element is for user to enter email message. This control is bound to the
REPORTPARAMETER.EMAILCOMMENTS attribute.
14
When this button is clicked, it will fire the sendEmail() method, as stipulated by the "mxevent"
attribute, in the custom AppBean class. Needless to say, this method name must exist in the
bean class. If you want to change the method name, beware that you must change it in both
places.
15
When this button is clicked, it will cancel out the operation and close the dialog box. The
"dialogcancel" event is actually a common method inherited from the base class. We don't
need to write any custom code to handle this event.
Tip: When importing an Application Definition file, do not have the application record opened in the Application
Designer application. In fact, make sure the List tab is empty of any record before you do the import.
Tip: If you are developing a general purpose dialog box to be accessed by numerous applications and the dialog
box is bound to fixed MBO(s), you can add your dialog box to the system Library XML file (instead of individual
applications). The upside is less work for you, but the downside is that you may not be able to modify the dialog
box via the Application Designer application.
This tutorial focuses on the PO application. If you want to use other applications, by all means go
ahead. The steps are the same.
i.
ii.
iii.
Export the Application Definition (an XML file) of your application and save the file to a local
location.
iv.
Open the exported file with any text or XML editor of your choice.
v.
vi.
Just before the </presentation> end tag, insert your XML code block (from step 1) here.
Make sure your code is within the <presentation> tag and it doesn't break other existing
tags.
vii.
viii.
ix.
On the List tab, click on the Import Application Definition toolbar button to import your
modified file.
x.
Done.
ii.
iii.
iv.
v.
At a minimum, you need to provide a name for the option and a description (see figure 4).
Others you can do as you see fit. The only key thing to watch out for is that the option name
must be the same as your dialog box id. This is how the system associates this signature
option to your dialog box.
vi.
vii.
Launch the Security Groups application and retrieve a security group named "EVERYONE".
viii.
ix.
Look up the application of your choice and you should be able to see the new signature
option (see figure 5). Grant access to it and save your changes.
x.
Done.
Note: I am using the "EVERYONE" security group because it is the quickest approach for me to grant wide
access. You should really only give access to group(s) that needs it.
Follow these steps to create a custom toolbar button to launch your dialog box:
i.
ii.
iii.
iv.
o
o
o
o
o
o
o
Click on New Row to add a new row. Use the following values (also shown in figure 6):
Element Type = OPTION
Key Value = <Select your new signature option created in step 3 from the pick list.>
Image = nav_icon_statusSent.gif
Position = <Use any value as you see fit.>
Subposition = <Use any value as you see fit.>
Visible = Yes
Tabs = MAIN
v.
vi.
vii.
Go to any tab other than the List tab. You should be able to see your new custom toolbar
control. Click on it to open the dialog box. At this point, you can only view your dialog box. It
will not work because no functionality has been implemented yet.
viii.
Done.
The package name is custom.webclient.system.beans. If you are to modify this name, you need to
update the XML code for the dialog box accordingly. It is referenced there.
The initialize() is a method from the base class. We are simply overriding it here. This method is
automatically called when the dialog box first load. We will be setting default value for some form
controls here. Do not change the method name.
The sendEmail() is a custom method that will perform the core task, i.e., generate report and email
report. This method name is explicitly referenced in the XML code for the dialog box. You are free to
change the method name, but you must also update the XML code accordingly.
The log() is a custom method for writing out custom message to the log file. This method explicitly
uses the mail logger and it will only output message if the logger is in debug mode. Otherwise,
nothing will be written to the log file. Keep this method handy and use it on your other Java classes.
You might want to consider using other logger as well. The mail logger is appropriate in this tutorial
but may not be so in other situations. Check out the Logging application in Maximo for other types of
loggers.
The msgbox() is a custom method for displaying custom message on screen via a pop up window.
This method explicitly uses a custom message object created in Maximo (see step 6 for details). The
hardcoded strings "messagebox" and "CustomMessage" are used to identify that particular
message object. You may use other if you wish. Keep this method handy and use it on your other
Java classes.
Now, let's examine some specific functions:
i.
For datasource element, use the getDataBean() and pass in the datasource element id, e.g.,
ii.
ControlInstance ctr1 =
this.clientSession.findControl("rptemail_emailsubject");
String uservalue = ctr1.getProperty("value");
iii.
iv.
v.
vi.
ReportAdminServiceRemote reportservice =
(ReportAdminServiceRemote)MXServer.getMXServer().lookup("BIRTREPORT");
byte[] reportOutput = reportservice.runReport(ui, "poprint.rptdesign",
"PO", para, "newreport.pdf", "pdf");
vii.
ii.
iii.
Click on New Row to add a new row. Use the same settings as shown in figure 7 below. Both
the Message Group value and theMessage Key value are referenced in the AppBean class,
so they must match.
Figure 7: Creating a new message object.
iv.
Done.
Note: The "Display ID?" property doesn't seem to work in my current version of Maximo. Perhaps IBM will fix this
in future version. Supposeably, this property will allow us to hide the message ID on the message box but it
doesn't (as shown in figure 8).
Tip: Once you have a generic message box created, you can keep re-using it in your other Java classes. You
don't really need to create a new one each time.
ii.
iii.
iv.
Click on Save and then make sure to click on Select Action > Apply Settings after.
v.
Done.
Once you begin testing the email tool, make sure to check the output log file for logging information,
which should look something like this:
28 May 2012 09:11:37:381 [DEBUG] >>>> Entering
custom.webclient.system.beans.EmailReportAppBean:sendEmail()
28 May 2012 09:11:37:381 [DEBUG] >>>> Report Name = poprint.rptdesign
28 May 2012 09:11:37:381 [DEBUG] >>>> Where POID = 18704
28 May 2012 09:11:37:381 [DEBUG] >>>> Output File Path =
'E:\temp\PO_20120528091137AM.pdf'
28 May 2012 09:11:38:991 [DEBUG] ------------------------------------------28 May 2012 09:11:38:991 [DEBUG] To: [email protected]
28 May 2012 09:11:38:991 [DEBUG] From:
[email protected]
28 May 2012 09:11:38:991 [DEBUG] Subject:
Purchase Order #5992
28 May 2012 09:11:38:991 [DEBUG] Message:
testing
28 May 2012 09:11:38:991 [DEBUG] File
Attachment:E:\temp\PO_20120528091137AM.pdf
28 May 2012 09:11:38:991 [DEBUG] ------------------------------------------28 May 2012 09:12:03:802 [DEBUG] >>>> Exiting
custom.webclient.system.beans.EmailReportAppBean:sendEmail()
Tip: Change the log level back to "ERROR" when not testing or troubleshooting. Otherwise, you will end up with
huge log files taken up precious server disk space. "ERROR" log level means only error will be written to the log
file.
Copy your custom AppBean class to the following location on your Maximo server:
<maximo>\applications\maximo\maximouiweb\webmodule\WEB-INF\classes\
ii.
iii.
Done.
At this point, you are ready for testing. Simply launch your application of choice and test out the email
tool.
Tip: Custom bean class must be deployed to a different location on the server than other types of classes (e.g.,
field class, MBO class, etc.). For other types of classes, you have to copy your file to
<maximo>\applications\maximo\businessobjects\classes\. Whereas, for bean class the path is
<maximo>\applications\maximo\maximouiweb\webmodule\WEB-INF\classes\.The system will not inform you if
you have your class file at the wrong location. But you will be left wondering why your code doesn't work.
Final Notes
If you do find this tool useful, you may also want to consider these additional enhancements:
1. On the AppBean class, add a validation check to make sure email addresses entered are
comma delimited. The current code will throw an error if email addresses are delimited by
semi-colon for instance. I have amended the Java source code to replace all semi-colons with
commas.
2. On the AppBean class, add a check to see whether the current user has the necessary rights
to run a particular report before generating one. The psdi.app.report.ReportService object has
a method called "canRunThisReport()" which can do just that.
If you have any questions or comments, feel free to contact me. You can find my contact information
on my home page.
Tip: If you have problem sending email from Maximo (via SMTP) to hotmail, yahoo or google account for
instance, contact your network guys and ask them to configure your SMTP server allowing your Maximo server to
relay email.