Tuesday, December 8, 2009

Cool Things with Hyperion Planning Custom Buttons

Have you ever wanted to capture the various Hyperion Planning slicer settings information or even capture the connected user?  If so, then hopefully this post can show you the technique to use.  Hyperion Planning has a nifty way to add “Custom Buttons” to any web form.  These buttons can then be attached to an action.


The Hyperion Planning documentation has deployment information for other application servers, but this post will focus on Tomcat.  There is a directory called “custom” and in this directory will be a fill called “ValidateData.js”.  Here is an example of where to find the file:


C:\Hyperion\deployments\Tomcat5\HyperionPlanning\webapps\HyperionPlanning\custom


 


In the file you will find various functions.  You will need to add the code to the functions to draw the buttons and assign actions to the buttons.


 


The first function that needs to be modified is the “drawCustomButtons” and following is an example that can be cut and pasted into your code (note: you need to update the application name and form name in the red font):


 


function drawCustomButtons() {


 if (equalsIgnoreCase(applicationName,"TotPlan"))
 {
  if (equalsIgnoreCase(formName,"Dept Exp"))
  {
   document.writeln('<table cellspacing=2 cellpadding=0 border=0><tr><td>');


            // First row of buttons
   document.writeln('<tr>');
   document.writeln('<td>');


   DrawCmdBtn("actionButton1", "Action 1", null, "submitAction(1)", "This executes Action #1");
   document.writeln('&nbsp;');


   DrawCmdBtn("actionButton2", "Action 2", null, "submitAction(2)", "This executes Action #2");
   document.writeln('&nbsp;');
   DrawCmdBtn("actionButton3", "Action 3", null, "submitAction(3)", "This executes Action #3");
   document.writeln('&nbsp;');
   
   document.writeln('</td>');
   document.writeln('</tr>');
   
   document.writeln('</table>');
  }
  
 }


 if (equalsIgnoreCase(applicationName,"<<SOME OTHER APP NAME>>"))
 {
  if (equalsIgnoreCase(formName,"<<SOME OTHER FORM NAME>>"))
  {
   document.writeln('<table cellspacing=2 cellpadding=0 border=0><tr><td>');


            // First row of buttons
   document.writeln('<tr>');
   document.writeln('<td>');


   DrawCmdBtn("actionButton1", "Action 1", null, "submitAction(1)", "This executes Action #1");
   document.writeln('&nbsp;');


   DrawCmdBtn("actionButton2", "Action 2", null, "submitAction(2)", "This executes Action #2");
   document.writeln('&nbsp;');
   DrawCmdBtn("actionButton3", "Action 3", null, "submitAction(3)", "This executes Action #3");
   document.writeln('&nbsp;');
   
   document.writeln('</td>');
   document.writeln('</tr>');
   
   document.writeln('</table>');
  }
  
 }


Once the buttons are created, we then need to assign an action.  In the above code we are referencing a function called “submitAction(X)”. 


function submitAction(buttonNumber)
{
    // Get User Name
    var userName = getUserName();


    // Get slicer settings
    var slicerParameters = ""
    var SlicerValue;
    var index;
    for (index = 0; index < currentDataGrid.numberPages; index++)
    {
        if (index == 0)
        {
            SlicerValue = document.DataGridSilent.Page_0_0.options[document.DataGridSilent.Page_0_0.selectedIndex].value;
         slicerParameters = slicerParameters + "&param1=" + escape(SlicerValue);
        }
        else if (index == 1)
        {
            SlicerValue = document.DataGridSilent.Page_0_1.options[document.DataGridSilent.Page_0_1.selectedIndex].value;
         slicerParameters = slicerParameters + "&param2=" + escape(SlicerValue);
        }
        else if (index == 2)
        {
            SlicerValue = document.DataGridSilent.Page_0_2.options[document.DataGridSilent.Page_0_2.selectedIndex].value;
         slicerParameters = slicerParameters + "&param3=" + escape(SlicerValue);
        }
        else if (index == 3)
        {
            SlicerValue = document.DataGridSilent.Page_0_3.options[document.DataGridSilent.Page_0_3.selectedIndex].value;
         slicerParameters = slicerParameters + "&param4=" + escape(SlicerValue);
        }
        else if (index == 4)
        {
            SlicerValue = document.DataGridSilent.Page_0_4.options[document.DataGridSilent.Page_0_4.selectedIndex].value;
         slicerParameters = slicerParameters + "&param5=" + escape(SlicerValue);
        }
        else if (index == 5)
        {
            SlicerValue = document.DataGridSilent.Page_0_5.options[document.DataGridSilent.Page_0_5.selectedIndex].value;
         slicerParameters = slicerParameters + "&param6=" + escape(SlicerValue);
        }
        else if (index == 6)
        {
            SlicerValue = document.DataGridSilent.Page_0_6.options[document.DataGridSilent.Page_0_6.selectedIndex].value;
         slicerParameters = slicerParameters + "&param7=" + escape(SlicerValue);
        }
        else if (index == 7)
        {
            SlicerValue = document.DataGridSilent.Page_0_7.options[document.DataGridSilent.Page_0_7.selectedIndex].value;
         slicerParameters = slicerParameters + "&param8=" + escape(SlicerValue);
        }
        else
        {
            alert("Too many slicers. Please update ValidateData.js");
        }
    }

    url = "?user=" + escape(userName) + "&app=" + escape(applicationName) + "&form=" + escape(formName) + "&button=" + buttonName + slicerParameters + "&datetime=" + nowString;
    alert (url);
    //url = ("RequestTest.html");
    openPopupWin(url);
}


There were a few other functions called.  Simply cut and paste the following into the “ValidateData.js” file and you will bring all the pieces together.


function get_cookie ( cookie_name )
{
  var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)' );


  if ( results )
    return ( unescape ( results[2] ) );
  else
    return null;
}


function getUserName()
{
    // Uncomment this to see all cookies in case user name cookie not called "MRUUsername"
    //var cookie_string = document.cookie;
    //alert (cookie_string);


    var userName = get_cookie ( "MRUUsername" );


    if (userName)
    {
        //alert("userName: " + userName);
        return userName;
    }
    else
    {
        //alert("userName not found");
        return "";
    }
}
function openPopupWin (URL)
{
        var height = 300;
        var width = 400;
        var top = (window.screen.availHeight - height)/2;
        var left = (window.screen.availWidth - width)/2;
       
        window.open(URL,"", "height=" + height + ", width=" + width + ", top=" + top + ", left=" + left
        + ",menubar=no,location=no,toolbar=no,status=no,directories=no,scrollbars=yes,resizable=yes",replace="true");
}


In closing, I hope this example can help achieve the customization often required in Hyperion Planning. As this example demonstrates, it easy to pluck off the Hyperion Planning information with a little Java Script and then use the information in other applications such as passing to another application or a scheduler. 


Future posts will integrate this example with Oracle Fusion 11 and Star Finance Command Center whereby the content can be passed and used in a variety of ways.


Lastly, if you are having trouble with any of the code, please feel free to reach out to me.

Friday, December 4, 2009

Automate *ANY* Interface from a Command Line

Given that this is the first post of the blog Autogration, I thought it would be worthwhile to describe an approach that will allow *ANY* interface to be automated and subsequently integrated with a  job stream.  There are a myriad of legacy interfaces that either have no ability to be automated which requires a human to interact with the system or if there is a command line interface, it does not provide the entire feature set required to automate the task at hand.  To over come this, there is the completely free and very light “AutoIt Script” product.   Some highlights include:


* Free download  at: http://www.autoitscript.com/autoit3/
* Very simple Basic like scripting in plain text
* Ability to compile stand-alone EXEs with  full digital signatures


Parameterize the scripts and execute the Windows automations as well as pass in the appropriate parameters to execute the specific reports you want to run.  Here is an example with NOTEPAD.EXE.


SYNTAX: <<script name.exe>>  << # of Params>>  <<Param1>>  <<Param2>>  <<Param3>> <<etc>>


$CmdLine[0] is number of parameters
$CmdLine[1] is param 1 (after the script name)
$CmdLine[2] is param 2 etc


EXAMPLE: RUN_REPORTS_NOW.EXE reports Vermont Cola


Note: AutoIt Scripts can be easily compiled with full digital signatures


Here is an example script:


Run("notepad.exe")
WinWaitActive("Untitled - Notepad")
Send($CmdLine[2])
Send("{ENTER}")
Send("{ENTER}")
Send($CmdLine[3])
WinClose("Untitled - Notepad")
WinWaitActive("Notepad","Do you want to save")
send("!y")
WinWaitActive("Save As")
Send($CmdLine[1] & ".txt")
send("!s")


Here is the result:


Auto_script_example


In summary, the above is fully automatable with only a few lines of code and with the complete ability to run from the command line.  Now I am ready to automate the download and streaming of my own personal BBC podcast off of live updates from my XM Radio which is far superior and relevant news versus what they offer as Podcast or their website.