Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 63 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
63
Dung lượng
504,64 KB
Nội dung
you try to move the cursor from the Approval form name field to another field, as shown in the following figure: Postopen Postmodechange Querysave Queryclose Click Exiting GetApproverDetails Globals You cannot move the cursor without typing a name, because the Exiting event handler checks the field contents. The Approver button has a Click event handler which is called by a mouse click trigger. The handler calls the global routine GetApproverDetails, which displays a dialog box created by a layout region in the (Approverinfo) form. The following picture shows an event sequence which occurs when you create the Application Profile document: 622 Lotus Domino Release 5.0: A Developer’s Handbook Eclipses shown in gray are not performed, because there is no program defined for them. You can use the Domino debugger to see the sequence of real-time events. For more information on the debugger, see Chapter 10: Programming for Domino. Approval Cycle Database: Agent The approval application requires an agent to deal with the due date expiration in this example. When the due date has passed and the approver has not taken any action, the agent processes the approval request depending on the criteria specified in the application profile for the due date. A Closer Look at the ApprovalLogic Subform The following section explains how the ApprovalLogic subform works and shows you some of the techniques that you can use in designing your own workflow applications. We assume here that you have already created your workflow form and have set up an Application Profile document for it. Note The LotusScript that follows may not look exactly the same as that in the template, as it has been formatted for better clarity. Chapter 16: Domino Ad Hoc Workflow 623 The Major Fields The ApprovalLogic subform uses many variables to perform its operation, but there are a few that require particular attention: Controls which action button (submit, approve, deny) the current user has clicked and performs the appropriate functions. This field is not displayed on the form, but created via the action buttons. TextAction Contains the current status of the workflow document as designated in the Application Profile document. TextStatus Contains the name of the next approver in the workflow process. TextNextApprover Controls who currently has the ability to edit the document. This is modified in the QuerySave form event and changed from the original author to the next approver, and finally to the form administrator. AuthorsAuthorizedEditors Description F ield Type F ield Name Creating a New Request 1. To create a new request, the user clicks Create New Request in the All Requests view. This does three things: • It builds a list of available Application Profiles from the ApplicationProfiles view and displays them in a dialog box where the user can make selections. • It sets an environment variable, DocType, to the value of the selected document. • It composes the selected document. tList := @DbColumn(""; ""; "ApplicationProfiles"; 1); List := @If(@IsError(tList); @Return(@Prompt([OK]; _ "Error"; "An error has occurred. Please try again.")); _ tList); ENVIRONMENT DocType := @Prompt([OKCANCELLIST]; "New _ Request"; "Choose one of the following:"; @Subset(List; _ 1); List); @PostedCommand([Compose]; DocType) 2. When the new workflow document is being created, the LotusScript PostOpen event is triggered. This code first checks to see if the new document was created via the Create New Request action button by checking the value of the environment variable DocType. If the environment variable does not exist or is blank, then the user is not allowed to proceed. 624 Lotus Domino Release 5.0: A Developer’s Handbook If source.IsNewDoc Then DocType = s.GetEnvironmentString("DocType") Call s.SetEnvironmentVar("DocType", "None") If DocType = "None" Or Isempty(DocType) Then Messagebox "This Document must be created via" "the Create New Request action."_ & " Please remove it from the Create Menus.", 0,_ "Error" Continue = False source.Close Exit Sub End If 3. Still within the PostOpen event of the form, LotusScript then finds the selected Application Profile document and copies all the fields into the new document being created. If the profile document cannot be found, the user is informed and is not allowed to continue. Set view = db.GetView("Application Profiles")\ Set profile = view.GetDocumentByKey(DocType,False) If profile Is Nothing Then Messagebox "This application will not execute"&_ "correctly without an application profile.", 0 + 64, "Design Error" doc.close Print Exit Sub Else profile.RemoveItem("Form") Call profile.CopyAllitems(note) End If FormAdmin = note.FormAdmin If FormAdmin(0) = "" Then note.FormAdmin = db.Managers note.RequesterName = s.CommonUserName End If Note The form name is removed from the Application Profile document before the fields are copied into the new document. If this was not done, the new document would open using the Application Profile form rather than the correct workflow form. Although the form field is removed from the Application Profile document, it is not actually deleted, as the document is not saved. 4. When a new document is being created, the subroutine InitializeNewDoc() is called from the forms PostOpen event to set up the following approver fields: Approver Names (only if not defined on the Application Profile), Status, Approval Dates, and Comments. Chapter 16: Domino Ad Hoc Workflow 625 5. If the list of approvers has been defined in the Application Profile as being stored in another database, the GetApproverNames() LotusScript function is executed to retrieve the list of names from the database and the view specified in the Application Profile. Note All the fields have been updated in the back-end document, rather than the UIDocument. 6. At the end of the PostOpen event, the fields in the UI document are reloaded from the back-end database and then refreshed to reset the hide-when formulas and computed fields. source.Reload source.Refresh 7. When the document is refreshed, the PostRecalc event for the form is triggered. This event checks whether the current user is trying to edit the approver list and, if not, exits. 8. The new document is then displayed for the user to complete as required. In summary, when a new workflow document is created, the PostOpen form event validates whether the request was generated from the Create New Request action button by using environment variables. The Application Profile document is located and its fields copied into the new document, and the list of approver fields is updated. Submitting a New Form for Approval 1. When a new workflow document is completed as required, the user clicks Submit for Approval. This performs the following functions. • It checks to see if the field ApprName contains the value “Entered when Submitted.” This value is copied from the Application Profile document and indicates that the user has not selected the list of people to send this document to for approval. If they have not made the selection, then an error message is displayed, and they are required to return to the document and enter the approvers’ names. • The action button sets the value of the field Action to the value Submit. The field SaveOptions is then set to the value “1” to force the document to be saved and not display the “Do you want to Save this Document” dialog box to the user. 626 Lotus Domino Release 5.0: A Developer’s Handbook • The document is then saved and closed. @If(@Contains(ApprName; "Entered when submitted"); @Return(@Prompt([OK]; PromptTitle; "Please use the \"Edit Approver List\" button to enter a valid approver name.")); ""); FIELD Action := "Submit"; FIELD SaveOptions := "1"; @PostedCommand([FileSave]); @PostedCommand([FileCloseWindow]) 2. Before the document is closed, the QuerySave() form event is triggered by the @PostedCommand([FileSave]) function from the action button. • This function first sets the global variable DocWasSaved to true so that the QueryClose event knows to remove some fields. • It is possible that the user simply wanted to save the document rather than submit it for approval, so a check is made to see if the document was saved via the Submit for Approval action button by testing whether the document contains the Action field: If Not note.HasItem("Action") Then Exit Sub • Next, the IdentifyUser() subroutine is called to rebuild the list of remaining approvers by identifying those approvers that still have a status of none. • Using a case statement, the QuerySave event then checks to see which action button the user clicked (Submit, Approve, or Deny) by testing the value of the field Action: Select Case Action(0) Case "Submit" If (Status(0) = StatusList(4)) Or (Status(0) = _ StatusList(5)) Then For n = 1 To 5 note.RemoveItem("ApprStatus") note.RemoveItem("ApprDate") note.RemoveItem("ApprComment") Next End If note.RequestDate = dt.LSLocalTime note.Status = StatusList(2) SetNextApprover SetDueDate SendNotification Chapter 16: Domino Ad Hoc Workflow 627 • If the action is Submit, the function SetNextApprover() is called to identify the next approver. This subroutine checks to see which routing method has been defined (either Serial or Parallel) and sets the next approver to the first person in the array built from the IdentifyUser() subroutine: Select Case RoutingMethod(0) 'If RoutingMethod is serial then NextApprover is simply 'the next in the list Case "Serial" If NextAppr > Ubound(ApprName) Then 'StatusQualifier is only used while the approval cycle is 'active note.RemoveItem("StatusQualifier") LastApprover = True Else NextApprover = ApprName(NextAppr) note.NextApprover = NextApprover note.StatusQualifier = "by " & NextApprover End If Case "Parallel" Select Case Action(0) 'If submitting - the next approver is all approvers Case "Submit" note.NextApprover = ApproverList 'If Approving - remove CurrentUser from the ApproverList 'and reset NextApprover to the new list Case "Approve" ListMax = Ubound(ApproverList) Redim tmpList(ListMax) x = 0 For y = 0 To ListMax If ApproverList(y) <> CurrentUser Then tmpList(x) = ApproverList(y) x = x + 1 End If Next If x = 0 Then tmpList(x) = "None" LastApprover = True End If note.NextApprover = tmpList End Select End Select 628 Lotus Domino Release 5.0: A Developer’s Handbook • The subroutine SetDueDate() is called next to set the due dates by which the approver(s) must authorize the document. For a parallel workflow document all the due dates for each of the remaining authorizers are set, and for a serial workflow document, only the next approver’s due date is set: Select Case RoutingMethod(0) 'If Parallel - adjust all dates Case "Parallel" For n = 0 To ListMax Adjustment = ApprWin(n) dt.AdjustDay(Int(Adjustment)) tmpList(n) = dt.LSLocalTime dt.SetNow Next 'If Serial - only adjust the date for the Next Approver Case "Serial" DueDate = note.DueDate Redim tmpList(NextAppr) x = 0 Forall d In DueDate tmpList(x) = d If (tmpList(x) = "") Then tmpList(x) = dt.LSLocalTime End If x = x + 1 End Forall Adjustment = ApprWin(NextAppr) dt.AdjustDay(Int(Adjustment)) tmpList(NextAppr) = dt.LSLocalTime End Select note.DueDate = tmpList • The SendNotification() subroutine is then called to mail the details of the workflow document to the next approver. This subroutine creates a new mail document and sets up the required Domino mail fields in order for the document to be mailed. If the workflow document is set up as a serial document, all approvers are sent an e-mail, if it is set up as a parallel workflow document, only the next approver is e-mailed: Select Case RoutingMethod(0) 'If it is Serial - mail gets sent to the NextApprover Case "Serial" SendTo = NextApprover Recipient = NextApprover 'If it is Parallel - mail gets sent to all approvers Case "Parallel" SendTo = ApproverList Chapter 16: Domino Ad Hoc Workflow 629 Recipient = "all Approvers" End Select Subject = WorkflowObject(0) & " requires your approval by " & Format(DueDate(NextAppr), "Long Date") maildoc.DueDate = Format(DueDate(NextAppr), "Long Date") maildoc.FlowStatus = "Please follow this doclink to the " & WorkflowObject(0) & " and either approve or deny it." 'Put a doclink in the Body field and populate the other fields on the Bookmark mail form Call rtitem.AppendDocLink(note, "Doclink to " & WorkflowObject(0)) maildoc.InheritedDbTitle = db.Title maildoc.Form = "Bookmark" maildoc.SendTo = SendTo maildoc.Subject = subject • The mail message is then sent: Call maildoc.Send (False) • Finally, the UI document is then reloaded from the back-end document to update the UI document fields. 3. After the mail item is sent and the QuerySave event has finished, the @PostedCommand([FileCloseWindow]) function is performed. This triggers the QueryClose form event. This event cleans up any temporary fields that were used in the document: 'Remove the Action field and any field that begins with d_ 'This includes all temporary fields and all display only 'fields '(a back-end save will save computed for display fields 'unless you do this) note.RemoveItem("Action") ItemList = note.Items Forall n In ItemList If Left(n.Name, 2) = "d_" Or Left(n.Name, 2) = "D_" Then n.Remove End Forall 4. The QueryClose event then executes the ResetAuthorNames() subroutine. This subroutine removes the document author from the AuthorizedEditors Authors field and adds the name of the next approver: Select Case NewStatus(0) 'If approvals are done - the FormAdmin is the only editor Case StatusList(6), StatusList(7) note.AuthorizedEditors = FormAdmin(0) 'If approvals are not started - the Requester is the only 'editor Case StatusList(0), StatusList(1) 630 Lotus Domino Release 5.0: A Developer’s Handbook note.AuthorizedEditors = RequesterName(0) Case Else tmpList(0) = FormAdmin(0) x = 1 Forall n In NextApprover tmpList(x) = n x = x + 1 End Forall note.AuthorizedEditors = tmpList End Select 5. The document is then finally closed. In summary, when Submit is clicked, the field Action is set to Submitted and the QuerySave event is triggered. The QuerySave event sets up a list of remaining approvers, sets the next due date and sends an e-mail to the next approver(s). Finally, the QueryClose event cleans up the document and sets the author of the document to be the next approver. Approving a Request When an approver clicks Approve, the following events occur: 1. On the Approve action button, the value of the field Action is set to Approve and a dialog box is displayed to enable the approver to enter any comments. The document is then saved and closed: @Command([EditDocument]; "1"); FIELD Action := "Approve"; FIELD SaveOptions := "1"; @If(CommentsAllowed = "Yes"; @DialogBox("EnterComments"; [AutoVertFit] : [AutoHorzFit]); PromptTitle); @PostedCommand([FileSave]); @PostedCommand([FileCloseWindow]) 2. The @PostedCommand([FileSave]) command triggers the QuerySave form event. The QuerySave event updates the current approver status, date and comment fields: Select Case Action(0) Case "Approve" 'Set approval status for the current approver ApprStatus = note.ApprStatus ApprStatus(CurrentApprover) = StatusList(3) note.ApprStatus = ApprStatus 'Set approval date for the current approver ApprDate = note.ApprDate ApprDate(CurrentApprover) = dt.LSLocalTime note.ApprDate = ApprDate 'Set comment value for the current approver Chapter 16: Domino Ad Hoc Workflow 631 [...]... OpenNavigator Syntax: http://Host/Database/NavigatorName?OpenNavigator http://Host/Database/$defaultNav?OpenNavigator Examples: http://www.testR5.com/products.nsf/Main+Navigator?OpenNavigator http://www.testR5.com/products.nsf/$defaultNav?OpenNavigator Note $defaultNav opens the folder navigator in a database OpenAgent Syntax: http://Host/Database/Agentname?OpenAgent Examples: http://www.testR5.com/sales/leads.nsf/Process+New+Leads?OpenAge... http://www.testR5.com/discussion.nsf/Docs/By+Author 636 Lotus Domino Release 5.0: A Developer’s Handbook Opening Servers, Databases, and Views The following commands access servers, databases, views, About documents, help documents, and database icons OpenServer Syntax: http://Host Example: http://www.testR5.com/?OpenServer OpenDatabase Syntax: http://Host/DatabaseFileName?OpenDatabase http://Host/DatabaseReplicaID?OpenDatabase Examples:... http://Host/Database/FramesetName?OpenFrameset Note FramesetName can be also an alias of the frameset Examples: http://www.testR5.com/products.nsf/Product?OpenFrameset OpenPage Syntax: http://Host/Database/PageName?OpenPage Note PageName can be also an alias of the page Examples: http://www.testR5.com/products.nsf/Product?OpenPage Appendix A: Domino URLs 639 OpenForm Syntax: http://Host/Database/FormName?OpenForm... reach specific components quickly Domino URL Command Syntax Domino URL commands have the following syntax: http://Host/Database/DominoObject?Action&Arguments where: Host DNS entry or an IP address Caution You cannot use the Domino Server name unless it has a DNS entry Database Database can be one of the following: • The database file name with the path relative to notes\data • The database Replica... menu bar so you can use arrow keys to choose commands F10 or ALT Create a new memo CTRL+M Send a memo ALT+3 Create a new database CTRL+N Open a database (add a database to workspace) CTRL+O Close a document ESC continued 647 Action Shortcut Cancel a server operation CTRL+BREAK Open the Scan Unread dialog box TAB Enter and follow a URL to a World Wide Web site CTRL+L Move from one workspace tab to another... the ApprovalLogic subform to better understand how an ad hoc workflow application can be designed 634 Lotus Domino Release 5.0: A Developer’s Handbook Appendix A Domino URLs Domino uses URLs to access servers, databases, and other components of a Web site, and display them to Web users Knowing Domino URL commands allows you to design links or enter commands directly into a browser to navigate a Domino. .. command to access the database icon Syntax: http://Host/Database/$icon?OpenIcon Examples: http://www.testR5.com/leads.nsf/$icon?OpenIcon 638 Lotus Domino Release 5.0: A Developer’s Handbook Login Argument Append the Login argument to any Domino URL to force user authentication, regardless of the database access control list This ensures that anonymous Web users who weren’t initially prompted for a name... than one attached file has the same name, the URL includes both the internal file name as well as the external name Since the internal file name is not easily determined, make sure that all attached files have unique names Domino treats all file attachment OpenElement commands as implicit commands, because some browsers require that the URL ends with the attached file name Using OpenElement with Image... FALSE], default = FALSE • SearchOrder=[1,2,3] default = 1 • 1 = “By Relevance” • 2 = “By Date Ascending” • 3 =“By Date Descending” • SearchMax=[n], 0 default= 0 (meaning all) • SearchWV=[TRUE, FALSE], default = TRUE • Start=[n] • OldSearchQuery Repeats the last query Note The SearchThesaurus argument is ignored by the R5.0 search machine 646 Lotus Domino Release 5.0: A Developer’s Handbook Appendix B... require user authentication Because URLs may not contain spaces, use the + (plus sign) as a separator For example: http://www.testR5.com/discussion.nsf/By+Author 5 Separate arguments with & (ampersands) For example: http://www.testR5.com/leads.nsf/By+Salesperson?OpenView&Exp andView 6 Separate hierarchical names with / (slashes) For example, to open a view named Docs\By Author in a database named Discussion, . navigator in a database. OpenAgent Syntax: http://Host/Database/Agentname?OpenAgent Examples: http://www.testR5.com/sales/leads.nsf/Process+New+Leads?OpenAge nt 6 40 Lotus Domino Release 5. 0: A Developer’s. argument: http://Host/Database/FormUniversalID?OpenForm&ParentUNID Examples: http://www.testR5.com/products.nsf/40aa91d55cle4c82 852 5636 300 4d c9e0?OpenForm&ParentUNID=6bc7 2a9 2613fd6bf 852 563de 001 f 1a 25 Note You can also use the ?OpenRead or ?ReadForm command. forms, navigators, and agents in a database. OpenFrameset Syntax: http://Host/Database/FramesetName?OpenFrameset Note FramesetName can be also an alias of the frameset. Examples: http://www.testR5.com/products.nsf/Product?OpenFrameset OpenPage Syntax: http://Host/Database/PageName?OpenPage Note