Maximo Open Forum

 View Only
  • 1.  Script to Zero YTD hours for Laborers

    Posted 04-13-2021 13:29
    Inspired by an article I came across authored by Chris Winston, I want to create a script that will do the Zero Year-to-Date hours function automatically.

    I created an Escalation to run once a year in the wee hours of the first day of our fiscal year, on the LABOR object, with no SQL condition.

    Created one Escalation Point, with no restrictions on it.  That Point has an Action, which is to run the script I created.

    This is the Jython code:
    from psdi.mbo import MboConstants
    from psdi.mbo import MboSet
    from com.ibm.tivoli.maximo.util.mbo import IterableMboSet
    
    laborSql = " reportedHrs > '0' or ytdOTHrs > '0' or ytdHrsRefused > '0'"
    
    laborSet = mbo.getMboSet("CUSTOMLABORLIST", "LABOR", laborSql)
    
    if (laborSet.count() > 0):
        labor = laborSet.moveFirst()
        while (labor is not None):
            labor.zeroYTD()
            labor = laborSet.moveNext()
    
        laborSet.setFlag(MboConstants.DISCARDABLE, True)
        laborSet.close()
    
    else:
        laborSet.setFlag(MboConstants.DISCARDABLE, True)
        laborSet.close()
    ​


    Here are my questions:
    1) Is the script "right"?  Is that labor.zeroYTD() call done right?  Do I need to put any parameters there (the Javadocs says this method has three parameters)?
    2) Is it better to put the SQL here in the script and run it through a whole mboset, or would it have been better to put the SQL in the Escalation's condition and have the script simply call that zeroYTD() method -- so, like the Escalation is responsible for finding the records instead of the Script?


    Once I get this working, I want to do the same for zeroing Asset costs, Inventory quantities, etc. . .
    #Administration
    #EverythingMaximo

    ------------------------------
    Travis Herron
    Pensacola Christian College
    ------------------------------


  • 2.  RE: Script to Zero YTD hours for Laborers

    Posted 04-14-2021 09:20
    We've automated it a few different ways over the years for customers in our cloud, but our most common design was an escalation on ORGANIZATION that had actions for each (running the asset rollup reports, zeroing inventory YTD, zeroing labor, and zeroing asset costs). If you build the actions appropriately, you can use this to determine which organizations to run it on if you have it. Also make sure you set it to repeat (you don't want it to just work once).

    We typically avoid counts as it's easy enough to iterate and you don't need to know the count. It causes an additional query to execute that might not be needed. We do something like this to loop:

    laborMbo = laborSet.moveFirst()
    while laborMbo:
        laborMbo.zeroYTD(True,True,True)
        laborMbo = laborSet.moveNext() 
    laborSet.save()
    laborSet.close()

    As for your questions
    1) We used laborMbo.zeroYTD(True,True,True). Those 3 parameters are Reported, Overtime, and Refused and we assumed all customers would want all 3 to be zeroed out.
    2) We like the escalation determining which organizations this should run on and then executing for all labor in that organization at once. In our design, we set laborSet.setLogLargFetchResultDisabled(True) because if you have more than 5000 records (or whatever your stop limit is) that would prevent it from retrieving the set. For most organizations, they won't have 5000 labor records so it won't be a big deal but because we wrote it generically I thought I'd call it out.


    As for your future plans, inventory and asset zeroing of asset costs is even more straight forward. The biggest challenge is getting the asset cost rollup report executed and ensuring all costs are rolled up prior to zeroing asset costs.

    Once you're sure asset costs are rolled up (checking the SERVRECTRANS, TOOLTRANS, MATUSETRANS, LABTRANS tables), zeroing the asset costs is easy because it's done at a set level (IE assetSet.zeroCosts(True,False)). First argument is YTD, second argument is TOTALCOST. Obviously for year end activities you don't want to zero the second.

    For inventory, it's also at a set level but there are no arguments. You simply need to call inventorySet.zeroYTDQuantities().

    In all of our automation, we put in additional checks as we had bugs on certain versions that caused escalations to run on the wrong date/time or run more than once. As long as you're on newer versions you probably don't need to worry about this, but it may be something worth tracking somewhere (potentially on the organization record) so you can avoid processing twice.

    ------------------------------
    Steven Shull
    Projetech Inc.
    ------------------------------



  • 3.  RE: Script to Zero YTD hours for Laborers

    Posted 8 hours ago

    So I tried writing a script to zero the Inventory and Labor values, it works but will cause performance issues, is there a way to paginate MBO sets so that a reasonable amount is processed each time? My dev environments have yet to recover from processing 15k inventory records, and i shudder to think what would happen if i run it against all sites.

    # Automation script to zero ytd values for labor, inventory

    from psdi.server import MXServer
    from psdi.util.logging import MXLoggerFactory

    logger = MXLoggerFactory.getLogger("maximo.script")

    logger.info("Start Auto ZeroYTD")

    try:
    # Reset all Labor Reported, Overtime, Refused
        mxe=MXServer.getMXServer()
        laborSet = mxe.getMboSet("LABOR", mxe.getSystemUserInfo())
        laborSet.setLogLargFetchResultDisabled(True)
        laborSet.setWhere( "worksite = 'XXXX'")

        logger.info("Labour Records: " + str(laborSet.count()))

        i = 0
        labor = laborSet.moveFirst()
        while (labor):
            i = i + 1
            if (i % 100 == 0):
                logger.info("Processing: " + labor.getString("LABORCODE"))
                logger.info("Record: " + str(i))
            labor.zeroYTD(True, True, True)
            labor = laborSet.moveNext()

        laborSet.save()
        laborSet.close()

        logger.info("Completed Labor, Starting Inventory")

        inventorySet = mxe.getMboSet("INVENTORY", mxe.getSystemUserInfo())
        inventorySet.setLogLargFetchResultDisabled(True)
        inventorySet.setWhere("SITEID='XXXX'")

        logger.info("Inventory Records: " + str(inventorySet.count()))

        inventorySet.zeroYTDQuantities()
        inventorySet.save()
        inventorySet.close()

        logger.info("Complete Auto ZeroYTD")
    except Exception as error:
        logger.error(str(error))



    ------------------------------
    Jonathan Ma
    IKO Industries
    ------------------------------



  • 4.  RE: Script to Zero YTD hours for Laborers

    Posted 4 hours ago

    The inventory YTD is pretty simple in what it does. It takes the value from issue2yrago and moves it to issue3yrago, issue1yrago to issue2yrago, etc. Unless there are other things in play (like automation scripts, publish channels, etc.) I'd be surprised if you saw a significant impact executing this. Asset rollup (especially during the report era, prior to the changes that 7.6.1.3+ introduce) was exponentially by far the biggest problem with year-end processing. 

    But to answer your question, yes, if you come up with a way to distinguish smaller groups you can certainly do that. For example, you could go storeroom by storeroom if you have enough storerooms to split it up. The challenge is you do not have a great way to identify inventory records that have been processed if you need to split up a storeroom. You can't just look at the issueytd for example to look for a 0 because it's possible that part wasn't issued in a calendar year. You could add another attribute to the inventory records with a date that it was zeroed and set that as you loop through the inventory items yourself but that seems overkill.

    If you wanted to loop through inventory, you do not need to utilize the set method. You can use zeroYTDQuantities on the inventory MBO directly as you loop through. 



    ------------------------------
    Steven Shull
    Naviam
    ------------------------------