0

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.

Jeroen
  • 1,638
  • 3
  • 23
  • 48

1 Answers1

2

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.

Dex
  • 1,241
  • 6
  • 13
  • I just get a NullPointerException error on the setWhere line. (BMXAA7837E). This makes no sense to me, since the set is correct and so is the where clause. – Jeroen Feb 27 '15 at 14:26
  • There is a lot more information in the question now, with a more clear idea of what is going wrong. This answer isn't relevant anymore. – Dex Feb 28 '15 at 16:07
  • However, I can't comment on the question itself yet, so I will comment here. According to what you have posted, the only way to get a null pointer on that line is for "ilSet" to be null. You don't show it here, but you say you log the set. Depending on what you are logging, you should get a null pointer at that code instead. I'm thinking either there is more at the error line than we see, or the line number being reported isn't fully correct (as in, it may include overhead lines that Maximo is adding to the script before it runs; I can't recall anymore if that is a real problem). – Dex Feb 28 '15 at 16:12
  • I'm still puzzeled by all this. I'm very positive that my ilSetWhereis correct (it's similar and based on the same parameters used for the other objects) The null pointer exception stack trace points to psdi.app.invoice.InvoiceLine.init(InvoiceLine.java:270) which is in the init-function: MboRemote invoice = getOwner(); 270: if ((invoice.isBasedOn("INVOICE")) && (!invoice.toBeAdded())) { if (((InvoiceRemote)invoice).isConsignmentInvoice()) { setReadOnlyForConsInvoice(); } } Is it possible the code can't retrieve the owner this way? – Jeroen Mar 02 '15 at 14:01
  • Ah ah. That is key information. Correct. According to that code (which looks familiar; I think I've been across this before), Maximo effectively insists that an INVOICELINE set have an owner and you don't have one. I'm modifying my answer. – Dex Mar 04 '15 at 01:54