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