Enhancing an OpenInsight report for use with O4W

If you've got an existing OI report that generates OIPI/OIPI.Net output, there are a few options for how you might make this same output available via the browser to O4W users.

If the existing report is basically data-driven (for example, if the output could be effectively generated via R/List), there are some easy options.  One choice is to recreate the report using the O4W Report Wizard.  This will allow you to create a "collector" window (for any prompts) and then specify which fields you wish to display, and allows you to include any R/List style modifiers (total, break-on, etc.).  Since this report is designed for web output, it is fully interactive, and allows the user to download the results.  The second choice is to create a Banded Report Writer (BRW) report, which can then be called from the browser to generate PDF outputs.

If neither of these "easy options" is appropriate – for example, the output cannot be easily represented as an R/List report – then modifications to the basic+ code are necessary. These break down into two pieces: 1. Prompting for data required to run the report, and 2. Generating output for display in the browser.

For step 1, you can write an O4W custom stored procedure to prompt the user for required information (such as starting and ending dates for the report, customer names, etc.).  This custom stored procedure can be as simple, or as elaborate, as you wish.  For example, a very rudimentary example might be as follows:

SUBROUTINE O4W_CUSTOMER_REPORT(ctlentid, event, request)
$INSERT O4WCOMMON
$INSERT O4WEQUATES

BEGIN CASE
    CASE EVENT _EQC "CREATE"
        O4WForm()
        O4WTableStart("promptTable")
        O4WText("Enter starting date: ")
        O4WSetCell()
        O4WTextBox(OCONV(DATE(), "D4/"), "", "", "STDATE", "STDATE")
        O4WSetCell("+1")
        O4WText("Enter ending date: ")
        O4WSetCell()
        O4WTextBox(OCONV(DATE(), "D4/"), "", "", "EDDATE", "EDDATE")
        O4WSetCell("+1")
        O4WSetCell()
        O4WButton("Generate Report", "BTN_GENERATE")
        O4WTableEnd("promptTable")
        O4WQualifyEvent("BTN_GENERATE", "CLICK")
END CASE

Return 0


For step 2, you must collect the results from your collector window, and then "submit" them for processing by your basic+ report routine.  You will almost certainly need to modify your routine so that it generates a PDF, and accepts all the collected user input via passed parameters.  You can then use RTI_TASK_SUBMIT to invoke your routine (or, perhaps, a "wrapper" routine that can pass in the proper parameters to your report routine), and RTI_TASK_STATUS to wait until the output is ready.  Your O4W custom stored procedure might be modified as follows to accomplish this:

SUBROUTINE O4W_CUSTOMER_REPORT(ctlentid, event, request)
$INSERT O4WCOMMON
$INSERT O4WEQUATES

DECLARE FUNCTION RTI_TASK_SUBMIT, RTI_TASK_STATUS

BEGIN CASE
    CASE EVENT _EQC "CREATE"
        O4WForm()
        * build a table for the user prompts and the text boxes to hold their responses
       O4WTableStart("promptTable")
        O4WText("Enter starting date: ")
        O4WSetCell()
        O4WTextBox(OCONV(DATE(), "D4/"), "", "", "STDATE", "STDATE")
        O4WSetCell("+1")
        O4WText("Enter ending date: ")
        O4WSetCell()
        O4WTextBox(OCONV(DATE(), "D4/"), "", "", "EDDATE", "EDDATE")
        O4WSetCell("+1")
        O4WSetCell()
        * also give them a button to push after entering the values
       O4WButton("Generate Report", "BTN_GENERATE")
        O4WTableEnd("promptTable")
        * tell us when they've clicked the button
       O4WQualifyEvent("BTN_GENERATE", "CLICK")

   CASE EVENT _EQC "CLICK"
        O4WResponse()
        * read in the user-entered responses
      stDate = O4WGetValue("STDATE")
      edDate = O4WGetValue("EDDATE")
       iStDate = iconv(stDate, "D")
       iEdDate = iconv(edDate, "D")
      * to do: validate user inputs
       * save off the user reponses – create a unique ID to save them under
      ourInputsID = O4WGenerateID("CUSTOMER_REPORT")
      ourInputsRecord = ""
      ourInputsRecord<1> = iStDate
      ourInputsRecord<2> = iEdDate
      write ourInputsRecord on O4WTempFile%, ourInputsID
      * pass them into the background task generator
      taskID = RTI_TASK_SUBMIT("", "CUSTOMER_REPORT_WRAPPER", ourInputsID)
      * start our "please wait" display
      taskCounter = 0
      Gosub pleaseWait

   CASE EVENT _EQC "TIMER"
      * We're here because the "please wait" dialog called us via a timer event
      * First, hide the "please wait" dialog
      O4WResponse()
      O4WDialog("pleaseWait")
      * Load in the values the dialog passed back to us
      taskID = O4WGetValue("TASKID")<1,1>
      taskCounter = O4WGetValue("COUNTER")<1,1>
      bIsCancelled = O4WGetValue("CANCELLED")
      If bIsCancelled = "" then
          If taskID <> "" then
               myStatus = RTI_Task_Status(taskID, results)
               if myStatus _eqc "COMPLETED" Or myStatus _eqc "ERROR" then
                    * report has finished generating – download the results
                  O4WDownload(results,'','','O4WREPORT.PDF')
              End Else
                  * redisplay dialog
                  taskCounter += 1
                  If taskCounter > 5 Then taskCounter = 0
                 Gosub PleaseWait
            End
        End Else If taskCounter <> "-1" Then
            * taskCounter = -1 => user requested cancel
            O4WError(O4WI_FORMATMSG(O4W_MESSAGE_GENERATE_ERROR$, "PDF"))
        end
   End
END CASE

Return 0

PleaseWait: * Generate 'please wait' dialog
O4WSectionStart("pleaseWait", O4WResponseOptions():O4WMarkedOptions(1))
O4WText(O4WI_FORMATMSG(O4W_MESSAGE_PLEASE_WAIT$):O4WI_FORMATMSG(O4W_MESSAGE_GENERATING$, "PDF"):str(".", taskCounter))
O4WBreak()
O4WBreak()
O4WSectionStart("showImage", "DESELECTED":@SVM:"STDALIGN")
O4WImage("please wait", "../images/pleasewait2.gif",'','','','',O4WSizeStyle('','100%'))
O4WSectionEnd("showImage")
O4WBreak()
O4WButton("Cancel", "BTN_QUIT")
O4WQualifyEvent("BTN_QUIT", "CLICK")
O4WStore("", "CANCELLED")
O4WTimer(1, "", "TASKID=":taskid:"&COUNTER=":taskCounter)
O4WSectionEnd("pleaseWait")
* display this as a dialog
O4WDialog("pleaseWait", O4WI_FORMATMSG(O4W_MESSAGE_GENERATING$,"PDF"):str(".",taskCounter))
Return


As a final step, you must create a wrapper routine function (in our example, CUSTOMER_REPORT_WRAPPER) that will be passed the ID of a record to read from the O4WTEMP table, and will return (as the function result) the name of the PDF that has been generated.   After reading the data from the O4WTEMP table, the record can be deleted, and the "real" basic+ report invoked – perhaps with additional flags to indicate that a PDF should be generated, or with the specific name of a PDF to generate.  An example of the wrapper function might be:

FUNCTION CUSTOMER_REPORT_WRAPPER(userPromptID)

PDFPath = ""
Open "O4WTEMP" to TEMP.FL Then
    Read userInfo from TEMP.FL, userPromptID Then
         iStDate = userInfo<1>
        iEdDate = userInfo<2>
        * If the basic+ report routine requires more/different parameters, then modify this line as appropriate
       call CUSTOMER_REPORT(iStDate, iEdDate, PDFPath)
    End
End 

RETURN PDFPath