Building Your First Business Process - Hands on Challenge (Solution)


I was wondering if anyone could share the solutions for this exercise since i'm stuck:

Thanks in advance!

Hello b_pal. Sharing solutions is not allowed in this forum, but write me a message with details of your progress, and I can help you.

I am also stuck with where to begin.  My first thought was to update the Assign Reviewer form to have two names: Primary Reviewer and Secondary Reviewer.  Then the AssignReviewer action can use the CreateOrUpdateReview action twice, passing in a different user each time.  This doesn't work, however, because the Assign Reviewer form has to correspond to a single Review.  So, I guess we're going to make poor Chris open the Assign Reviewer box twice?

In the Session Selection process, there could be two tracks coming off of the Start node, as described in the lesson on parallel activities.  However, I don't understand how that works with the UI.  I understand that you want people to work through this on their own, but the guidance on this exercise is sparse.  Any suggestions?


I have not tried, but i think for assigning reviewer, we need to modify the form to enable Chris to choose 2 reviewers.

Then i got stuck in assigning human activity to each reviewer.



Hello Scott. I will help you if you share the code that you are working on via private message.


Hi there,

Is there a clue on how to assign a proposal to 2 reviewers by Christ? Do we need to change the Form such that Christ can tick 2 reviewers all at once in one task?



Indra, there are multiple solutions to the problem, and you should be able to decide how to make the changes necessary to support 2 reviewers for a session.

If you want help, please send me the code that you currently have, and in private we can discuss your options.

Thank you Sir,

After lost in two days, I am nearly to my solution, but i 'll ask some concepts i am still in doubt:

- How to read this wait activity? 

When a review (say Rachael) give a suggest (UpdateReview), the Wait is not close, but it is waiting for the second reviewer (say ROn); it closed when both have done updateReview. Does this mean that the Wait is waiting to close per proposedSessionId, not per ReviewId basis? So, the UpdateReview (in the CLose On property is rather misleading): 



For Christ to assign 2 reviewers, i can manage it by NOT closing the AssignReviewer taskbox (and in this case taskbox is something just like a reminder (accessories- trivial) - not a non trivial business action) in the screen action until  two reviewers are assigned, something like this (is it correct):



May be my 2 cents about BPT:

I found something elegant in ORacle tech called SQL Model, but it is rarely used as it is rather hard to learn. And I rather de javu when learning BPT :). Hopefully, i am wrong.



Hello Indra. Your latest posts are somewhat confusing.

I cannot tell by your pictures if you are doing it correctly or not. Like I said, there are multiple solutions, and I would rather check the code that you've produced until I can give you feedback on what's right and what's wrong. You can save your work in Service Studio (CTRL-S) and send me the file in a private message.

Your first post said the CloseOn was misleading. The CloseOn determines when the Wait activity closes. The timeout is also another way of telling when the Wait activity will close. However, you can cancel any of those Close events if you throw an AbortActivityChange Exception during the OnClose callback.

Your second post has a piece of code that is out of context. Is that code inside a screen action, or inside the process? If it's inside a process, then the Feedback Message will not work - I hope you know why is that. Either way, I don't think you need a call to ActivityClose, so you might be doing something wrong or at least overcomplicating the solution.

Your third post compares BPT to SQL Model. I had never heard of this feature, but upon searching by it I found this, which describes some SQL syntax to performe multidimensional calculations. I really don't know how to compare that with BPT, as they are completely different things. I can only think that you mistaken the name of some other Oracle product, or at least I didn't find the tool you were thinking of.

From this I can give you an advice for future posts, please be more specific. Either include a link to the product you're mentioning, or at least make clear how you are comparing both products.

I'm also stuck with the Master Class on Modeling Business Processes (BPT) challenge.
I manage to assign two 2 reviewers, but after I assigned the second person when I look in serviceCenter the user is the same as the first person to who I assigned the session. See attached image.
How can I solve this problem/what is going wrong?

Sorry for a too late reply on this topic, but since I offered help, I thought I could share a few steps that might help most of the people that get stuck in this challenge.

  1. I am attaching to this comment the SelectionProcess.oml with all changes done in the videos. This is not the solution, but just a convenient starting point. I still recommend you to watch the videos and do all of the changes by yourself - this exercises your muscle memory and you get to explore different things along the way.
  2. The first thing you should consider is: does the data model support multiple reviews per session? If it doesn't support, then you need to change the data model.
  3. The second thing is: does the user interface support multiple reviews per session? Is Chris (the review committee chair) able to assign multiple reviews to a given session? If it doesn't, the you will need to change the user interface. Hint: the Display property of a Container is being used to conditionally hide the Assign Review link - you still need to find the container and change the Display property. Another hint: something is closing the AssignReviewer activity after the first review is assigned... maybe it's not a good idea to close it! Remember that Chris can still close the activity in the taskbox.
  4. How is the taskbox activity created for each reviewer? Do you understand how that mechanism works? If you don't, you should watch the video Add Human Activities to a Process and Pick Tasks Assigned to You From the Taskbox.
  5. Each reviewer only sees the taskbox activity that is assigned to him/her. How does that work? If you don't understand how each activity gets assigned to a particular user, watch the video Add Human Activities to a Process again.
  6. Now consider that you assign multiple reviews for a given session. Will multiple taskbox activities get created, one for each review? You can check how many were created in Service Center, which is described in great detail at the end of the video Pause a Process with a Wait Activity.
  7. In the case of having multiple reviews for a session, does each ReviewProposedSession activity get assigned to the correct user? If not, check how the user is being assigned to the activity, and try to understand why doesn't it work. Remember that each session will have multiple reviewers, but each ReviewProposedSession activity should be assigned to its own reviewer. Hint: if only you could get the correct Review record, and then read its ReviewerId...
  8. Try to assign multiple reviews for a given session, then complete the last review before the others. Does that work as you would expect? If not, you will need to fix it. Hint: what a good time to use the debugger!
  9. Try to assign multiple reviews for a given session, make sure you close Chris's taskbox activity, then complete the first review before the others. Check the status of the session. Does the status reflect what you would expect? If not, you will need to fix it. Hint: you got too used to this, no hint this time...
  10. Try to assign multiple reviews for a given session, make sure you close Chris's taskbox activity, then complete all reviews but rejecting the last review. Check the status of the session. Is it what you would expect? If not, are you able to fix this?

Finishing this challenge could take 2 to 16 hours. If you still couldn't finish it, send me a private message and I'll try to help.

If you finished the challenge with ease, and want to spend more time in this challenge, allow me to highlight the second part of this challenge, which most people don't even start to think of:

"DecideOnSession should also be implemented to allow the chairperson to make a decision when the reviewers don’t agree to reject the session."

Let me talk briefly what it entails.

What is being asked is that the decision must be escalated to Chris (the review committee chair) in the case of two reviewers disagreeing on rejecting or not the session. In that circumstance, Chris would be able make a final decision.

Any solution to this second part would require designing some business logic that is not very explicit, and a user interface for Chris to make the decision. Feel free to get creative in this part, but I'm going to suggest a simple solution.

On the ReviewerRejectedSession decision, change its logic so that the Rejected status only gets set if all complete reviews have the Reject decision, i.e. all reviewers agree it should be rejected.

On the DecideOnSession activity, you should check if all complete reviews have Accept decision. If so, then update the status of the session to Accepted. Otherwise, set the status to Undecided.

On Chris's list of sessions (ProposedSessions screen), for sessions that have status Undecided, Chris will see two new buttons: Accept and Reject. The Accept button simply changes the status of the session to Accepted. Similarly, the Reject button sets the status to Rejected.

Good luck!

Thanks Leonardo!

I just finished this challenge and your guidance was very useful. :-)

One thing for others to notice: In your testing, you should start any activity from taskbox with selecting activity, even current UI is allowing you to jump directly to AssignReview and Review Session popups. 

In other words, ActivitId is Null before you select task from taskbox, so in real life solutions, UI should have links to activity screens only via taskbox. This took a while to notice since I was looking errors in my code when problem was how I was executing my testing.

leonardo.fernandes wrote:

Indra, there are multiple solutions to the problem, and you should be able to decide how to make the changes necessary to support 2 reviewers for a session.

If you want help, please send me the code that you currently have, and in private we can discuss your options.

Hi Leonardo,

After struggling 4 days I rest my case. My solution is processing an order that need to be checked by two persons. The setup is exactly the same as in the course. I am able to assign two people to check the same order without problems, but the Console then shows double entries. On person fits nice, but the other shows up double. I really have no clue. Attached my solution. Would appreciate if you can help me out.


Hi Ron. First, don't feel too bad, as you can see lots of other people had the same problem.

I haven't deployed your solution, but I could only find 4 things that you need fixing. These are quite common as well, so I'll leave some details about fixing them so others could benefit.

1. You have two conditional starts for the CreateCheck. You don't need that. A conditional start is not something that only fires once. Indeed, it will fire for every event matching the Start On condition. So you only need a single conditional start, which will be fired twice if two checkers get created.

You can have only a single conditional start, and the condition can be CreateCheck filtering only by OrderId. Remove the filter by CheckerId, and the conditional start will work for any checker that gets created for the same OrderId.

2. The conditional start outputs an ActivityCheckId, which you should use on your conditional flow. For example, in the CheckForAction1, you are initializing the UserId based on the OrderId, but because there could be two different checkers, you have created a boolean flag to retrieve either the first one or the second one.

You could initialize the UserId based on the ActivityCheckId, which will represent the Checker that spawned the conditional flow. If the conditional flow is spawned twice, because two Checkers were created for the same OrderId, then the value of ActivityCheckId will be different for each execution.

UserId = GetCheck(NewCheck1.ActivityCheckId).Check.CheckerId

3. You have two parallel wait activities before deciding on the order. Each wait activity will run in parallel, and as soon as one finishes, the process will continue. So the arrows merging in the DecideOnOrder do not represent a process join!

Again, you can have a single Wait activity, which waits for all checkers. However, there's no way to express that in the Wait activity: you have either the option of a Timeout, or a Close On entity event. But using a Close On, the Wait would close as soon as any update is made on the Check entity, and does not guarantee that all Checkers have made a decision.

The way you circumvent that lack of expressivity is by using a Wait with Close On = UpdateCheck (just like you have), but then add a On Close callback on the Wait activity. It's unfortunate that there's a "Close On" and a "On Close" which are completely different things, so I'll link to the doumentation for both: Close On is a property of the Wait ( and On Close is a callback (

The code in the On Close callback will run whenever the Wait tries to close itself, and you can build logic to validate whether you really want to close in this state, or if you still want to remain waiting. The logic you must build is: query all Check of this same OrderId. If there's at least on Check without decision, then you must keep waiting, and for that you can simply throw an exception called Abort Activity Change Exception.

4. You should not be using GetCheckerFromOrder anymore. The case that you have more than two Checkers for the same order will not work with your current solution. Even if you are trying to focus on having only two Checkers, that boolean specifying either the first or the second feels kind of weird, and creates the tendency to duplicate code which only differ in that flag (do you recognize that?).

A good solution to this exercise should delete the GetCheckerFromOrder action, and replace it with a better mechanism. When you consider a 1-to-many relationship between Order and Checker, this whole concept of "GetCheckerFromOrder" starts to fall apart. It should be your goal to remove that code to make sure your application is still sound after the change.