Introduction

Groovy provides a very easy way to interact with the user via run time prompts, or RTPs.  These can be linked to dimensions, members, and input.  One of the huge benefits of getting RTPs in Groovy is that the result can be validated, and the calculation can be cancelled if they don’t validate (we will touch on this in a future post).

The Solution

This is one of the easier things to do with a Groovy calculation.  There are two things required.  First, the Groovy calculation must prompt the user to select a value.  This is done by doing the following.

/*RTPS: {RTP_Consolidate_Data}*/

At any point in the script after the above, the value can be used.  If it is going to be used multiple times, it might be easier to set a variable.  Regardless of the approach, the value can be referenced using the rtps object as follows.

 String sRTP
 sRTP = rtps.RTP_Consolidate_Data.toString()

That is all that is required!

Conclusion

Beyond the obvious uses of an RTP, I have started using these for a number of other reasons.

  • On global forms where multiple values may be changed throughout a short period of time and execute long running calculations, like allocations, I have seen benefits of prompting a user with a yes/no smartlist RTP.  If the user has more changes, they may not need to execute the calculation after every save.  This gives them the option.
  • If there is a requirement where some prompts are dependent on other prompts, using RTPs in Groovy gives you the flexibility to validate the combination.  For example, if an employee is set to hourly with a VP title, the prompts can be validated and returned to the user as invalid combinations before the prompts are removed from user view.
 
16 replies
  1. Surendra says:

    I have this in my groovy BR.
    String sRTP
    sRTP = rtps.UserSL.toString()

    I have UserSL as Global RTP
    Still I get below error
    No Rtp with the name found.

     
    Reply
    • Kyle Goodfriend says:

      Do you have the following at the top of your rule? It looks like a comment but it is actually embedding the RTP in the rule to be used.
      /*RTPS: {UserSL}*/

       
      Reply
        • Kyle Goodfriend says:

          I had the same issue the first time I used it – it is a little confusing :). Glad I could help. If you have multiple RTPs, just put a space between them, like
          /*RTPS: {RTP1} {RTP2}*/

           
          Reply
  2. Senthil says:

    Hi Kyle,

    Thanks for great blog !
    I am trying to use RTP for smartpush and datamap, somehow I am not getting the Department variables RTP and it’s not recognizing. I am able to get RTP for other dimensions. Do you see any issue with this code

    /*RTPS: {VarDepartment} */
    String sRTP
    sRTP = rtps.VarDepartment.toString()
    operation.application.getDataMap(“CapexToCapexReporting”).execute(“Department”:sRTP, false)

     
    Reply
    • Kyle Goodfriend says:

      I believe you need to reference all the RTPs in one line, so I would expect to see something like this in your example: *RTPS: {VarOtherDim1 VarOtherDim2 VarDepartment} */

       
      Reply
  3. Senthil says:

    Thanks for the reply. I did tried that, but Department RTP variable is not recognizing. Do you see any other issue

    /*RTPS: {varDepartment} {varEntity} {varSite}*/

    String sRTPSEntity
    String sRTPSDepartment
    String sRTPSSite
    sRTPSEntity = rtps.varEntity.toString()
    sRTPSDepartment = rtps.varDepartment.toString()
    sRTPSSite = rtps.varSite.toString()
    operation.application.getDataMap(“FCSTTest”).createSmartPush().execute([“Department”:sRTPSDepartment,”Entity”:sRTPSEntity,”Site”:sRTPSSite])

    Thanks
    Senthil

     
    Reply
  4. Siddharth Gupta says:

    Hi Kyle,

    I was trying to get the Account members of a web form in the form of RTP, where the user can input the data against the account members on the fly. So, “ACC_Closed_Date” is one such account member. How do I show it in the rtp through groovy ?

    I am using the below script –
    /*RTPS: {ACC_Closed_Date}*/

    def ACC_Closed_Date = rtps.ACC_Closed_Date.member

    Can you specify what is the issue in this rule ?
    I am getting error –
    Unable to retrieve variable ACC_Closed_Date deployed in the application

     
    Reply
    • Kyle Goodfriend says:

      Did you create your run time prompt yet? You still have to go in and create the RTP in Planning. The scope of it can be app, db, or rule level.

       
      Reply
  5. Prashant says:

    Hi Kyle,

    Thanks for this post. I can’t describe what a life savior it is.
    If I want to pass level 0 members of a run time prompt of 3 dimensions such as entity, product, region selected by the user to a data map, how can do I so?
    I saw your post of passing the level 0 members of the dimension in a loop. But here there are multiple dimensions and they may be parent members. So I want to pass the level 0 of all of them together in the data map

    Thanks a ton for your help!
    Prashant

     
    Reply
    • Kyle Goodfriend says:

      I am assuming you want a map with 3 elements and the members of each in one map. In that case, it would look something like this
      Map> periodRangeMap = [:]
      here you would loop through your RTPs and the member for each in a loop and inside the loop you would have
      // Create a place in the map for the dimension if it doesn’t exist
      if(periodRangeMap[rtps.rtpXXX.member.dimension.name] == null){periodRangeMap[rtps.rtpXXX.member.dimension.name] = []}
      periodRangeMap[dimName] << memberName I have something that loops through a date range and creates a map for each year with the months in the year for the range Date calcStart = Date.parse("yyyy-MMM-dd", "20${rtps.rtpStartYear.getSmartListEntry().getName().toString().substring(2)}-${rtps.rtpStartMonth.getSmartListEntry().getName().toString()}-05") Date calcEnd = Date.parse("yyyy-MMM-dd", "20${rtps.rtpEndYear.getSmartListEntry().getName().toString().substring(2)}-${rtps.rtpEndMonth.getSmartListEntry().getName().toString()}-05") Map> periodRangeMap = [:]
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(calcEnd);
      calendar.add(Calendar.MONTH, 2)
      Date loopEnd = calendar.getTime()
      while (current.before(loopEnd)) {
      calendar.setTime(current);
      periodRange << [current.format("MMM"),"FY${current.format("YY")}"] if(periodRangeMap["FY${current.format("YY")}".toString()] == null){periodRangeMap["FY${current.format("YY")}".toString()] = []} periodRangeMap["FY${current.format("YY")}".toString()] << current.format("MMM").toString() periodSubmitYears << "FY${current.format("YY")}".toString() periodSubmitPeriods << current.format("MMM").toString() calendar.add(Calendar.MONTH, 1); current = calendar.getTime(); } Hope this helps.

       

      Reply
  6. Dermott Beverley says:

    Hi Kyle, is it possible to pass a value of a string to a hidden RTP when a business rule executes using groovy?

    I am creating dynamic members-on-the-fly for a standard planner and have managed to create a unique member name (to add), using a concatenation of customer (from the POV), date and time. I cannot seem to pass this string to the RTP, to effectively override what the user would normally enter themselves.

    If I could get it to work in this way, then a standard planner can automatically create a member to be used on a form. The issue with using the ‘saveMember’ method is that it is only available to Administrators as a privileged method.

    Thanks
    Dermott

     
    Reply
    • Kyle Goodfriend says:

      Why do you need the RTP if you are dynamically creating the member? As far as adding the member, you can use dynamic children. I don’t like that honestly. What I have done is to have an admin rule run at night (scheduled) that takes all the newly created members and create new members in the outline. So the test member that holds the new member would be used to create the member. In your case, I don’t know if you actually need to create the dynamic member name when the user creates the action since it is build on a POV and date. The rule creates the new member, does the refresh, then runs a rule that moves the data from the TBH member to the created member based on the text value, just like when you created the member.

      Hope that helps.

       
      Reply
      • Dermott Beverley says:

        I had an issue where I was using save.Member method to create the dynamic member. I should have been using the addDynamicChild method/function.

        // Constructs the promotion string details
        String nextPromo = ‘”‘ + “Promo_” + sCustomer + “_” + date.format(‘yyyyMMdd’) + “_” + date.format(‘HHmmss’) + ‘”‘

        // Adds the member to the outline
        Member promotion = DriverMem.addDynamicChild(nextPromo)

        What was so hard to figure out, now looks so easy…

        Thanks for your help 🙂

         
        Reply
  7. Divya Bharathi R says:

    Can I check RTP within an IF loop in Groovy scripting.
    Example : If(RTP == ABC)
    ( Statement1);
    Elseif(RTP == DEF)
    (Statement2);
    Else(RTP == GHI)
    (Statement3);
    ENDIF

     
    Reply

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.