Maximo

Maximo

Come for answers, stay for best practices. All we're missing is you.

 View Only
  • 1.  Start/stop timer for tasks (WOTRACK and Quick Reporting)

    Posted Tue October 26, 2021 10:35 AM
    Edited by System Admin Wed March 22, 2023 11:50 AM
    MAM 7.6.1.2:

    What are the options for creating a start/stop timer for tasks in WOTRACK and Quick Reporting?

    I'm aware that task timer functionality exists in the Activities and Tasks application. But, my Organization wanted this functionality in the WOTRACK and Quick Reporting applications, since our business is centered around those two applications.

    Related info in the comments of this post.
    RFE: Start/Stop timer for tasks
    TS007343687 - Use start/stop timer for tasks: BMXAA2554E - Timer not started.
    Tech Note: Stop Timer in Work Order prompts "Timer Not Started"



    Screenshots of what we were looking for:




    #AssetandFacilitiesManagement
    #Maximo


  • 2.  RE: Start/stop timer for tasks (WOTRACK and Quick Reporting)

    Posted Tue October 26, 2021 10:37 AM
    Edited by System Admin Wed March 22, 2023 11:43 AM
    I thought I'd give back to the community by sharing the tool that we use for this. The team that we worked with built a custom Java tool…it seems to work well enough. If anyone needs to build something similar, this might be helpful...

    (There are probably a few different ways this could have been solved. The team we worked with chose Java. I wasn't involved, so I couldn't say if that was the best/easiest approach or not.)



    I don't know anything about Java customizations. So there could be key information missing here.

    cust.webclient.beans.workorder.CGQuickRepAppBean
    
    import createch.webclient.beans.workorder.CGQuickRepAppBean;
    import java.rmi.RemoteException;
    import psdi.app.labor.LabTransSet;
    import psdi.app.labor.LaborRemote;
    import psdi.app.signature.SignatureServiceRemote;
    import psdi.app.workorder.WORemote;
    import psdi.mbo.MboRemote;
    import psdi.mbo.MboSetRemote;
    import psdi.security.UserInfo;
    import psdi.server.MXServer;
    import psdi.util.MXApplicationException;
    import psdi.util.MXException;
    import psdi.webclient.beans.workorder.QuickRepAppBean;
    import psdi.webclient.system.beans.DataBean;
    import psdi.webclient.system.controller.Utility;
    
    public class CGQuickRepAppBean extends QuickRepAppBean {
      public static WORemote woRemote = null;
      
      public int STARTTIMER() throws MXException, RemoteException {
        DataBean appBean = Utility.getDataSource(this.sessionContext, this.app.getAppHandler());
        woRemote = (WORemote)this.app.getAppBean().getMbo(0);
        LabTransSet labTransSet = null;
        String laborOrg = null;
        String laborCode = null;
        UserInfo userinfo = woRemote.getUserInfo();
        laborOrg = woRemote.getString("orgid");
        SignatureServiceRemote sigService = (SignatureServiceRemote)MXServer.getMXServer().lookup("SIGNATURE");
        LaborRemote laborRemote = sigService.getLaborForUserAndOrg(userinfo.getUserName(), laborOrg, userinfo);
        if (laborRemote != null)
          laborCode = laborRemote.getString("laborcode"); 
        MboSetRemote woMboSet = woRemote.getMboSet("CHILDTASK");
        if (!woMboSet.isEmpty()) {
          MboRemote mbo = null;
          int i = 0;
          while ((mbo = woMboSet.getMbo(i)) != null) {
            labTransSet = (LabTransSet)mbo.getMboSet("LABTRANS");
            labTransSet.setWhere("timerstatus='ACTIVE' and laborcode='" + laborCode + "'");
            labTransSet.reset();
            if (!labTransSet.isEmpty())
              throw new MXApplicationException("labor", "TimerAlreadyStarted"); 
            i++;
          } 
        } 
        return super.STARTTIMER();
      }
    }
    ​

    cust.webclient.beans.workorder.CGQuickRepTasksBean​
    
    import createch.webclient.beans.workorder.CGQuickRepTasksBean;
    import java.rmi.RemoteException;
    import psdi.app.labor.LabTransSet;
    import psdi.app.labor.LaborRemote;
    import psdi.app.signature.SignatureServiceRemote;
    import psdi.app.workorder.WORemote;
    import psdi.mbo.MboRemote;
    import psdi.mbo.MboSetRemote;
    import psdi.security.UserInfo;
    import psdi.server.MXServer;
    import psdi.util.MXApplicationException;
    import psdi.util.MXException;
    import psdi.webclient.beans.workorder.QuickRepTasksBean;
    import psdi.webclient.system.beans.DataBean;
    import psdi.webclient.system.controller.RequestHandler;
    import psdi.webclient.system.controller.Utility;
    import psdi.webclient.system.controller.WebClientEvent;
    
    public class CGQuickRepTasksBean extends QuickRepTasksBean {
      public static WORemote woRemote = null;
      
      public int STARTTIMER() throws MXException, RemoteException {
        DataBean appBean = Utility.getDataSource(this.sessionContext, this.app.getAppHandler());
        woRemote = (WORemote)this.app.getAppBean().getMbo(0);
        LabTransSet labTransSet = null;
        String laborOrg = null;
        String laborCode = null;
        UserInfo userinfo = woRemote.getUserInfo();
        laborOrg = woRemote.getString("orgid");
        SignatureServiceRemote sigService = (SignatureServiceRemote)MXServer.getMXServer().lookup("SIGNATURE");
        LaborRemote laborRemote = sigService.getLaborForUserAndOrg(userinfo.getUserName(), laborOrg, userinfo);
        if (laborRemote != null)
          laborCode = laborRemote.getString("laborcode"); 
        MboSetRemote woMboSet = woRemote.getMboSet("CHILDTASK");
        if (!woMboSet.isEmpty()) {
          MboRemote mbo = null;
          int i = 0;
          while ((mbo = woMboSet.getMbo(i)) != null) {
            labTransSet = (LabTransSet)mbo.getMboSet("LABTRANS");
            labTransSet.setWhere("timerstatus='ACTIVE' and laborcode='" + laborCode + "'");
            labTransSet.reset();
            if (!labTransSet.isEmpty())
              throw new MXApplicationException("labor", "TimerAlreadyStarted"); 
            i++;
          } 
          labTransSet = (LabTransSet)woRemote.getMboSet("LABTRANS");
          labTransSet.setWhere("timerstatus='ACTIVE' and laborcode='" + laborCode + "'");
          labTransSet.reset();
          if (!labTransSet.isEmpty())
            throw new MXApplicationException("labor", "TimerAlreadyStarted"); 
        } 
        WebClientEvent event = this.sessionContext.getCurrentEvent();
        int row = getRowIndexFromEvent(event);
        woRemote = (WORemote)woRemote.getMboSet("CHILDREN").getMbo(row);
        try {
          if (this.app.isMobile())
            woRemote.setFromMobile(true); 
          woRemote.startTimer();
          appBean.save();
        } catch (MXException mxe) {
          Utility.showMessageBox(this.sessionContext.getCurrentEvent(), mxe);
          structureChangedEvent((DataBean)this);
          dataChangedEvent((DataBean)this);
        } 
        this.sessionContext.queueRefreshEvent();
        return 1;
      }
      
      public int STOPTIMER() throws MXException, RemoteException {
        DataBean appBean = Utility.getDataSource(this.sessionContext, this.app.getAppHandler());
        try {
          woRemote = (WORemote)this.app.getAppBean().getMbo(0);
          WebClientEvent event = this.sessionContext.getCurrentEvent();
          int row = getRowIndexFromEvent(event);
          woRemote = (WORemote)woRemote.getMboSet("CHILDREN").getMbo(row);
          MboRemote labtrans = woRemote.stopTimer(null, false);
          if (woRemote.needPopupOnStopTimer()) {
            RequestHandler.showDialog(this.sessionContext, "confirmlabtrans");
            return 1;
          } 
          woRemote.stopTimer();
          appBean.save();
        } catch (MXException mxe) {
          Utility.showMessageBox(this.sessionContext.getCurrentEvent(), mxe);
        } 
        this.sessionContext.queueRefreshEvent();
        return 1;
      }
    }
    

    cust.webclient.beans.workorder.CGWOTasksBean
    
    import createch.webclient.beans.workorder.CGWOTasksBean;
    import java.rmi.RemoteException;
    import psdi.app.labor.LabTransSet;
    import psdi.app.labor.LaborRemote;
    import psdi.app.signature.SignatureServiceRemote;
    import psdi.app.workorder.WORemote;
    import psdi.mbo.MboRemote;
    import psdi.mbo.MboSetRemote;
    import psdi.security.UserInfo;
    import psdi.server.MXServer;
    import psdi.util.MXApplicationException;
    import psdi.util.MXException;
    import psdi.webclient.beans.workorder.WOTasksBean;
    import psdi.webclient.system.beans.DataBean;
    import psdi.webclient.system.controller.RequestHandler;
    import psdi.webclient.system.controller.Utility;
    import psdi.webclient.system.controller.WebClientEvent;
    
    public class CGWOTasksBean extends WOTasksBean {
      public static WORemote woRemote = null;
      
      public int STARTTIMER() throws MXException, RemoteException {
        DataBean appBean = Utility.getDataSource(this.sessionContext, this.app.getAppHandler());
        woRemote = (WORemote)this.app.getAppBean().getMbo(0);
        LabTransSet labTransSet = null;
        String laborOrg = null;
        String laborCode = null;
        UserInfo userinfo = woRemote.getUserInfo();
        laborOrg = woRemote.getString("orgid");
        SignatureServiceRemote sigService = (SignatureServiceRemote)MXServer.getMXServer().lookup("SIGNATURE");
        LaborRemote laborRemote = sigService.getLaborForUserAndOrg(userinfo.getUserName(), laborOrg, userinfo);
        if (laborRemote != null)
          laborCode = laborRemote.getString("laborcode"); 
        MboSetRemote woMboSet = woRemote.getMboSet("CHILDTASK");
        if (!woMboSet.isEmpty()) {
          MboRemote mbo = null;
          int i = 0;
          while ((mbo = woMboSet.getMbo(i)) != null) {
            labTransSet = (LabTransSet)mbo.getMboSet("LABTRANS");
            labTransSet.setWhere("timerstatus='ACTIVE' and laborcode='" + laborCode + "'");
            labTransSet.reset();
            if (!labTransSet.isEmpty())
              throw new MXApplicationException("labor", "TimerAlreadyStarted"); 
            i++;
          } 
          labTransSet = (LabTransSet)woRemote.getMboSet("LABTRANS");
          labTransSet.setWhere("timerstatus='ACTIVE' and laborcode='" + laborCode + "'");
          labTransSet.reset();
          if (!labTransSet.isEmpty())
            throw new MXApplicationException("labor", "TimerAlreadyStarted"); 
        } 
        WebClientEvent event = this.sessionContext.getCurrentEvent();
        int row = getRowIndexFromEvent(event);
        woRemote = (WORemote)woRemote.getMboSet("CHILDREN").getMbo(row);
        try {
          if (this.app.isMobile())
            woRemote.setFromMobile(true); 
          woRemote.startTimer();
          appBean.save();
        } catch (MXException mxe) {
          Utility.showMessageBox(this.sessionContext.getCurrentEvent(), mxe);
          structureChangedEvent((DataBean)this);
          dataChangedEvent((DataBean)this);
        } 
        this.sessionContext.queueRefreshEvent();
        return 1;
      }
      
      public int STOPTIMER() throws MXException, RemoteException {
        DataBean appBean = Utility.getDataSource(this.sessionContext, this.app.getAppHandler());
        try {
          woRemote = (WORemote)this.app.getAppBean().getMbo(0);
          WebClientEvent event = this.sessionContext.getCurrentEvent();
          int row = getRowIndexFromEvent(event);
          woRemote = (WORemote)woRemote.getMboSet("CHILDREN").getMbo(row);
          MboRemote labtrans = woRemote.stopTimer(null, false);
          if (woRemote.needPopupOnStopTimer()) {
            RequestHandler.showDialog(this.sessionContext, "confirmlabtrans");
            return 1;
          } 
          woRemote.stopTimer();
          appBean.save();
        } catch (MXException mxe) {
          Utility.showMessageBox(this.sessionContext.getCurrentEvent(), mxe);
        } 
        this.sessionContext.queueRefreshEvent();
        return 1;
      }
    }
    


    cust.webclient.beans.workorder.CGWorkorderAppBean
    
    import createch.webclient.beans.workorder.CGWorkorderAppBean;
    import java.rmi.RemoteException;
    import psdi.app.labor.LabTransSet;
    import psdi.app.labor.LaborRemote;
    import psdi.app.signature.SignatureServiceRemote;
    import psdi.app.workorder.WORemote;
    import psdi.mbo.MboRemote;
    import psdi.mbo.MboSetRemote;
    import psdi.security.UserInfo;
    import psdi.server.MXServer;
    import psdi.util.MXApplicationException;
    import psdi.util.MXException;
    import psdi.webclient.beans.workorder.WorkorderAppBean;
    import psdi.webclient.system.beans.DataBean;
    import psdi.webclient.system.controller.Utility;
    
    public class CGWorkorderAppBean extends WorkorderAppBean {
      public static WORemote woRemote = null;
      
      public int STARTTIMER() throws MXException, RemoteException {
        DataBean appBean = Utility.getDataSource(this.sessionContext, this.app.getAppHandler());
        woRemote = (WORemote)this.app.getAppBean().getMbo(0);
        LabTransSet labTransSet = null;
        String laborOrg = null;
        String laborCode = null;
        UserInfo userinfo = woRemote.getUserInfo();
        laborOrg = woRemote.getString("orgid");
        SignatureServiceRemote sigService = (SignatureServiceRemote)MXServer.getMXServer().lookup("SIGNATURE");
        LaborRemote laborRemote = sigService.getLaborForUserAndOrg(userinfo.getUserName(), laborOrg, userinfo);
        if (laborRemote != null)
          laborCode = laborRemote.getString("laborcode"); 
        MboSetRemote woMboSet = woRemote.getMboSet("CHILDTASK");
        if (!woMboSet.isEmpty()) {
          MboRemote mbo = null;
          int i = 0;
          while ((mbo = woMboSet.getMbo(i)) != null) {
            labTransSet = (LabTransSet)mbo.getMboSet("LABTRANS");
            labTransSet.setWhere("timerstatus='ACTIVE' and laborcode='" + laborCode + "'");
            labTransSet.reset();
            if (!labTransSet.isEmpty())
              throw new MXApplicationException("labor", "TimerAlreadyStarted"); 
            i++;
          } 
        } 
        return super.STARTTIMER();
      }
    }
    ​

    #Maximo
    #AssetandFacilitiesManagement


  • 3.  RE: Start/stop timer for tasks (WOTRACK and Quick Reporting)

    Posted Tue October 26, 2021 10:54 AM
    Edited by System Admin Wed March 22, 2023 11:49 AM

    Note:

    The custom Java task timer tool does the following:
    The actual labor transaction (internal/inside labor) that is created by the tool is unapproved by default, even when the "Automatically Approve Inside Labor Transactions" setting is enabled (in the Organizations application).

    The labor actual only becomes approved once the end time is entered.
    Actual labors are unapproved, even though "Automatically Approve Inside Labor Transactions" is enabled


    But someone mentioned in another post that it’s probably expected behaviour. The Activities and Tasks application works the same way. The labor actual needs to be unapproved (editable) because we’re not finished editing it yet (doesn’t have an end time). Once we enter and end time with via the timer, the labor actual becomes approved (read-only). Working as expected.


    #Maximo
    #AssetandFacilitiesManagement


  • 4.  RE: Start/stop timer for tasks (WOTRACK and Quick Reporting)

    Posted Wed October 27, 2021 10:38 PM
    For us the easier route was to add a signature option. Then add the options to the Toolbar Menu and setting the proper images.

    With that we were able to get the same functionality as the Activities and Tasks app. It almost seems too easy. I don't think there was anything else. I'll look through some notes and post if I find anything that I'm forgetting.



    ------------------------------
    John Rice
    ------------------------------



  • 5.  RE: Start/stop timer for tasks (WOTRACK and Quick Reporting)

    Posted Thu October 28, 2021 05:42 AM
    Would be interested to hear if it works for tasks in the actuals tab of a main WO in WOTRACK. I couldn't get that working.

    I think that's why my organization must have gone the customization route. I wasn't involved.


  • 6.  RE: Start/stop timer for tasks (WOTRACK and Quick Reporting)

    Posted Wed November 10, 2021 03:20 PM
    The folks we did this for were only interested in tracking time a the work order level and not at the task level. I'll apply this to another environment and see if it works for tasks as well. I don't remember if there is a task entry on that dialog.

    ------------------------------
    John Rice
    ------------------------------