1
0
-1

We have a specific requirement with our form that requires a Job Collaboration of sorts, but after a far amount of searching I'm struggling to find a scenario that fits our needs. It seems that we need something that's different from all the documentation so I could do with some pointers if anybody is able to help! The list of requirements and info is below:

  • We have a single form consisting of 13 sections and a large number of fields. 
  • We have 2 user types - Customers and Brokers - both of whom need to be able to fill out the form. 
  • The form has to be accessed by authenticated users only, so anonymous form sharing is not a possibility.
  • Sections 12 and 13 should only be accessible for Customers, and Brokers who work on behalf of customers must "hand over" the form to the customer to complete.
  • So, if a customer is completing the form then they can complete all 13 sections, so no job is needed.
  • And, if a broker is completing the form, then they should get to the end of section 11 and have some way to send the form to their specific customer to complete - we can't use groups for this.

Any help or pointers here will be great!

Thanks in advance,

Rich 

  1. Nirmal Solanki

    Hi Richard,

    Are customers authenticated users or anonymous? How they start the application form if they were to complete all 13 sections or last two sections?

CommentAdd your comment...

4 answers

  1.  
    2
    1
    0

    Hi Richard,

    You may want to do a prefill service to set a flag in the form data to say a user is a customer or broker. The sections of the form could be hidden or visible depending on the flag.

    With regards to the Conditional Route Name mentioned by Nirmal this is currently only available for task steps - Task Wait (TM 4.3.4). There is a change request to add this to the Job Form Start.

    It is however quite easy to create a Groovy job action that runs in the start step after the JobFormStart. One advantage to this is that you can calculate if a user is a customer or broker on the server side.

    Here is a diagram of a sample Job to show you what the solution may look like. Below I have also included a non working example of Start Route Job Action to perform the routing, and a sample Job Definition (based on Job example 1 to show how to Start Route Job Action is place in the Application Start step.

     

    Cheers

    Larry Bunton

     

     

    Start Route Job Action - Performs Routing
    /* Groovy Job Action service which is used to execute job step actions.
       Script parameters include: 
           actionContext : com.avoka.fc.core.service.job.ActionContext
           actionStepProperties :  com.avoka.fc.core.service.job.ActionStepProperties
           serviceDefinition : com.avoka.fc.core.entity.ServiceDefinition 
           serviceParameters : Map<String, String>
           job : com.avoka.fc.core.entity.Job 
           submission : com.avoka.fc.core.entity.Submission 
           formDataMap : Map<String, String>
       Script return:
           actionResult : com.avoka.fc.core.service.job.ActionResult
    */
    import com.avoka.fc.core.service.job.ActionContext
    import com.avoka.fc.core.service.job.ActionResult
    import com.avoka.fc.core.service.job.ActionResult.Status
    import com.avoka.core.groovy.GroovyLogger as logger
    
    def route = "Customer"
    if(isUserABroker(job.getFirstSubmission()).getUser()){
    	route = "Broker"  
    }
    
    ActionResult actionResult = ActionResult(Status.COMPLETED)
    actionResult.setRoute(route)
    
    return actionResult
    
    /**
    * method
    */
    boolean isUserABroker(user) {
      boolean isBroker = false
      
      /* enter server side logic here */
      
      return isBroker()
    }
    Sample Customer Job
    {
      "jobDetails": { 
        "name": "Customer Broker",  
        "version": "4.3.4"
      },
      "steps": [
        {
          "name": "Application Start",
          "type": "start",
          "actions": [
            {
              "name": "Accept Quote",
              "type": "Job Form Start",
              "properties": [
                { "name": "Process Message Send Email",  "value": "true" },
                { "name": "Process Message Text",  "value": "Thank you ${formDataMap.firstName} ${formDataMap.lastName} your ${submission.formName} is being processed." }
              ]
            },
            {
              "name": "Start Route Job Action 	",
              "type": "Job Action"
            }
          ],
          "routes": [
            { "name": "Customer",  "nextStep": "Application Delivery" },
            { "name": "Broker",  "nextStep": "Customer Sign Off" }
          ]
        },
        {
          "name": "Customer Sign Off",
          "type": "",
          "actions": [
            {
              "name": "Assign Customer",
              "type": "Job Task Assign",
              "properties": [
                { "name": "Task Assign Groups",  "value": "Job Reviewers, Job Managers" },
                { "name": "Task Form Code",  "value": "$func.startFormCode()" },
                { "name": "Task Message",  "value": "Please review the ${submission.formName} by ${formDataMap.firstName} ${formDataMap.lastName}." },
                { "name": "Task Review Previous Step",  "value": "true" },
                { "name": "Task Subject",  "value": "Review ${submission.formName} by ${submission.contactEmailAddress}." },
                { "name": "Task Type",  "value": "Review" }
              ]
            },
            {
              "name": "Customer Wait",
              "type": "Job Task Wait"
            }
          ],
          "routes": [
            { "name": "Default",  "nextStep": "Application Delivery" }
          ]
        },
        {
          "name": "Application Delivery",
          "type": "",
          "actions": [
            {
              "name": "Application Delivery",
              "type": "Job Delivery"
            },
            {
              "name": "Application Delivery Wait",
              "type": "Job Delivery Wait"
            }
          ],
          "routes": [
            { "name": "Default",  "nextStep": "Application Completed" }
          ]
        },
        {
          "name": "Application Completed",
          "type": "endpoint",
          "actions": [
            {
              "name": "Process Message",
              "type": "Job Process Message",
              "properties": [
                { "name": "Process Message Send Email",  "value": "true" },
                { "name": "Process Message Submission",  "value": "$func.startSubmission()" },
                { "name": "Process Message Text",  "value": "Thank you ${formDataMap.firstName} ${formDataMap.lastName} your ${submission.formName} has been Approved." }
              ]
            }
          ]
        }
      ]
    }
      CommentAdd your comment...
    1.  
      2
      1
      0

      TM doesn't allow you to associate collaboration job conditionally. However, you can have conditional routes. So you always have a job associated with the form regardless its started by Customer or Broker. You can set some data extract if its started by Broker and hide last two sections of the form. Once collaboration job kicks in, you can have conditional route to assign form to the customer by reading that data extract in the condition. If its started by Broker, assign the form to the customer, otherwise route to the endpoint.

      More info can be found at: Multi Step Group Review Job

      For example

       

      Conditional Route Name*

      The following Action Property is from the Task Wait Service. It defines a rule that is applied on the Server Side using collaboration Jobs.

      { "name": "Conditional Route Name",  "value": "#if ( $formDataMap.startedBy == 'Broker' 
      Assign Customer #else Terminate #end" }

      Routers configuration

            "routes": [
              
              { "name": "Assign Customer",  "nextStep": "Additional Review"},
              { "name": "Terminate",  "nextStep": "Terminated Initial" }
            ]
        CommentAdd your comment...
      1.  
        1
        0
        -1

        Hi Richard,

        Your form should contain a field that says whether the form is a Customer or Broker. If a Broker is selected you should show a field where the Broker can select or enter the customer. This field should be setup as a Data Extract see https://support.avoka.com/kb/display/AT43/Composer . The customer sign of tab can then use the value in this field to assign the task in the Customer Sign Off step to the user to fill out.

        The type of field you use depends upon the customer details held in the system.

        Customer is Authenticated: The Customer is held as a UserAccount in Transact and the we need to user login name to set the the Customer Sign Off. How you do this depends on how fancy you want the form to be. It is possible with a lookup field and a Form Dynamic Data. The operation could be like the Address Lookup widget,  the broker could enter the first characters in the users name, the broker would be shown a list of users. When they select the customer login name is put into a hidden field which is a data extract.

        Alternatively you could have the broker enter an email address, click a button and this can be used to lookup the login name.

        Here is what the Customer Sign Off step would look like for an authenticated user

        {
         "name": "Customer Sign Off",
         "type": "",
         "actions": [
           {
            "name": "Assign Customer",
            "type": "Job Task Assign",
            "properties": [
              {"name": "Task Type",  "value": "Review"},
              {"name": "Task Assign User",  "value": "$formDataMap.customerLoginName"},
              {"name": "Task Form Code",  "value": "$func.startFormCode()"},
              {"name": "Task Message",  "value": "Please complete the form"},
              {"name": "Task Review Previous Step",  "value": "true"},
              {"name": "Task Subject",  "value": "Complete ${submission.formName}"},
            ]
           },

         

        Unauthenticated the broker would enter the email address into an email the field. 

        Here is what the Customer Sign Off  step would look like for an anonymous task

        {
         "name": "Customer Sign Off",
         "type": "",
         "actions": [
           {
            "name": "Assign Customer",
            "type": "Job Task Assign",
            "properties": [
             {"name": "Task Assign Email",  "value": "$formDataMap.customerEmail"},
             {"name": "Task Assign Portal", "value": "Customer Space"},
             {"name": "Task Form Code",  "value": "$func.startFormCode()"},
             {"name": "Task Message",  "value": "Please complete the form"},
             {"name": "Task Subject",  "value": "Complete ${submission.formName}"},
             {"name": "Task Input XML Prefill", "value":"$func.startSubmissionXml()"},
             {"name": "Task Type",  "value":"Anonymous"},
             {"name": "Task Save Challenge", "value": "${formDataMap.phoneNumber}"},
            ]           

        Cheers

        Larry

          CommentAdd your comment...
        1.  
          1
          0
          -1

          Hi Nirmal, Larry

          Thank you both for your replies... It's given me a huge amount more information to work with already! I'll crack on and try to get it doing something on a test form.

          One thing that I'm still a bit confused by is how the Customer receives the "handover" from their broker... I can see from both of your examples that there is a different route for the 2 user types - which is perfect - but when the broker needs to send it to the Customer for Sign-Off, where do I specify the details of doing that? I.e. The email address etc. of the customer in question?

          With regards to the routing, I already have a flag in the form XML to determine the user type as there are fields throughout the form which only need to show for one or the other; so that bit should be easy!

          Thank you both for your help so far (smile)

          Rich 

            CommentAdd your comment...