Maximo dynamic relationships
The declarative nature of the SQL language is spectacular for more than 90% of information retrieval cases but there are still scenarios to be addressed with the use of an imperative language.
I think that this yet another excellent post "Improved record change tracking using Audit feature" by Bruno Portaluri is a good cue to show therefore the use of dynamic relationships in Maximo. That is the possibility to create relationships that trigger code execution instead of the canonical where-clause based SQL queries. The code should return an MBOSet that is consistent with the target object of the relationship, but with the flexibility to create it with a variety of business logic. So these kinds of relationships are a bit like the moving staircases at Hogwarts: you take them, but you have no idea where they will take you (unless, of course, you are the one who wrote the code).
In the out-of-the-box Maximo (both the good old EAM and the current Manage) there are indeed Java-based examples, identified by the prefix "mbomethod:".
But of course in the latest versions you can also use an automation script (with all the usual advantages and some disadvantages).
For example, we can eliminate the update button suggested in Bruno's blog, because the retrieval of the updated data is implied when MBOSet is fetched. The changes to be made are few and simple.
In the CX_AUDIT relationship, the clause should be changed to "script:CX_AUDIT". The prefix "script:" tells Maximo that the relationship should delegate the creation of the MBOSet to the script that will be specified later.
The CX_AUDIT script must be modified to properly set the implicit variable “mboset” (in lowercase letters, mind you) that will represent the collection of objects returned by the relationship:
from psdi.server import MXServer
#-------------------------------------------------------------------------------
def getAuditAttrs(objname):
attrSet = MXServer.getMXServer().getMboSet("MAXATTRIBUTE", mbo.getUserInfo())
attrSet.setWhere("objectname='" + objname + "' and eauditenabled=1 and persistent=1")
attrSet.setOrderBy("primarykeycolseq, attributeno")
attrList = []
attr = attrSet.moveFirst()
while (attr):
attrList.append([attr.getString("ATTRIBUTENAME"), attr.getString("TITLE")])
attr = attrSet.moveNext()
attrSet.close()
return attrList
#-------------------------------------------------------------------------------
attrList = getAuditAttrs(mbo.getName())
whereClause = "recordid=:" + mbo.getUniqueIDName() + " and objectname='" + mbo.getName() + "'"
aSet = mbo.getMboSet("$Z_AUDIT"+str(mbo.getUniqueIDValue()), "Z_AUDIT", whereClause)
aSet.deleteAll()
aSet.save()
auditSet = mbo.getMboSet("A_" + mbo.getName())
attrValues = {}
for attr in attrList:
attrValues[attr[0]] = ""
audit = auditSet.moveFirst()
while (audit):
# compare values of the current audit record with previous values
for attr in attrList:
attrName = attr[0]
attrTitle = attr[1]
v0 = attrValues.get(attrName)
v1 = audit.getString(attrName)
if v1 != v0 and attrName != "CHANGEBY":
a = aSet.add()
a.setValue("OBJECTNAME", mbo.getName())
a.setValue("RECORDID", mbo.getUniqueIDValue())
a.setValue("ATTRNAME", attrName)
a.setValue("CHANGEDATE", audit.getDate("EAUDITTIMESTAMP"))
a.setValue("CHANGEBY", audit.getString("EAUDITUSERNAME"))
a.setValue("ATTRDESC", attrTitle)
a.setValue("VALUE1", v0)
a.setValue("VALUE2", v1)
attrValues[attrName] = v1
audit = auditSet.moveNext()
aSet.save()
mboset = aSet
As I said, this is just a draft of a possible variation on the original approach, which may give you an interesting hint. The purpose of this short post was to show you the possibilities of using dynamic relationships. So do not take it as gospel, but always evaluate my examples critically and in context. This is even more true for techniques such as dynamic relationships, since there is usually an advanced SQL statement that might do the job better and simpler. Rather, if you know it, please let me know that because there is always something to learn.
Solutions Architect | Asset Mgmt | Payments | CBPR+
3 个月Very interesting post, learned something new!