Wednesday 24 July 2019

Maximo Scheduled report execution with Automation Script

Scheduled report execution

There are two report execution options that involve scheduling:

•Running a report once in the future (“At this Time” selection)
•Running a report on a recurring basis in the future (“Recurring” selection)

Once a report is scheduled, there are two configuration records that drive report execution:

Report schedule record
The report schedule record is used by the reporting framework to hold the scheduling details for a report
Cron task instance record
The cron task instance record for the REPORTSCHEDULE cron task is used by the Cron Task manager to execute the report on a schedule by placing a job into the report queue. The REPORTSCHEDULE cron task looks up the report schedule record to obtain details of the report execution.

When the selection is “At this Time”, meaning, one time execution, the reporting framework prepares a one-time cron task instance with the REPORTSCHEDULE cron task.

Once the report has been executed, this one-time instance record is removed from the Cron Task instance table.

When the selection is “Recurring”, meaning, multiple execution, the reporting framework prepares a cron task instance with the REPORTSCHEDULE cron task.

This cron task instance remains in the product environment until an administrator deletes the report schedule record using the View Scheduled Reports user interface in Report Administration application.

NOTE: The REPORTSCHEDULE cron task is a read-only cron task. To view it in the Cron Task Setup application, you must set the Access Level field to READONLY and search.
Scripting report execution

Automation scripting in Tpae 7.5 is restricted to the business object framework executing on the application server. Scripting does not support any facet of the user interface framework except posting error and warning messages.

 These latter are also managed from the business object framework.

The immediate execution of a report and the display of the BIRT Report Viewer window is initiated and controlled in the user interface layer of the product and involves URL re-direction and servlet use.

 This capability cannot be scripted. What can be scripted, instead, are the scheduled execution of reports and the sending of report notification to intended recipients. What can also be scripted is the preparation of the report schedule configuration in response to a status change in the business application.

 This article describes how this can be implemented.
For the report execution scenario I want to automate, I will mimic the “At this Time” feature of scheduled report execution.

Design
The low-level design of this script does the following:

Check status change

•Create report schedule record
•Create cron task instance record
•Create cron task parameters (copying parameters from the report’s parameter records)
•Save



Quick Steps to Develop:


  • 1) Create an object launch point , Ex: On WORKORDER object , on Save , update ,after save.
  • 2)Give conditional where clause as :status='COMP' , in this example we want to trigger the reports whenever workorder status changed to COMP.
  • 3)Add the binding variables in the attached excel sheet.
  • 4)Copy the script in the attached file.
  • 5)Save the script and make Launch point and Script active.
  • 6) Test the things by chaniging workorder status to 'COMP'

Excel Data for Binding Variables: 
Variable Variable Type Binding Type Binding Value Override
v_appname IN LITERAL APPNAME  EX: WOTRACK Y
v_emailcomments IN LITERAL Ad Hoc Report has been sent from script. Y
v_emailfiletype IN LITERAL PDF Y
v_emailsubject IN LITERAL Ad Hoc Audit Report testing from script Y
v_emailto IN LITERAL Email ID Y
v_emailtype IN LITERAL attach Y
v_maximourl IN LITERAL  http://hostname:9080/maximo Y
v_paramdelimiter IN LITERAL    || Y
v_paramstring IN LITERAL appHierarchy=appname,objectname  Ex: appHierarchy=WOTRACK,WORKORDER Y
v_reportname IN LITERAL Report Name Ex: test.rptdesign Y
Script is Below: 
Note : At the line number 80 , replace objectname.objectid as   ex: workorder.workorderid

from java.util import Calendar
from java.util import Date
from psdi.app.report import ReportUtil
from psdi.server import MXServer
from psdi.mbo import MboConstants
from psdi.mbo import SqlFormat

c = Calendar.getInstance()
c.add(Calendar.SECOND,60)
d = c.getTime()
thisauditset = mbo.getThisMboSet()
if thisauditset is not None:
 locale = thisauditset.getClientLocale()
 userinfo = thisauditset.getUserInfo()
 schedule = ReportUtil.convertOnceToSchedule(d,locale,c.getTimeZone())
 if schedule is not None:
  reportschedset = MXServer.getMXServer().getMboSet("REPORTSCHED",userinfo)
  if reportschedset is not None:
   reportsched = reportschedset.add()
   reportsched.setValue("REPORTNAME",v_reportname)
   reportsched.setValue("appname",app)
   reportsched.setValue("USERID",userinfo.getUserName()) # To run as current logged in user
   reportsched.setValue("TYPE","once")
   reportsched.setValue("EMAILTYPE",v_emailtype)
   reportsched.setValue("MAXIMOURL",v_maximourl)
   reportsched.setValue("EMAILUSERS",v_emailto)
   reportsched.setValue("EMAILSUBJECT",v_emailsubject)
   reportsched.setValue("EMAILCOMMENTS",v_emailcomments)
   reportsched.setValue("EMAILFILETYPE",v_emailfiletype)
   reportsched.setValue("COUNTRY",locale.getCountry())
   reportsched.setValue("LANGUAGE",locale.getLanguage())
   reportsched.setValue("VARIANT",locale.getVariant())
   reportsched.setValue("TIMEZONE",thisauditset.getClientTimeZone().getID())
   reportsched.setValue("LANGCODE",userinfo.getLangCode())
   print("About to work with REPORTSCHEDULE cron task")
   crontaskdef = reportsched.getMboSet("$parent","crontaskdef","crontaskname='REPORTSCHEDULE'").getMbo(0)
   if crontaskdef is not None:
    crontaskinstset = crontaskdef.getMboSet("CRONTASKINSTANCE")
    if crontaskinstset is not None:
     print("About to work with Cron task instance of REPORTSCHEDULE cron task")
     crontaskinst = crontaskinstset.add(MboConstants.NOACCESSCHECK | MboConstants.NOVALIDATION_AND_NOACTION)
     if crontaskinst is not None:
      d = Date()
      crontaskinstname = str(d.getTime())
      crontaskinst.setValue("CRONTASKNAME","REPORTSCHEDULE",MboConstants.NOACCESSCHECK | MboConstants.NOVALIDATION_AND_NOACTION)
      crontaskinst.setValue("INSTANCENAME",crontaskinstname,MboConstants.NOACCESSCHECK | MboConstants.NOVALIDATION_AND_NOACTION)
      crontaskinst.setValue("SCHEDULE",schedule,MboConstants.NOACCESSCHECK | MboConstants.NOVALIDATION_AND_NOACTION)
      crontaskinst.setValue("ACTIVE",1,MboConstants.NOACCESSCHECK | MboConstants.NOVALIDATION_AND_NOACTION)
      crontaskinst.setValue("RUNASUSERID",userinfo.getUserName(),MboConstants.NOACCESSCHECK | MboConstants.NOVALIDATION_AND_NOACTION)
      crontaskinst.setValue("HASLD",0,MboConstants.NOACCESSCHECK | MboConstants.NOVALIDATION_AND_NOACTION)
      crontaskinst.setValue("AUTOREMOVAL",True,MboConstants.NOACCESSCHECK | MboConstants.NOVALIDATION_AND_NOACTION)
      print("have set all cron task instance values for REPORTSCHEDULE cron task")
      reportsched.setValue("CRONTASKNAME",crontaskinst.getString("CRONTASKNAME"))
      reportsched.setValue("INSTANCENAME",crontaskinst.getString("INSTANCENAME"))
      print("Now going to work with Cron task PARAMETERS")
      cronparamset = crontaskinst.getMboSet("PARAMETER")
      if cronparamset is not None:
       sqf = SqlFormat(cronparamset.getUserInfo(),"reportname=:1")
       sqf.setObject(1,"REPORTPARAM","REPORTNAME",v_reportname)
       reportparamset = MXServer.getMXServer().getMboSet("REPORTPARAM",cronparamset.getUserInfo())
       if reportparamset is not None:
        print("working with REPORTPARAM mbo set")
        reportparamset.setWhere(sqf.format())
        reportparamset.reset()
i=reportparamset.count()
        reportparammbo = None
        for j in range(i):
         reportparam = reportparamset.getMbo(j)
cronparam = cronparamset.add(MboConstants.NOACCESSCHECK | MboConstants.NOVALIDATION_AND_NOACTION)
         if cronparam is not None:
  cronparam.setValue("CRONTASKNAME","REPORTSCHEDULE",MboConstants.NOACCESSCHECK | MboConstants.NOVALIDATION_AND_NOACTION)
          cronparam.setValue("INSTANCENAME",crontaskinstname,MboConstants.NOACCESSCHECK | MboConstants.NOVALIDATION_AND_NOACTION)
  cronparam.setValue("CRONTASKNAME","REPORTSCHEDULE",MboConstants.NOACCESSCHECK | MboConstants.NOVALIDATION_AND_NOACTION)
  paramname = reportparam.getString("PARAMNAME")
          cronparam.setValue("PARAMETER",paramname,MboConstants.NOACCESSCHECK | MboConstants.NOVALIDATION_AND_NOACTION)
  if paramname=="where":
   uniqueidname = mbo.getUniqueIDName()
   uniqueidvalue = mbo.getUniqueIDValue()
   uniquewhere = uniqueidname + "=" + str(uniqueidvalue)
   cronparam.setValue("VALUE","(("+"objectname.objectnameid"+"="+str(uniqueidvalue)+"))",MboConstants.NOACCESSCHECK | MboConstants.NOVALIDATION_AND_NOACTION)
          elif paramname=="paramstring":
           cronparam.setValue("VALUE",v_paramstring,MboConstants.NOACCESSCHECK | MboConstants.NOVALIDATION_AND_NOACTION)
  elif paramname=="paramdelimiter":
   cronparam.setValue("VALUE",v_paramdelimiter,MboConstants.NOACCESSCHECK | MboConstants.NOVALIDATION_AND_NOACTION)
  elif paramname=="appname":
   cronparam.setValue("VALUE",v_appname,MboConstants.NOACCESSCHECK | MboConstants.NOVALIDATION_AND_NOACTION)
  else:
   continue
  reportschedset.save()