Search code examples
coordinatesjythonmaximo

Populate custom X & Y fields in WORKORDER


Updated:

In Maximo 7.6.1.1, I have custom fields in these tables:

  • WORKORDER: X & Y
  • ASSET: X & Y
  • LOCATIONS: X & Y

I would like to populate the X & Y fields in WORKORDER using the logic below.

(The logic is similar--but slightly different--to the logic in the auto-create spatial search.)

At a high level:

  • If exists, use WOSERVICEADDRESS.LATITUDEY & LONGITUDEX
  • Else, use ASSET.X & Y
  • Else, use LOCATIONS.X & Y

Proposed pseudo-code:

Scenario: A user is creating a new work order or editing an existing work order.

When the WO is saved:

01    1.  In the related WOSERVICEADDRESS table:
02
03        if WOSERVICEADDRESS.LATITUDEY gets edited:
04
05            if WOSERVICEADDRESS.LATITUDEY is not null:
06                then update WORKORDER.X & Y with WOSERVICEADDRESS.LATITUDEY & LONGITUDEX
07
08           #Handle the scenario where the WOSERVICEADDRESS.LATITUDEY is changed to null:
09
10            elseif WORKORDER.ASSETNUM is not null:
11                then update WORKORDER.X & Y with the related values in ASSET.X & Y
12
13            elseif WORKORDER.LOCATION is not null:
14                then update WORKORDER.X & Y with the related values in LOCATIONS.X & Y
15    
16    2.  In the WORKORDER table: 
17
18        (if WORKORDER.ASSETNUM gets edited or if WORKORDER.LOCATION gets edited) and if WOSERVICEADDRESS.LATITUDEY is null
19
20        then:
21            if WORKORDER.ASSETNUM is not null:
22            then update WORKORDER.X & Y with the related values in ASSET.X & Y
23
24            elseif WORKORDER.LOCATION is not null:
25            then update WORKORDER.X & Y with the related values in LOCATIONS.X & Y.

Is there a way to do this Jython Automation script (without slowing down the workorder application)?

(Keyword: Maximo Spatial)


Solution

  • Going with the idea that you want the solution pieced together more explicitly from the answer in the other question, the other answer here, the comments from the other answer here, and the updated requirements, I've created an amalgamation of all that. I have not tested this at all, some relationships, event conditions or exact hops through the API may be incorrect. This also assumes that if either the X or Y are filled in at a spot that takes precedence but the other isn't, that you still want to use filled in value and the blank value from that spot.

    Because these are on two different objects, there will be a slight inefficiency handling updates on the service address because that needs to be handled on its own. First, create an automation script launch point on the SERVICEADDRESS object. Set it to run on "add" and "update" and to do those "before save". Add an object event condition of :longitudex != :$old_longitudex or :latitudey != :$old_latitudey. Make that script the following:

    # Assume this change is being made from the UI, so the work order will be the owner of the
    # SERVICEADDRESS object. This way your modifications can be reflected on screen and not cause a
    # refetch error if the user also modified work order in this same transaction.
    wo = mbo.getOwner()
    if wo is not None:
        wo.setValue("X", mbo.getString("LONGITUDEX"))
        wo.setValue("Y", mbo.getString("LATITUDEY"))
    

    This takes care of updating the workorder's fields with the service address fields if they are changed. They will always overwrite what is on the work order so they will take precedent, as your requirements dictate. If someone clears these values and then saves, this would try to clear the values on the work order too, which may not be desired if there actually is an asset or location x and y. You can't really handle that without removing the event condition on the next script, which you don't really want to do if you want to keep it from running as often as you say you do.

    Second, create an automation script launch point on the WORKORDER object. Set it to run on "add" and "update" and to do those "before save". Add an object event condition of :asset != :$old_asset or :location != :$old_location. Make that script the following:

    saddr = mbo.getMboSet("SERVICEADDRESS").getMbo(0)
    if saddr is None or (saddr.getString("LONGITUDEX") == "" and saddr.getString("LATITUDEY") == ""):
        asset = mbo.getMboSet("ASSET")
        location = mbo.getMboSet("LOCATION")
        if asset is not None and (asset.getString("X") != "" or asset.getString("Y") != ""):
            mbo.setValue("X", asset.getString("X"))
            mbo.setValue("Y", asset.getString("Y"))
        else if location is not None and (location.getString("X") != "" or location.getString("Y") != ""):
            mbo.setValue("X", location.getString("X"))
            mbo.setValue("Y", location.getString("Y"))
    

    This script takes care of updating the workorder from the asset or location any time one of those is modified, as long as there isn't an x or y on the serviceaddress. If it turns out neither the asset or location have an x or y on them, it will skip setting the workorder's values, thereby leaving any value already there in place (which should be nothing though, since the serviceaddress wouldn't have had a value either, if it got this far).