jythonmaximo

Maximo scripting cannot load second MboSet


I've a script with an object launchpoint on INVOICELINE. For the mbo I want to get all INVOICELINES with the same PONUM as the current MBO (since they could be in other then the current mbo's invoice)

In the script I find the PO like so: (to test for status)

from psdi.server import MXServer
from psdi.mbo import Mbo
from psdi.mbo import MboConstants
from psdi.security import UserInfo
from psdi.server import MXServer

myMXServer = MXServer.getMXServer()
userInfo = mbo.getThisMboSet().getUserInfo()

# find the PO
poSet = myMXServer.getMboSet("PO", userInfo)
poSetWhere = "ponum='" + mbo.getString("PONUM") + "' and siteid='" + mbo.getString("POSITEID") + "' and status not in " + poNoUpdate
poSet.setWhere(poSetWhere)

poMbo = poSet.getMbo(0)

which works great.

then later I do the very same for the set of invoicelines:

ilSet = myMXServer.getMboSet("INVOICELINE", userInfo)
ilSetWhere = "ponum='" + mbo.getString("PONUM") + "' and positeid='" + mbo.getString("POSITEID") + "'"
ilSet.setWhere(ilSetWhere)
ilMbo = ilSet.moveFirst()

while ilMbo is not None:
    ...

which results in a error on the setWhere line. Curiously, logging (which I removed for readability) indicates that ilSet contains all invoicelines records after the getMboSet (as expected), the ilSetWhere has a valid query that you can copy-paste in SQL Developer.

Does Maximo need some index or so before it can execute this setWhere?

Here is the logging result for the two setWhere strings:

ponum='4140006682' and siteid='mysite' and status not in ('CLOSED','CAN','GESLTN','ANN')

and

ponum='4140006682' and positeid='mysite'

The error I get is a generic BMXAA7837E java.lang.NullPointerException in script at line... (the line refers to the line with the ilSet.setWhere(ilSetWhere) expression. I'm out of ideas how to fix this and have no clue how to work around it.


Solution

  • Now we have an error to work with!

    Maximo effectively insists that an INVOICELINE set has an "owner", which you have not set up in your code example. Think of an owner as a parent set. Specifically, it is the MBOSet used to fetch the current set off of. It doesn't actually have to be related to the current set, but most of the time it will be (and it makes the most sense to fetch sets that way). An owner can be injected into the set after it's fetched (to change it or trick Maximo), but this is rarely good code.

    Instead of getting a fresh set (no other ties or possible data caching) from the server in its own transaction, you might be best off getting the invoiceline set off of your current MBO. I don't know your exact use case, but generally you want to do something like this instead of getting a new set like you did. At the least, it will give your new set an "owner". You may even want to make the SQL a "relationship" instead of hard-coding it.

    ilSetWhere = "ponum='" + mbo.getString("PONUM") + "' and positeid='" + mbo.getString("POSITEID") + "'"
    ilSet = mbo.getMboSet("$TempInvoiceLineRelationship", "INVOICELINE", ilSetWhere)
    ilMbo = ilSet.moveFirst()
    

    I'm going from memory for this code, so I don't know if it is exactly correct. That form of "getMboSet" takes three parameters. The first is a relationship name. If Maximo finds that relationship name already "registered" from this starting object, it will ignore the next two parameters and use that relationship to get you that set. If it doesn't find that relationship "registered" it registers it for the scope of this code (so you can re-use it later in this code if you wanted). The second parameter defines what destination object to create the temporary relationship to. The third parameter defines the "where clause" of this temporary relationship.


    Original Answer:

    What is the error you are getting?

    Also, you say you log "ilSet" after the "myMXServer.getMboSet..." line? That is going to cause Maximo to run the query and load the objects into the set at that point (it waits to run the query until it has to). As a result of that, you won't see the effects of your where clause change until you "reset()" the set.