I’m trying to calculate the difference between the due date of two tasks in a project. I’ll need to do this for a large volume of projects, so anything that’s not bundle-able (e.g. script actions) is not a viable solution. Anyone been able to do this? I thought about trying to get creative with roll-ups and formula fields in portfolios, but that feels pretty finicky, so not sure that’s the best path forward.
That would be my first suggestion, assuming they’re top-level tasks (not subtasks) in the project. I did get this working, and it’s finicky and a little involved but it’s in production for the client where I used it and working for months.
Perhaps AI Studio as well??
Thanks,
Larry
I remember seeing a similar post a while ago.
There seems to be a need for this, but I think it would be difficult to implement.
HI, @Stephen_Li .
Sorry, this isn’t a direct answer.
Any advice would be appreciated.
Anyway, I was able to calculate and output the difference between the due dates of two tasks.
I also used Copilot to create the script.
/**
-
What’s in scope?
-
- (string) project_gid, workspace_gid, task_gid (only if triggered on a task)
-
- (function) log - this behaves like console.log and takes any number of parameters
-
- (object) *ApiInstance - for each group of APIs, an object containing functions to call the APIs; for example:
-
tasksApiInstance.getTask(…)
-
goalsApiInstance.addFollowers(…)
-
For more info, see GitHub - Asana/node-asana: Official node.js and browser JS client for the Asana API v1
*/
async function run() {
// Make an API request to get the triggered task and wait for the response
// Use the task data in your script by referencing task.data.{attribute} ex: task.data.assignee
const task = await tasksApiInstance.getTask(task_gid);
// Print the task’s name to see it in the run history.
log("task’s current name: " + task.data.name);
// Anything else you want to do!
const projectId = 1210894538568609;
const taskNameA = ‘Task A’;
const taskNameB = ‘Task B’;
const customFieldName = ‘SUB1’;
async function main() {
try {
// Get list of tasks in project
const tasks = await client.tasks.findByProject(projectId, { opt_fields: ‘name,due_on,custom_fields’ });
// Search for task A and task B
const taskA = tasks.data.find(task => task.name === taskNameA);
const taskB = tasks.data.find(task => task.name === taskNameB);
// Initialize message for comment
let commentMessage = '';
if (!taskA || !taskB) {
commentMessage = 'Task A or B was not found.';
} else if (!taskA.due_on || !taskB.due_on) {
commentMessage = 'Task A or B does not have a due date. ';
} else {
// Calculate the date difference
const dateA = new Date(taskA.due_on);
const dateB = new Date(taskB.due_on);
const diffDays = Math.ceil((dateA - dateB) / (1000 * 60 * 60 * 24));
// Get the SUB1 field for task A
const sub1Field = taskA.custom_fields.find(field => field.name === customFieldName);
if (sub1Field) {
// Set the number of days in the SUB1 field
await client.tasks.update(taskA.gid, {
custom_fields: {
[sub1Field.gid]: `${diffDays}日`
}
});
}
// Add a comment
commentMessage = `The difference between the due dates of task A and task B is ${diffDays} days. This value was set in the SUB1 field. `;
}
// Add comment to task A
if (taskA) {
await client.tasks.addComment(taskA.gid, {
text: commentMessage
});
}
console.log('Processing completed.');
} catch (error) {
console.error(‘An error occurred:’, error);
}
}
main();
}
// To function properly, the script must end with returning a Promise via run().
run();
@Ka_Nishiyama - really like both of these and will def try them out in my demo environment. Unfortunately, the AI option isn’t viable for my main (we have AI disabled for now) and the script one will be difficult to implement at scale (since scripts sadly aren’t yet supported in bundles).