This site contains the documentation that is relevant to older WSO2 product versions and offerings.
For the latest WSO2 documentation, visit https://wso2.com/documentation/.
Production Issue and Bug Tracking in Producteev
The second use case in the Producteev business scenario is production issue and bug tracking. This page describes the relevant tasks and the operations you use in the Producteev connector and the other ESB connectors.
Overview
The flow for production issue and bug tracking is illustrated in the following diagram. The ESB connectors for Zoho CRM will be used to connect to each service.
- Retrieve all the cases from the Zoho CRM API which are in the status "New" using the searchRecords operation.
- Retrieve the potential details associated with the case from the Zoho CRM API using the searchRecords operation.
- Create the task using the Zoho CRM case details in the Producteev API using the createTask operation.
- Add a task note with the case description in the Producteev API using the createNote operation.
- Add a task note with the Case ID in the Producteev API using the createNote operation.
- Once the process is completed update the case details in the Zoho CRM API using the updateRecords operation.
- Assign the task created in the Producteev API using the assignTask operation.
- Remove the default assignee from the task using the removeAssignee operation in the Producteev API.
- Use the getTask operation in the Producteev API to avoid the issues with "No Content" response.
- Add a label to the task according to the label type of the case using the addLabelToTask operation in the Producteev API.
Update the task with the priority using the updateTask operation in the Producteev API.
Note
The task should be created under the project which is mapped to the potential which is associated to the case.
Producteev operations
Zoho CRM operations
Prerequisites
 There should be at least one user available in the Producteev account other than the account owner, to be added as an assignee.
Samples
<?xml version="1.0" encoding="UTF-8"?> <!-- Copyright (c) 2005-2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. WSO2 Inc. licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <!-- Retrieve cases from the ZohoCRM API and create tasks in the Producteev API having them assigned to users and tag the created tasks with the relevant label. --> <proxy xmlns="http://ws.apache.org/ns/synapse" name="producteev_createTasksAndAddLabels" transports="http, https" statistics="disable" trace="disable" startOnLoad="true"> <target> <inSequence onError="faultHandlerSeq"> <!-- ZohoCRM properties. --> <property name="zohocrm.apiUrl" value="https://crm.zoho.com" /> <property name="zohocrm.accessToken" expression="json-eval($.zohocrm.accessToken)" /> <property name="zohocrm.scope" value="crmapi" /> <property name="zohocrm.caseModule" value="Cases" /> <property name="zohocrm.potentialModule" value="Potentials" /> <property name="zohocrm.caseCriteria" value="(status:New)" /> <property name="zohocrm.xmlData" value="<Cases> <row no="1"> <FL val="Status">Completed</FL> </row> </Cases>" /> <!-- Producteev properties. --> <property name="producteev.apiUrl" value="https://www.producteev.com" /> <property name="producteev.accessToken" expression="json-eval($.producteev.accessToken)" /> <property name="producteev.assigneeIds" expression="json-eval($.producteev.assigneeIds)" /> <property name="producteev.labelBug" expression="json-eval($.producteev.labelIds.bug)" /> <property name="producteev.labelProductionIssue" expression="json-eval($.producteev.labelIds.productionIssue)" /> <!-- Common properties. --> <property name="id.empty" value="{}" /> <property name="index" value="0" scope="operation" /> <property name="potentialIndex" value="0" scope="operation" /> <property name="projectIndex" value="0" scope="operation" /> <property name="producteevUserIndex" expression="0" scope="operation" /> <property name="producteevTaskIndex" expression="0" scope="operation" /> <!-- Retrieving all the cases from ZohoCRM account which are in status "New". --> <zohocrm.init> <scope>{$ctx:zohocrm.scope}</scope> <accessToken>{$ctx:zohocrm.accessToken}</accessToken> <apiUrl>{$ctx:zohocrm.apiUrl}</apiUrl> </zohocrm.init> <zohocrm.searchRecords> <criteria>{$ctx:zohocrm.caseCriteria}</criteria> <module>{$ctx:zohocrm.caseModule}</module> </zohocrm.searchRecords> <!--Removing unused headers. --> <sequence key="removeResponseHeaders" /> <!-- START : Checks for the successful execution of searchRecords method. --> <property name="errorCode" expression="json-eval($..code)" /> <filter xpath="get-property('errorCode') != '[]'"> <then> <!-- START : Checks for the successful retrieval of Cases for the given criteria. --> <property name="message" expression="json-eval($..message[0])" /> <property name="noData" expression="json-eval($..nodata)" /> <filter xpath="get-property('noData') != '[]'"> <then> <!-- If the Cases are not available for the account within the given criteria, generate the error response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id.empty}" /> <with-param name="status" value="Skipped" /> <with-param name="activity" value="zohocrm_listCases" /> <with-param name="message" value="There are no new cases exist to process." /> </call-template> <loopback /> </then> <else> <!-- searchRecords method execution failure, generate the error response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id.empty}" /> <with-param name="activity" value="zohocrm_listCases" /> <with-param name="status" value="Error" /> <with-param name="message" value="{$ctx:message}" /> </call-template> <loopback /> </else> </filter> <!-- END : Checks for the successful retrieval of Cases. --> </then> <else> <property name="zohocrmCasesCount" expression="count(//result/Cases/row)" scope="operation" /> <!-- START: Iterates over the Cases and proceed to create Tasks in Producteev. --> <iterate continueParent="false" id="casesIterator" expression="//result/Cases/row" sequential="true"> <target> <sequence> <!-- START : Checks whether the Task is already created for the Case. Otherwise proceed to create Task. --> <property name="producteevTaskId" expression="//FL[val[text()='Producteev Task ID']]/content/text()" /> <filter source="boolean(get-property('producteevTaskId'))" regex="true"> <then> <property name="index" expression="get-property('operation','index') + 1" scope="operation" /> </then> <else> <property name="producteevTaskIndex" expression="get-property('operation','producteevTaskIndex') + 1" scope="operation" /> <property name="zohocrm.potentialName" expression="//FL[val[text()='Potential Name']]/content/text()" /> <property name="zohocrm.potentialId" expression="//FL[val[text()='POTENTIALID']]/content/text()" /> <property name="zohocrm.taskLabel" expression="//FL[val[text()='Task Label']]/content/text()" /> <property name="zohocrm.caseId" expression="//FL[val[text()='CASEID']]/content/text()" /> <property name="zohocrm.caseSubject" expression="//FL[val[text()='Subject']]/content/text()" /> <property name="zohocrm.taskLabel" expression="//FL[val[text()='Task Label']]/content/text()" /> <property name="zohocrm.caseDescription" expression="//FL[val[text()='Description']]/content/text()" /> <property name="zohocrm.casePriority" expression="//FL[val[text()='Priority']]/content/text()" /> <!-- START : Checks for the successful retrieval of Potential Name associated with the case. --> <filter xpath="get-property('zohocrm.potentialName') = '[]'"> <then> <property name="index" expression="get-property('operation','index') + 1" scope="operation" /> </then> <else> <property name="potentialIndex" expression="get-property('operation','potentialIndex') + 1" scope="operation" /> <property name="zohocrm.potentialCriteria" expression="fn:concat('(Potential Name:', get-property('zohocrm.potentialName'), ')')" /> <!-- Retrieving the Potential details associated with the Case. --> <zohocrm.init> <scope>{$ctx:zohocrm.scope}</scope> <accessToken>{$ctx:zohocrm.accessToken}</accessToken> <apiUrl>{$ctx:zohocrm.apiUrl}</apiUrl> </zohocrm.init> <zohocrm.searchRecords> <criteria>{$ctx:zohocrm.potentialCriteria}</criteria> <module>{$ctx:zohocrm.potentialModule}</module> </zohocrm.searchRecords> <!--Removing unused headers. --> <sequence key="removeResponseHeaders" /> <!-- START : Checks for the successful execution of searchRecords method. --> <property name="errorCode" expression="json-eval($..code)" /> <property name="noData" expression="json-eval($..nodata)" /> <property name="message" expression="json-eval($..message[0])" /> <filter xpath="get-property('errorCode') != '[]'"> <then> <filter xpath="get-property('noData') != '[]'"> <then> <property name="index" expression="get-property('operation','index') + 1" scope="operation" /> </then> <else> <property name="message" expression="fn:concat('Failed to retrieve the potential associated with the case. Reason: ', get-property('message'))" /> <!-- searchRecords method execution failure, generate the error response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id.empty}" /> <with-param name="activity" value="zohocrm_getPotential" /> <with-param name="status" value="Error" /> <with-param name="message" value="{$ctx:message}" /> </call-template> <loopback /> </else> </filter> </then> <else> <!-- START : Checks for the successful retrieval of Producteev Project ID associated with the Potential. --> <property name="producteev.projectId" expression="//FL[val[text()='Producteev Project ID']]/content/text()" /> <filter source="boolean(get-property('producteev.projectId'))" regex="false"> <then> <property name="index" expression="get-property('operation','index') + 1" scope="operation" /> </then> <else> <property name="projectIndex" expression="get-property('operation','projectIndex') + 1" scope="operation" /> <!-- Create the Task in Producteev using the ZohoCRM Case details. --> <producteev.init> <accessToken>{$ctx:producteev.accessToken}</accessToken> <apiUrl>{$ctx:producteev.apiUrl}</apiUrl> </producteev.init> <producteev.createTask> <title>{$ctx:zohocrm.caseSubject}</title> <projectId>{$ctx:producteev.projectId}</projectId> </producteev.createTask> <!--Removing unused headers. --> <sequence key="removeResponseHeaders" /> <!-- Stores the response details of createTask method execution to be used later. --> <property name="producteev.taskId" expression="json-eval($.task.id)" /> <property name="producteev.creatorId" expression="json-eval($.task.creator.id)" /> <!-- START : Checks for the successful execution of createTask method. --> <property name="responseStatus" expression="$axis2:HTTP_SC" /> <filter xpath="get-property('responseStatus') != 201"> <then> <property name="message" expression="json-eval($.error_description)" /> <filter xpath="get-property('responseStatus') = 401"> <then> <!-- createTask method execution failure, generate the error response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id.empty}" /> <with-param name="activity" value="producteev_createTask" /> <with-param name="status" value="Error" /> <with-param name="message" value="{$ctx:message}" /> </call-template> <loopback /> </then> <else> <property name="id" expression="fn:concat('zohocrm_caseId:',get-property('zohocrm.caseId'),',','zohocrm_potentialId:',get-property('zohocrm.potentialId'))" /> <!-- createTask method execution failure, generate the error response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id}" /> <with-param name="activity" value="producteev_createTask" /> <with-param name="status" value="Error" /> <with-param name="message" value="{$ctx:message}" /> </call-template> <property name="index" expression="get-property('operation','index') + 1" scope="operation" /> </else> </filter> </then> <else> <!-- Add Case details as notes to the Task to be used later. --> <!-- START : Checks for the successful retrieval of case description. --> <filter source="boolean(get-property('zohocrm.caseDescription'))" regex="true"> <then> <!-- Add Task note with Case description. --> <property name="zohoCaseDescription" expression="fn:concat('Task Description:',get-property('zohocrm.caseDescription'))" /> <producteev.init> <accessToken>{$ctx:producteev.accessToken}</accessToken> <apiUrl>{$ctx:producteev.apiUrl}</apiUrl> </producteev.init> <producteev.createNote> <message>{$ctx:zohoCaseDescription}</message> <taskId>{$ctx:producteev.taskId}</taskId> </producteev.createNote> </then> </filter><!-- END : Checks for the successful retrieval of case description. --> <!-- START : Checks for the successful execution of createNote method. --> <property name="responseStatus" expression="$axis2:HTTP_SC" /> <filter xpath="get-property('responseStatus') != 201"> <then> <property name="id" expression="fn:concat('zohocrm_caseId:', get-property('zohocrm.caseId'),',','producteev_taskId:', get-property('producteev.taskId'))" /> <property name="errInfo" expression="json-eval($.error_description)" /> <property name="message" expression="fn:concat('Failed to add case description as a note to the task. Reason: ',get-property('errInfo'))" /> <!-- createNote method execution failure, generate the error response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id}" /> <with-param name="activity" value="producteev_addNote" /> <with-param name="status" value="Error" /> <with-param name="message" value="{$ctx:message}" /> </call-template> </then> </filter> <!-- END : Checks for the successful execution of createNote method. --> <!-- Add Task note with Case ID. --> <property name="zohoCaseId" expression="fn:concat('ZohoCRM CaseID:',get-property('zohocrm.caseId'))" /> <producteev.init> <accessToken>{$ctx:producteev.accessToken}</accessToken> <apiUrl>{$ctx:producteev.apiUrl}</apiUrl> </producteev.init> <producteev.createNote> <message>{$ctx:zohoCaseId}</message> <taskId>{$ctx:producteev.taskId}</taskId> </producteev.createNote> <!-- START : Checks for the successful execution of createNote method. --> <property name="responseStatus" expression="$axis2:HTTP_SC" /> <filter xpath="get-property('responseStatus') != 201"> <then> <property name="id" expression="fn:concat('zohocrm_caseId:', get-property('zohocrm.caseId'),',','producteev_taskId:', get-property('producteev.taskId'))" /> <property name="errInfo" expression="json-eval($.error_description)" /> <property name="message" expression="fn:concat('Failed to add case ID as a note to the task. Reason: ',get-property('errInfo'))" /> <!-- createNote method execution failure, generate the error response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id}" /> <with-param name="activity" value="producteev_addNote" /> <with-param name="status" value="Error" /> <with-param name="message" value="{$ctx:message}" /> </call-template> </then> </filter> <!-- END : Checks for the successful execution of createNote method. --> <!-- Preparing the xmlData to update Case with Task ID once the process is completed. --> <property name="zohocrm.xmlData" expression="fn:concat('<Cases> <row no="1"> <FL val="Producteev Task ID">',get-property('producteev.taskId'),'</FL> </row> </Cases>')" /> <!-- Update the Case details in ZohoCRM once the process is completed. --> <zohocrm.init> <scope>{$ctx:zohocrm.scope}</scope> <accessToken>{$ctx:zohocrm.accessToken}</accessToken> <apiUrl>{$ctx:zohocrm.apiUrl}</apiUrl> </zohocrm.init> <zohocrm.updateRecords> <id>{$ctx:zohocrm.caseId}</id> <xmlData>{$ctx:zohocrm.xmlData}</xmlData> <moduleType>{$ctx:zohocrm.caseModule}</moduleType> </zohocrm.updateRecords> <!--Removing unused headers. --> <sequence key="removeResponseHeaders" /> <!-- START : Checks for the successful execution of updateRecords method. --> <property name="errorCode" expression="json-eval($..code)" /> <property name="message" expression="json-eval($..message[0])" /> <filter xpath="get-property('errorCode') != '[]'"> <then> <property name="id" expression="fn:concat('zohocrm_caseId:', get-property('zohocrm.caseId'),',','producteev_taskId:', get-property('producteev.taskId'))" /> <property name="message" expression="fn:concat('Error in updating the case with task ID. Reason: ', get-property('message'))" /> <!-- updateRecords method execution failure, generate the error response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id}" /> <with-param name="activity" value="zohocrm_updateCase" /> <with-param name="status" value="Error" /> <with-param name="message" value="{$ctx:message}" /> </call-template> <property name="index" expression="get-property('operation','index') + 1" scope="operation" /> </then> <else> <!-- Iterates over the list of assigneeIds given in the request and choose an user to assign the task. --> <property name="userIndex" expression="get-property('operation','producteevUserIndex')" /> <script language="js"> <![CDATA[ //Iterates over the list of assigneeIds given in the request, select an user to assign the task. var assigneeIds = mc.getProperty('producteev.assigneeIds'); if (assigneeIds != null && assigneeIds != "") { var userIndexString = '' + mc.getProperty('userIndex'); userIndexString = userIndexString.split('.')[0]; //splitting the assigneeIds string by comma to access each assigneeId. var assigneeArray = assigneeIds.split(','); var noOfAssignees = assigneeArray.length; mc.setProperty('producteev.currentAssigneeId', assigneeArray[userIndexString]); if(userIndexString < noOfAssignees - 1) { userIndexString = java.lang.Integer.parseInt(userIndexString) + 1; } else { userIndexString = 0; } mc.setProperty('userIndex', userIndexString); } else { mc.setProperty('errInAssignee', "ID of the assignee is not provided in the request."); } ]]> </script> <!-- START : Checks for the successful retrieval of the assignee ID. --> <property name="producteevUserIndex" expression="get-property('userIndex')" scope="operation" /> <filter source="boolean(get-property('errInAssignee'))" regex="true"> <then> <property name="id" expression="fn:concat('zohocrm_caseId:',get-property('zohocrm.caseId'),',','producteev_taskId:', get-property('producteev.taskId'))" /> <property name="message" expression="fn:concat('Task is successfully created but not assigned to a user. Reason: ', get-property('errInAssignee'))" /> <!-- Assignee is not found, generate the error response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id}" /> <with-param name="activity" value="producteev_createTaskAndAssignToUser" /> <with-param name="status" value="Skipped" /> <with-param name="message" value="{$ctx:message}" /> </call-template> <property name="index" expression="get-property('operation','index') + 1" scope="operation" /> </then> <else> <!-- Assign the Task created. --> <producteev.init> <accessToken>{$ctx:producteev.accessToken}</accessToken> <apiUrl>{$ctx:producteev.apiUrl}</apiUrl> </producteev.init> <producteev.assignTask> <taskId>{$ctx:producteev.taskId}</taskId> <userId>{$ctx:producteev.currentAssigneeId}</userId> </producteev.assignTask> <!--Removing unused headers. --> <sequence key="removeResponseHeaders" /> <!-- START : Checks for the successful execution of assignTask method. --> <property name="responseStatus" expression="$axis2:HTTP_SC" /> <filter xpath="get-property('responseStatus') != 200"> <then> <property name="id" expression="fn:concat('zohocrm_caseId:',get-property('zohocrm.caseId'),',','producteev_taskId:', get-property('producteev.taskId'))" /> <property name="errInfo" expression="json-eval($.error_description)" /> <property name="message" expression="fn:concat('Task is successfully created but not assigned to the user [',get-property('producteev.currentAssigneeId'), ']. Reason: ',get-property('errInfo'))" /> <!-- assignTask method execution failure, generate the error response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id}" /> <with-param name="activity" value="producteev_createTaskAndAssignToUser" /> <with-param name="status" value="Error" /> <with-param name="message" value="{$ctx:message}" /> </call-template> <property name="index" expression="get-property('operation','index') + 1" scope="operation" /> </then> <else> <property name="id" expression="fn:concat('zohocrm_caseId:', get-property('zohocrm.caseId'),',','producteev_taskId:', get-property('producteev.taskId'),',','producteev_assigneeId:', get-property('producteev.currentAssigneeId'))" /> <property name="message" value="Task is successfully created and assigned to the user." /> <property name="status" value="Success" /> <!-- Generate the success response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id}" /> <with-param name="activity" value="producteev_createTaskAndAssignToUser" /> <with-param name="status" value="{$ctx:status}" /> <with-param name="message" value="{$ctx:message}" /> </call-template> <!-- Remove the default assignee from the task. --> <producteev.init> <accessToken>{$ctx:producteev.accessToken}</accessToken> <apiUrl>{$ctx:producteev.apiUrl}</apiUrl> </producteev.init> <producteev.removeAssignee> <taskId>{$ctx:producteev.taskId}</taskId> <userId>{$ctx:producteev.creatorId}</userId> </producteev.removeAssignee> <!--Removing unused headers. --> <sequence key="removeResponseHeaders" /> <!-- Stores the response details of removeAssignee method execution to be used later. --> <property name="removeAssigneeStatusCode" expression="$axis2:HTTP_SC" /> <property name="errInfo" expression="json-eval($.error_description)" /> <!-- An extra method call to avoid the issues with "No content" response from previous call. --> <producteev.init> <accessToken>{$ctx:producteev.accessToken}</accessToken> <apiUrl>{$ctx:producteev.apiUrl}</apiUrl> </producteev.init> <producteev.getTask> <taskId>{$ctx:taskId}</taskId> </producteev.getTask> <!-- START : Checks for the successful execution of removeAssignee method. --> <filter xpath="get-property('removeAssigneeStatusCode') != 204"> <then> <property name="id" expression="fn:concat('zohocrm_caseId:', get-property('zohocrm.caseId'),',','producteev_taskId:', get-property('producteev.taskId'))" /> <property name="message" expression="fn:concat('Error in removing the default assignee from task. Reason: ', get-property('errInfo'))" /> <!-- removeAssignee method execution failure, generate the error response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id}" /> <with-param name="activity" value="producteev_removeDefaultAssignee" /> <with-param name="status" value="Error" /> <with-param name="message" value="{$ctx:message}" /> </call-template> <property name="index" expression="get-property('operation','index') + 1" scope="operation" /> </then> <else> <!-- START : Checks for the successful retrieval of Task Label of the Case. --> <filter source="boolean(get-property('zohocrm.taskLabel'))" regex="false"> <then> <property name="id" expression="fn:concat('{"zohocrm_caseId":"', get-property('zohocrm.caseId'), '",','"producteev_taskId":"', get-property('producteev.taskId'), '"}')" /> <!-- Failed to retrieve Task Label of the Case, generate the error response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id}" /> <with-param name="activity" value="producteev_addLabelToTask" /> <with-param name="status" value="Skipped" /> <with-param name="message" value="Task Label is not available for the case, hence the label is not added." /> </call-template> <property name="index" expression="get-property('operation','index') + 1" scope="operation" /> </then> <else> <script language="js"> <![CDATA[ //Setting the Labels for the Task. var bugId = mc.getProperty('producteev.labelBug'); var productionIssueId = mc.getProperty('producteev.labelProductionIssue'); var taskLabel = mc.getProperty('zohocrm.taskLabel'); if (taskLabel.equalsIgnoreCase('Bug')) { mc.setProperty('producteev.labelId', bugId); } if (taskLabel.equalsIgnoreCase('Production-Issue')) { mc.setProperty('producteev.labelId', productionIssueId); } ]]> </script> <!-- START : Checks for the availability of Producteev Task Label. --> <filter source="boolean(get-property('producteev.labelId'))" regex="false"> <then> <property name="id" expression="fn:concat('zohocrm_caseId:', get-property('zohocrm.caseId'),',','producteev_taskId:', get-property('producteev.taskId'))" /> <!-- Failed to retrieve Producteev Task Label, generate the error response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id}" /> <with-param name="activity" value="producteev_addLabelToTask" /> <with-param name="status" value="Skipped" /> <with-param name="message" value="ID of the label is not provided in the request, hence the label is not added." /> </call-template> <property name="index" expression="get-property('operation','index') + 1" scope="operation" /> </then> <else> <!-- Add label to the Task according to the Label type of the Case. --> <producteev.init> <accessToken>{$ctx:producteev.accessToken}</accessToken> <apiUrl>{$ctx:producteev.apiUrl}</apiUrl> </producteev.init> <producteev.addLabelToTask> <taskId>{$ctx:producteev.taskId}</taskId> <labelId>{$ctx:producteev.labelId}</labelId> </producteev.addLabelToTask> <!--Removing unused headers. --> <sequence key="removeResponseHeaders" /> <!-- START: Checks for the successful execution of addLabelToTask method. --> <property name="responseStatus" expression="$axis2:HTTP_SC" /> <filter xpath="get-property('responseStatus') != 200"> <then> <property name="id" expression="fn:concat('zohocrm_caseId:', get-property('zohocrm.caseId'),',','producteev_taskId:', get-property('producteev.taskId'))" /> <property name="errInfo" expression="json-eval($.error_description)" /> <property name="message" expression="fn:concat('Error in adding label to the task . Reason: ', get-property('errInfo'))" /> <!-- addLabelToTask method execution failure, generate the error response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id}" /> <with-param name="activity" value="producteev_addLabelToTask" /> <with-param name="status" value="Error" /> <with-param name="message" value="{$ctx:message}" /> </call-template> <property name="index" expression="get-property('operation','index') + 1" scope="operation" /> </then> <else> <!-- START : Checks for the availability of Case priority. --> <filter source="boolean(get-property('zohocrm.casePriority'))" regex="false"> <then> <property name="id" expression="fn:concat('zohocrm_caseId:', get-property('zohocrm.caseId'),',','producteev_taskId:', get-property('producteev.taskId'))" /> <!-- Failed to retrieve the case priority, generate the error response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id}" /> <with-param name="activity" value="producteev_assignPriorityForTask" /> <with-param name="status" value="Skipped" /> <with-param name="message" value="Priority is not set for the case, hence the priority is not assigned." /> </call-template> <property name="index" expression="get-property('operation','index') + 1" scope="operation" /> </then> <else> <!-- Mapping the priority levels of a Case in ZohoCRM to the priority levels of a Task in Producteev. --> <script language="js"> <![CDATA[ //Setting the priorities for Task. var taskPriority = mc.getProperty('zohocrm.casePriority'); if (taskPriority.equals("High")) { mc.setProperty('producteev.taskPriority', 4); } if (taskPriority.equals("Medium")) { mc.setProperty('producteev.taskPriority', 3); } if (taskPriority.equals("Low")) { mc.setProperty('producteev.taskPriority', 2); } ]]> </script> <!-- START : Checks for the availability of Priority of the Task. --> <filter source="boolean(get-property('producteev.taskPriority'))" regex="false"> <then> <property name="id" expression="fn:concat('zohocrm_caseId:', get-property('zohocrm.caseId'),',','producteev_taskId:', get-property('producteev.taskId'))" /> <!-- Failed to retrieve priority for the Task, generate the error response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id}" /> <with-param name="activity" value="producteev_assignPriorityForTask" /> <with-param name="status" value="Skipped" /> <with-param name="message" value="Failed to retrieve the case priority, hence the priority is not assigned." /> </call-template> <property name="index" expression="get-property('operation','index') + 1" scope="operation" /> </then> <else> <!-- Update the Task with the priority. --> <producteev.init> <accessToken>{$ctx:producteev.accessToken}</accessToken> <apiUrl>{$ctx:producteev.apiUrl}</apiUrl> </producteev.init> <producteev.updateTask> <taskId>{$ctx:producteev.taskId}</taskId> <priority>{$ctx:producteev.taskPriority}</priority> </producteev.updateTask> <!--Removing unused headers. --> <sequence key="removeResponseHeaders" /> <!-- START : Checks for the successful execution of updateTask method. --> <property name="responseStatus" expression="$axis2:HTTP_SC" /> <filter xpath="get-property('responseStatus') != 200"> <then> <property name="id" expression="fn:concat('zohocrm_caseId:', get-property('zohocrm.caseId'),',','producteev_taskId:', get-property('producteev.taskId'))" /> <property name="errInfo" expression="json-eval($.error_description)" /> <property name="message" expression="fn:concat('Error in setting priority for the task. Reason: ', get-property('errInfo'))" /> <!-- updateTask method execution failure, generate the error response. --> <call-template target="responseHandlerTemplate"> <with-param name="id" value="{$ctx:id}" /> <with-param name="activity" value="producteev_assignPriorityForTask" /> <with-param name="status" value="Error" /> <with-param name="message" value="{$ctx:message}" /> </call-template> <property name="index" expression="get-property('operation','index') + 1" scope="operation" /> </then> <else> <property name="index" expression="get-property('operation','index') + 1" scope="operation" /> </else> </filter><!-- END : Checks for the successful execution of updateTask method. --> </else> </filter><!-- END : Checks for the availability of Priority of the Task. --> </else> </filter><!-- END : Checks for the availability of Case priority. --> </else> </filter><!-- END : Checks for the successful execution of addLabelToTask method. --> </else> </filter><!-- END : Checks for the availability of Producteev Task Label. --> </else> </filter><!-- END : Checks for the successful retrieval of Task Label of the Case. --> </else> </filter><!-- END : Checks for the successful execution of removeAssignee method. --> </else> </filter><!-- END : Checks for the successful execution of assignTask method. --> </else> </filter><!-- END : Checks for the successful retrieval of the assignee ID. --> </else> </filter><!-- END : Checks for the successful execution of updateRecords method. --> </else> </filter><!-- END : Checks for the successful execution of createTask method. --> </else> </filter><!-- END : Checks for the successful retrieval of Producteev Project ID associated with the Potential. --> <!-- Move to outSequence when all the iterations are done. --> <filter xpath="get-property('operation', 'index') = get-property('operation', 'zohocrmCasesCount')"> <then> <filter xpath="get-property('operation','projectIndex') = 0.0"> <then> <call-template target="responseHandlerTemplate"> <with-param name="activity" value="producteev_createTasks" /> <with-param name="id" value="{$ctx:id.empty}" /> <with-param name="status" value="Skipped" /> <with-param name="message" value="There are no projects associated with any of the potentials." /> </call-template> </then> </filter> <loopback /> </then> </filter> </else> </filter> <!-- END : Checks for the successful execution of searchRecords method. --> </else> </filter> <!-- END: Checks for the successful retrieval of Potential Name associated with the case. --> <!-- Move to outSequence when all the iterations are done. --> <filter xpath="get-property('operation', 'index') = get-property('operation', 'zohocrmCasesCount')"> <then> <filter xpath="get-property('operation','potentialIndex') = 0.0"> <then> <call-template target="responseHandlerTemplate"> <with-param name="activity" value="zohocrm_getPotential" /> <with-param name="id" value="{$ctx:id.empty}" /> <with-param name="status" value="Skipped" /> <with-param name="message" value="There are no potentials associated with any of the cases." /> </call-template> </then> </filter> <loopback /> </then> </filter> </else> </filter><!-- END : Checks whether the Task is already created for the Case. --> <!-- Move to outSequence when all the iterations are done. --> <filter xpath="get-property('operation', 'index') = get-property('operation', 'zohocrmCasesCount')"> <then> <filter xpath="get-property('operation','producteevTaskIndex') = 0.0"> <then> <call-template target="responseHandlerTemplate"> <with-param name="activity" value="zohocrm_listCases" /> <with-param name="id" value="{$ctx:id.empty}" /> <with-param name="status" value="Skipped" /> <with-param name="message" value="There are no new cases exist to process." /> </call-template> </then> </filter> <loopback /> </then> </filter> </sequence> </target> </iterate><!--END LOOP: Iterates over the Cases. --> </else> </filter> <!-- END of filter: Checks for the successful execution of searcRecords method. --> </inSequence> <outSequence> <!-- Generate the chained response of all the API calls in createTasksAndAddLabels. --> <property name="messageType" value="application/json" scope="axis2" /> <payloadFactory media-type="json"> <format> { "Response": { "process": "producteev_createTasksAndAddLabels", "activityResponse": [$1] } } </format> <args> <arg evaluator="xml" expression="get-property('operation', 'responseString')" /> </args> </payloadFactory> <send /> </outSequence> </target> <description /> </proxy>
{ "zohocrm": { "accessToken": "c4f7cc36640277adc846e4b56e6db6e2" }, "producteev": { "accessToken": "ODkwNWFlOTM4OGM4MjU1YTQ1NjdiYjFhMzFjMjQ1Njk2NGMxYmMxNzU0YmQwNjI1NDVmOGUzYThkYmRmNTM3Yg", "assigneeIds": "55cc7df4b1fa099c6e00000c", "labelIds": { "bug": "55cc869eb1fa09ab7b000004", "productionIssue": "55cc86b2b0fa09697b000005" } } }
Note
 The following are the parameter descriptions:
A comma separated list of IDs of the users (Other than the account owner) available in the Producteev account.producteev.assigneeIds:
An object contains IDs of the 'Bug' and 'Production-Issue' labels which are available in the Producteev account as a prerequisite.producteev.labelIds:
All the rest of the parameters are API URLs and authentication credentials to access each API specified in the request. Refer to the individual connector methods for clarification.