Hello Everyone,
A custom function is a software code that can be used to automate a process and this allows you to automate a notification, call a webhook, or perform logic immediately after a workflow rule is triggered. This feature helps to automate complex tasks and calculations.
Lets take the below requirement from a customer -
A customer would like to monitor the progress of current week & last week tasklists and update in the custom fields at Milestone and projects levels.
Lets say, there are 4 Tasklists under a Milestone, the current week progress of these four Tasklists should be updated in the custom field of associated Milestone. Likewise, the progress of the previous week should be populated in another custom field.
Similarly, it should be rolled up and displayed in a custom field at Project level.
A custom function can be used to fulfil this need. However, this has to be implemented for each project i.e. ID of the project should be passed directly in the arguments. I have attached the screenshots of Arguments & schedule.
Establishing a connection with the scopes "zohoprojects.milestones.ALL , zohoprojects.projects.ALL" is all that is required. Below link will let you know how to establish a connection.
endPoint = "https://projects.zoho.com/restapi/portal/";
endPointV3 = "https://projects.zoho.com/api/v3/portal/";
// project cf id
projectCurrentWeekCustomFieldName = "xxxxxx"; // project current week cf name
milestoneCompletionPercent = 0;
divideBy100 = 0;
isTrue = false;
projectCurrentWeekValue = 0;
getAllMilestones = invokeurl
[
url :endPoint + portalId + "/projects/" + projectId + "/milestones/"
type :GET
connection:”******”
];
for each milestone in getAllMilestones.get("milestones")
{
milestoneId = milestone.get("id_string");
getMilestoneDetails = invokeurl
[
url :endPointV3 + portalId + "/projects/" + projectId + "/milestones/" + milestoneId
type :GET
connection:”******”
];
CurrentWeekFieldId = "xxxxxxx";
// milestone cf id
LastWeekFieldId = "xxxxxx";
// milestone cf id
milestoneParameter = Map();
if(getMilestoneDetails.get("custom_fields").get(CurrentWeekFieldId).get("value").equalsIgnoreCase("-"))
{
milestoneParameter.put(CurrentWeekFieldId,getMilestoneDetails.get("completion_percent").toString());
isTrue = true;
}
else
{
milestoneParameter.put(LastWeekFieldId,getMilestoneDetails.get("custom_fields").get(CurrentWeekFieldId).get("value").toString());
milestoneParameter.put(CurrentWeekFieldId,getMilestoneDetails.get("completion_percent").toString());
}
milestoneCompletionPercent=milestoneCompletionPercent+getMilestoneDetails.get("completion_percent");
divideBy100 = divideBy100 + 100;
updateMilestoneDetails = invokeurl
[
url :endPointV3 + portalId + "/projects/" + projectId + "/milestones/" + milestoneId
type :POST
parameters:toString(milestoneParameter)
connection:"*********"
];
}
projectMilestoneCompletionPercentage = (milestoneCompletionPercent / divideBy100) * 100;
// Update Project
projectCurrentWeekFieldId = "xxxxxx";
// project cf id
projectLastWeekFieldId = "xxxxxxx";
projectsParameter = Map();
if(isTrue)
{
projectsParameter.put(projectCurrentWeekFieldId,toString(projectMilestoneCompletionPercentage));
}
else
{
getProjectResponse = invokeurl
[
url :endPoint + portalId + "/projects/" + projectId + "/"
type :GET
connection:"*********"
];
customFields = getProjectResponse.get("projects").get(0).get("custom_fields");
for each customField in customFields{
if(customField.containKey(projectCurrentWeekCustomFieldName)){
projectCurrentWeekValue = customField.get(projectCurrentWeekCustomFieldName);
}
}
projectsParameter.put(projectLastWeekFieldId,projectCurrentWeekValue);
projectsParameter.put(projectCurrentWeekFieldId,toString(projectMilestoneCompletionPercentage));
}
updateProjectResponse = invokeurl
[
url :endPoint + portalId + "/projects/" + projectId + "/"
type :POST
parameters:projectsParameter
connection:"***********"
];
Creating custom functions in Zoho Projects is straightforward and well-documented. Watch this space for more such custom function codes.