This article will show you how to use the PPM Cloud REST API, illustrating how it can used to automate a manual task.
One of the challenges in Oracle PPM is maintaining worker assignments to projects - with a small number of workers and a handful of projects, this is simple, but can more onerous in larger organizations.
The PPM REST API allows you to assign workers to projects from the command line. This gives the potential to script multiple updates, saving time navigating in and out of each project’s team member list to perform manual assignments.
Getting Started
The first thing required is an ERP Cloud user account with the "Projects Integration Specialist" role - this allows the PPM REST APIs to be called.
You will also need the base URL for your cloud instance, which is in the form:
https://<pod>.prj.<region>.oraclecloud.com:443
For example, if your pod is abcd-dev1, and the region is em3 then the base url is:
https://abcd-dev1.prj.em3.oraclecloud.com:443
We will use URL in the examples below.
Retrieving The Project Id
The Team Members REST API is driven by the Project Id and not the Project Number or Project Name. So if we want to assign someone to project 1100100, we need to know Oracle’s internal ID for this project.
One way to find this out would be to use Oracle BI Publisher to create a custom Data Model with a simple SQL statement such as:
SELECT project_id , segment1 project_number FROM pjf_projects_all_v WHERE segment1 = '1100100';
When run, this would return the Project Id and Project Number.
Alternatively, sticking to our theme of running from the command line, we can use the PPM REST web service to do the same thing. To call a REST web service from the command line, we’ll use cURL.
The Projects GET URL is constructed from the following elements:
These are then used in the cURL command below.
curl --user USERNAME:PASSWORD -X GET \ "https://abcd-dev1.prj.em3.oraclecloud.com:443/projectsFinancialsApi/resources/latest/projects?fields=ProjectId,ProjectNumber&onlyData=true&limit=50&q=ProjectNumber=1100100"
This gives returns the Project Id for the Project Number.
{ "items" : [ { "ProjectId" : 300000056097271, "ProjectNumber" : "1100100" } ], "count" : 1, "hasMore" : false, "limit" : 50, "offset" : 0, "links" : [ { "rel" : "self", "href" : "abcd-dev1.prj.em3.oraclecloud.com:443/projectsFinancialsApi/resources/11.1.11/projects", "name" : "projects", "kind" : "collection" } ] }
One thing to add here is that you can run this without the "q" query parameter - and this will then return ALL projects and their IDs, which can be handy.
Assigning the Worker to the Project
Armed with the Project Id, we can derive the URL needed to add a team member to the project:
{ "PersonEmail" : "[email protected]", "ProjectRole" : "Project Team Member", "StartDate" : "2017-01-01" }
Notice that the unique identifier of the worker is the email address. This implies that there must be one and only worker in the system using that email address - otherwise the API cannot identify which worker to assign and will raise an error. The start date is also critical - the worker and project must be effective as of that date.
The API returns a message that is compressed using gzip - so we have to pipe the cURL output through gunzip to review it.
The full cURL command then looks like this:
curl --user USERNAME:PASSWORD -X POST \ https://abcd-dev1.prj.em3.oraclecloud.com:443/projectsFinancialsApi/resources/latest/projects/300000054485480/child/ProjectTeamMembers \ -H 'content-type: application/vnd.oracle.adf.resourceitem+json' \ -d '{ "PersonEmail" : "[email protected]", "ProjectRole" : "Project Team Member", "StartDate" : "2017-05-01" }' | gunzip
When run successfully, we see a simple (nearly) empty return message:
[]
As always, it is as important to check failure responses to understand what messages will be returned and how they can be handled.
Here is a sample error message. There are in an XML-like format.
<MESSAGE> <NUMBER>PJF-2235518</NUMBER> <TEXT>This team role is already assigned to this person in the specified date range.</TEXT> <CAUSE></CAUSE> <ACTION></ACTION> <DETAILS>You cannot assign a team role to a person more than once during a specific time frame. Enter a start and end date for this person and team role combination that does not overlap the date range for the existing assignment.</DETAILS> <INCIDENT></INCIDENT> </MESSAGE> JBO-27023: Failed to validate all rows in a transaction.JBO-27024: Failed to validate a row with key oracle.jbo.Key[300000056158736 ] in ProjectPartyEOJBO-PJF:::PJF_TM_DUP_ROLE_ASGMT: <MESSAGE> <NUMBER>PJF-2235518</NUMBER> <TEXT>This team role is already assigned to this person in the specified date range.</TEXT> <CAUSE></CAUSE> <ACTION></ACTION> <DETAILS>You cannot assign a team role to a person more than once during a specific time frame. Enter a start and end date for this person and team role combination that does not overlap the date range for the existing assignment.</DETAILS> <INCIDENT></INCIDENT> </MESSAGE> JBO-PJF:::PJF_TM_DUP_ROLE_ASGMT: <MESSAGE> <NUMBER>PJF-2235518</NUMBER> <TEXT>This team role is already assigned to this person in the specified date range.</TEXT> <CAUSE></CAUSE> <ACTION></ACTION> <DETAILS>You cannot assign a team role to a person more than once during a specific time frame. Enter a start and end date for this person and team role combination that does not overlap the date range for the existing assignment.</DETAILS> <INCIDENT></INCIDENT> </MESSAGE>
Checking the Results
To check the successful addition, we can list the Team Members on the project by calling the same URL with a GET request.
The curl command becomes:
curl --user USERNAME:PASSWORD -X GET \ "abcd-dev1.prj.em3.oraclecloud.com:443/projectsFinancialsApi/resources/latest/projects/300000054485480/child/ProjectTeamMembers?onlyData=true&limit=50"
And we can see from the output that the team member has been added:
{ "items" : [ { "FinishDate" : null, "PersonEmail" : "[email protected]", "PersonName" : "Jon Dixon", "ProjectId" : 300000054485480, "ProjectRole" : "Project Manager", "StartDate" : "2015-09-30", "TeamMemberId" : 300000054485569 }, { "FinishDate" : null, "PersonEmail" : "[email protected]", "PersonName" : "Matt Paine", "ProjectId" : 300000054485480, "ProjectRole" : "Project Team Member", "StartDate" : "2017-05-01", "TeamMemberId" : 300000056158735 } ], "count" : 2, "hasMore" : false, "limit" : 50, "offset" : 0, "links" : [ { "rel" : "self", "href" : "https://abcd-dev1.prj.em3.oraclecloud.com:443/projectsFinancialsApi/resources/11.1.11/projects/300000054485480/child/ProjectTeamMembers", "name" : "ProjectTeamMembers", "kind" : "collection" } ] }
Adding an End-Date
To remove a team-member from a project, we add an end-date using the PATCH method. We need the internal team member id - fortunately we have this from the prior step.
The cURL command is:
curl --user USERNAME:PASSWORD -X PATCH \ https://abcd-dev1.prj.em3.oraclecloud.com:443/projectsFinancialsApi/resources/latest/projects/300000054485480/child/ProjectTeamMembers/300000056158735 \ -H 'content-type: application/vnd.oracle.adf.resourceitem+json' \ -d '{ "StartDate" : "2017-05-01", "FinishDate" : "2017-05-30" }'
This returns an unzipped response containing the TeamMember JSON item, confirming the update:
{ "FinishDate" : "2017-05-30", "PersonEmail" : "[email protected]", "PersonName" : "Matt Paine", "ProjectId" : 300000054485480, "ProjectRole" : "Project Team Member", "StartDate" : "2017-05-01", "TeamMemberId" : 300000056158735, "links" : [ { "rel" : "self", "href" : "https://abcd-dev1.prj.em3.oraclecloud.com:443/projectsFinancialsApi/resources/11.1.11/projects/300000054485480/child/ProjectTeamMembers/300000056158735", "name" : "ProjectTeamMembers", "kind" : "item" }, { "rel" : "canonical", "href" : "https://abcd-dev1.prj.em3.oraclecloud.com:443/projectsFinancialsApi/resources/11.1.11/projects/300000054485480/child/ProjectTeamMembers/300000056158735", "name" : "ProjectTeamMembers", "kind" : "item" }, { "rel" : "parent", "href" : "https://abcd-dev1.prj.em3.oraclecloud.com:443/projectsFinancialsApi/resources/11.1.11/projects/300000054485480", "name" : "projects", "kind" : "item" } ] }
Note that at this stage you’re limited to updating the Start Date and Finish Date - you can’t update the team member’s role, see example below:
curl --user USERNAME:PASSWORD -X PATCH \ https://abcd-dev1.prj.em3.oraclecloud.com:443/projectsFinancialsApi/resources/latest/projects/300000054485480/child/ProjectTeamMembers/300000056158735 \ -H 'content-type: application/vnd.oracle.adf.resourceitem+json' \ -d '{ "StartDate" : "2017-05-01", "FinishDate" : "2017-05-30", "ProjectRole" : "Project Administrator" }'
This returns gzipped output, with the following error.
JBO-27008: Attribute ProjectRole in view object ProjectVO_ProjectTeamMembers_ProjectVOToTeamMemberVO_ProjectTeamMemberVO cannot be set.
Conclusion
Armed with the PPM REST API, we can list projects and their ids, create and update PPM team members. Using cURL, we can execute these REST APIs from the command line, which gives us the ability to script mass updates.
As always, pay careful attention to error trapping and handling - and make sure that you full test the functionality before production deployment.
Oracle are progressively expanding their REST API catalog for ERP Cloud. For example, in R12, you can report on and update Project Progress using REST.
I’d encourage you to review the full PPM REST API catalog which for R12 can be found here: http://docs.oracle.com/cloud/farel12/projectcs_gs/FAPAP/