Sunday, March 10, 2024

Set Label Names Dynamically in Maximo

Set Label Names dynamically in Maximo fields, section/section header or table column/header.

A few scenarios like displaying costs for decommissioned/not ready assets, Hazards and Precautions information for Work Order and Date table column in Assignment Manager application requires labels to have dynamic values to make relevance for current record.

Dynamic Label Names can be set in following places:
  • Field Name based on a sigoption condition by a property label
  • Section or Section Header Name using parameter values
  • Table column label using "Label Source ID" and "Label Attributes"
Field Name change by label property using sigoption condition

In WO application, we have configured "WOPRIORITY" field name based on the work type value condition. If it is PM based WO, then set the label as "PM Priority" else "WO Priority". 



Section Header or Table Control Name using parameter values
We can set a section header with a dynamic label using parameter value properties.

Parameter Values Control  <paramvalues> - contains a list of parameter values with positions that can be replaced with values in label of Section Header

Parameter Value <paramvalue> control defines the datasrc and dataattribute with position for label property. 

datasrc - you can set any datasource that is different than parent control i.e., table or section. If you don't set any datasource, then it inherits the parent's data source. If parent dont have a data source or parent is application, then primary data source of the application MAINRECORD will be taken

dataattribute - based on the datasource we can use an attribute name or any related record. 

position - the number in position will replace the label text in the sectionheader




Table Column - Label Source ID and Label Attributes:

We can dynamically set value for a table column using label source ID and Label attribute tags in table column properties. 

In Assignment Manager application (WORKMAN.xml), Maximo has defined a datasource on CALENDARVIEW mbo which is used for referencing the label source ID and label attributes. 

<datasrc id="AMcalendarview" mboname="calendarview"/>

<tablecol 
classname="rowbg_gray" dataattribute="labor.day1" filterable="false"  id="select_labor_col_7" label="{0}" labelattributes="day1" labelsrcid="AMcalendarview"    mxevent="assignlabgrid" sortable="false" targetid="select_labor_col_7" type="event"/>





References:

Wednesday, February 14, 2024

Maximo Average Calculation Methods for Continuous Meter readings

Continuous Meters for Locations or Assets will have an Average Calculation Method specified for calculating the Average Units per day value. Gauge and Characteristic type meters do not have Average calculation method.

Continuous Meters are used to measure consumption or cumulative values. These meters record items like mileage, hours worked, fuel usage or number of items produced. Reading type can be Actual (cumulative) or Delta (incremental). New reading value must be greater than or equal to last reading. 

Maximo calculates the daily Average based on the meter readings and average calculation method, There are four types of Average Calculation Methods available: ALL, SLIDING-DAYS,SLIDING-READINGS,STATIC.

ALL 
Daily Average is calculated based on all meter readings recorded so far for the meter

Average = (Sum of all delta readings  -  Delta reading of earliest date)  /

                           ( Last reading date – Earliest reading date)

Let us find the Average for ALL calculation type:

Current Date Time - 10-Feb-2024 18:00:00 

Average Units per day 
= Sum of all delta readings  -  Delta reading of Earliest Date (31-Jan-2024)   /
   Last reading date(10-Feb-2024 7:00:07) - Earliest Meter reading date(31-Jan-2024 7:00:07)
= (80+70+50+65+60+70+55+75+65+70+80)  - 80  / 10
= 660 / 10 = 66  

SLIDING-DAYS 
Daily Average is calculated based on last N days of meter readings. 
N - SLIDING Window Size

It's used for scenarios where the complete set of odometer readings doesn't make any relevance than taking the last 180/365 days of readings to know the exact overhaul or maintenance requirement.

Average = 

(Sum of all delta readings for Sliding days range - Delta reading of earliest date)  /

( Last reading Date – Earliest reading date from meter readings Set )

Let us find the Average for 10 Sliding Days:



Current Date Time - 10-Feb-2024 18:00:00 
Sliding Date Range starts from = Current Date Time - 10 Days = 31-Jan-202418:00
Meter Readings Range starts from values greater than 31-Jan-2024 18:00  
Earliest Meter Reading Date = 01-Feb-2021 7:00:07 ( from image list )

Average Units per day 
= Sum of all delta readings from 01-Feb-2024 to 10-Feb-2024  -  Delta reading of Earliest Date (01-Feb-2024)   /
   Last reading date (10-Feb-2024 7:00:07) - Earliest Meter reading date (1-Feb-2024 7:00:07)
= (80+70+50+65+60+70+55+75+65+70)  - 70  / 9
= 590 / 9 = 65.55  

SLIDING-READINGS 
Daily Average is calculated based on last N number of meter readings. 
N - SLIDING Window Size

Average = 

Sum of all delta readings for N sliding readings - Delta reading of earliest date  /

 ( Last reading Date – Earliest reading date from meter readings Set )

Let us find the Average for 5 Sliding readings.


Average Units per day 
Sum of all readings from 06-Feb-2024 to 10-Feb-2024  -  Reading of Earliest Date (06-Feb-2024)   /
Last reading date (10-Feb-2024 7:00:07) - Earliest Meter reading date (6-Feb-2024 7:00:07)
= (80+70+50+65+60)  - 60  / 5
= 265 / 5 = 53

STATIC
User need to manually enter a static value for Average Units/day field

References:

Friday, January 19, 2024

Outbound Object Structure Integration Customization Functions in Automation Script

Maximo Integration Framework supports customization of Object Structure in Java, Automation Script or both at the same time.

Object Structure processing can be Outbound or Inbound:
  • Outbound Object Structure custom processing can be performed during the serialization of Maximo business object (MBO) data into a json or XML message
  • Inbound Object Structure custom processing will happen in inbound json or XML message before it is mapped to MBO business object data
What ? Outbound Object Structure processing functions using Automation Script

Why? Java Customizations for Integration processing needs an outage for deployment. Using Automation Script is more like a configuration and doesn't need any deployment or restart for a change.

Conditional Skipping (or excluding) columns and Overriding field values from other MBOs can't be achieved using processing rule configuration. 

How to Implement ? Create an Outbound Object Structure processing script by selecting Create Integration Scripts from the Automation Scripting application. Choose any Object structure name - MXPR and select Outbound Definition check box.
 
Maximo will create a script with name OSOUT.<ObjectStructureName> and call the methods while processing Object Structure outbound operation.

                            

 


from psdi.util import HTML

def overrideValues (ctx):
    if ctx.getMboName() == "PR" or ctx.getMboName() == "PRLINE":
        # remove html tags from pr and prline description
        ctx.overrideCol("DESCRIPTION_LONGDESCRIPTION", 
			HTML.toPlainText(ctx.getMbo().getString("DESCRIPTION_LONGDESCRIPTION")))
		
def skipCols(ctx):
  if ctx.getMboName()=='PRLINE':
    # remove extra fields from outbound message to reduce payload size
    ctx.skipCol(['RL1','RL2','RL3','RL4'])
	
def skipMbo(ctx):
  if ctx.getMboName()=='PR':
    if ctx.getMbo().getMboSet("PRLINE").isEmpty():
      ctx.skipTxn()
  elif ctx.getMboName()=='PR':
    # skip MBOs that are COMP or in history status
    if ctx.getMbo().getInternalStatus() == "COMP" or ctx.getMbo().getBoolean("HISTORYFLAG") :
      ctx.skipMbo()  

References: 

Thursday, December 21, 2023

Maximo Filter data using LOOKUPS whereclause tag

What ? Apply filter/whereclause on lookup values 

Why ? Easier to apply a condition on a list of values without a table domain
Some Maximo fields like WORKORDER.WORKTYPE have a field level class and adding a table domain would add more complexity for applying a list where condition. Instead a custom lookups.xml configuration in application designer is simple approach to achieve it.

How ?  Sample use case: Display items in Work Order plans tab that are in ACTIVE status or PENDOBS (Pending Obsolesce)  status having current balance greater than zero.

Follow the below steps to filter values from a lookup
  • Export the LOOKUPS.xml from Application Designer
  • Open the xml file and add/modify new table section
  • Add whereclause attribute on the table tag
<table id="activeitem" inputmode="readonly" selectmode="single" 
whereclause="status='ACTIVE' or (status='PENDOBS' and exists (select 1 from inventory a, invbalances b 
       where a.itemnum = item.itemnum and a.itemsetid = item.itemsetid and a.itemsetid = b.itemsetid and a.location = b.location 
   and a.itemnum = b.itemnum and a.siteid = b.siteid and b.curbal &gt; 0 and a.status in ( 'ACTIVE', 'PENDOBS')))">

  • We can't use greater than and lesser than symbol directly in the lookup.xml, so replace them with equivalent characters.
         greater than  (>) -->  &gt;      lesser than (<) -->  &lt;
  • Condition in whereclause runs from Item table, so use item.itemnum inside the subquery
  • Import the LOOKUPS.xml

  • Link the custom lookup "activeitem" to the WOTRACK.xml application on the ITEM field under the Planned Materials section 

References :  limiting-lookups-using-whereclause

Saturday, November 25, 2023

Maximo server host name for hyperlink in BIRT report

What?  get the server hostname of the environment where the BIRT report is running.

Why? In a few scenarios, we need to form a URL in hyperlink property to point it to Maximo record or any other integrated application specific to environment.

Maximo BIRT framework don’t support implicit variable :HOSTNAME. This variable is handy on getting the server host name inside Maximo applications like communication template.

How? In order to achieve it inside BIRT, we need to run the sql query in MAXPROPVALUE table from the system property mxe.hostname on the beforeOpen method of the dataSet; it can also be from any instance or custom system property.



Store the hostname in a Global variable - hostname to use them inside the report.



Use the variable in a cell hyperlink property to point to specific Maximo host name

"https://" + reportContext.getPersistentGlobalVariable ("hostname") + "/maximo/ui/login?event=loadapp&amp;value=asset&amp;additionalevent=sqlwhere"
+"&amp;additionaleventvalue=assetid = (select assetid from asset where siteid = '"+row["siteid"]+"' and assetnum = '"+row["assetnum"]+"')"




Courtesy: Madhavan

Tuesday, October 24, 2023

Maximo MBO Change Status Based on Other MBO Conditions using Automation script

Change Status of MBO (PO or WORKORDER) based on other MBO Conditions using Automation Script Action Launch Point.

Why we need an Automation Script for changeStatus Action ? 
If the change status of a MBO (WORKORDER or PO) is a straightforward one like close WO after status Completion or close PO after receipts field value = COMPLETE, we can use an Action record of type "Change Status".
 
In real business scenarios, we need to changeStatus of a MBO based on conditions involving other MBOs, for example, complete a PO if its POLINES are invoiced and acknowledged by an external system or move an Inventory record to OBSOLETE if it's in PENDOBS status for 3 months without any current balance in INVBALANCES.

To build such complex requirements, we need to use an Action Launch point Automation script.

Maximo Configurations and Script
Create an Action launch point automation script with Object = PO. 

Don't call MboSet.save method inside the action as the changeStatus method will take care of it.


Maximo creates an Action record when we create an Action launch point script and populates its parameters [Script Name, Launch Point Name, Action Name]. 


Create an escalation to get the records against which the action need to be executed; Here, we have taken Approved PO with competed receipts 

Friday, September 22, 2023

Invoke Direct Print of Maximo BIRT Report using Automation Script

Auto-Initiate Maximo BIRT Direct Print Function from an Automation Script.

Why we need this option ? 
We need this feature to print records automatically on event trigger or user action, for example, a scenario of printing item or PO report on receiving items.
 
Please find the steps on how to implement it: 
  • Create a custom field "Is Print" on non persistent object RECEIPTINPUT
  • Use this field to select the records for printing on the "Select Ordered Items" dialog

  • Create a script with attribute launch point on this "Is Print ?" field validation class code receiptinput.isprint.val.py .ITEMNUM field from RECEIPTINPUT object will be collected and stored in a field in PO object.

  • Create 2 attributes PRINTLIST and NPPRINTLIST (non persistent) in PO object to store the list of items selected to be printed
  • On "Before Save" of PO object, copy the values from NPPRINTLIST to PRINTLIST on an automation script of launch point PO with event as before save
  • On "After save" event of PO object, trigger direct print of a report based on the values selected on the "Select Ordered Items" dialog code po.directprint.obj.as.py