Find your people. Pick a challenge. Ship something real. The CreatorCon Hackathon is coming to the Community Pavilion for one epic night. Every skill level, every role welcome. Join us on May 5th and learn more here.

Reoccuring scheduled Tasks

Nabilah
Tera Contributor

Hi

 

i have a requirement to create reoccuring schedule tasks based on a definition record (kind of mimicking outlook). I have a custom definition table and have created an activity task table that extends the task table. I have created a catalog item called scheduled activity defintion request. The end user selects reoccurance pattern, start date and end date (if they want tasks to generate indefinitely end date is left blank). I have a scheduled job that runs daily at 9am and triggers the following script include:

 

 

var GenerateTaskTest = Class.create();
GenerateTaskTest.prototype = {
    initialize: function() {},

    generateTasks: function(definitionRecord) {
        if (!definitionRecord || !definitionRecord.getValue("u_short_description")) {
            return;
        }

        // Get Scheduled Activity Task Definition Details
        var taskName = definitionRecord.getValue("u_short_description");
        var taskDesc = definitionRecord.getValue("u_description");
        var startDate = new GlideDateTime(definitionRecord.getValue("u_start_date"));
        var endDate = definitionRecord.getValue("u_end_date") ? new GlideDateTime(definitionRecord.getValue("u_end_date")) : null;
        var reoccurrencePattern = definitionRecord.getValue("u_run");
        var customInterval = definitionRecord.getValue("u_custom_interval");
        var assignedTo = definitionRecord.getValue("u_managed_by");
        var assignmentGroup = definitionRecord.getValue("u_assignment_group");
        var nextTaskDue = new GlideDateTime(definitionRecord.getValue("u_next_task_due"));

        // Get today's date
        var today = new GlideDateTime();
        today.setDisplayValue(today.getDate().getByFormat("yyyy-MM-dd 00:00:00"));
        startDate.setDisplayValue(startDate.getDate().getByFormat("yyyy-MM-dd 00:00:00"));

        // Set default next task due date if empty
        if (!nextTaskDue || nextTaskDue.getValue() === '') {
            nextTaskDue = new GlideDateTime(startDate);
        }

        
        if (nextTaskDue.compareTo(today) < 0) {
            if (reoccurrencePattern === "daily") {
                nextTaskDue.addDays(1);
            } else if (reoccurrencePattern === "weekly") {
                nextTaskDue.addWeeks(1);
            } else if (reoccurrencePattern === "monthly") {
                nextTaskDue.addMonths(1);
            } else if (reoccurrencePattern === "yearly") {
                nextTaskDue.addYears(1);
            } else if (reoccurrencePattern === "custom" && customInterval && !isNaN(customInterval)) {
                var intervalDays = parseInt(customInterval, 10);
                if (intervalDays > 0) {
                    nextTaskDue.addDays(intervalDays);
                } else {
                    gs.error("Invalid custom interval value: " + customInterval);
                    return;
                }
            } else {
                gs.error("Invalid recurrence pattern detected: " + reoccurrencePattern);
                return;
            }
        }

        // Update the field with the adjusted next due date
        definitionRecord.setValue("u_next_task_due", nextTaskDue);
        definitionRecord.update();

        // Stop tasks if end date has passed
        if (endDate && today.compareTo(endDate) > 0) {
            gs.info("Task generation stopped. End date has passed: " + endDate.getDisplayValue());
            return;
        }

        // Check if next task due date is today or earlier
        if (nextTaskDue.getDate().getByFormat("yyyy-MM-dd") > today.getDate().getByFormat("yyyy-MM-dd")) {
            gs.info("No task due today for: " + taskName + ". Next task is due on: " + nextTaskDue.getDisplayValue());
            return;
        }

        // Calculate next task due date based on recurrence pattern
        var nextTaskDate = new GlideDateTime(nextTaskDue);
        if (reoccurrencePattern === "daily") {
            nextTaskDate.addDays(1);
        } else if (reoccurrencePattern === "weekly") {
            nextTaskDate.addWeeks(1);
        } else if (reoccurrencePattern === "monthly") {
            nextTaskDate.addMonths(1);
        } else if (reoccurrencePattern === "yearly") {
            nextTaskDate.addYears(1);
        } else if (reoccurrencePattern === "custom" && customInterval && !isNaN(customInterval)) {
            var nextIntervalDays = parseInt(customInterval, 10);
            if (nextIntervalDays > 0) {
                nextTaskDate.addDays(nextIntervalDays);
            } else {
                gs.error("Invalid custom interval value: " + customInterval);
                return;
            }
        }

        // Stop task creation if next due date exceeds end date
        if (endDate && nextTaskDate.compareTo(endDate) > 0) {
            gs.info("Next due date exceeds end date. Task creation stopped.");
            return;
        }

        gs.info("Next task due on: " + nextTaskDate.getDisplayValue() + " for definition: " + taskName);

        // Create a new task
        var task = new GlideRecord("u_scheduled_activity_task");
        task.initialize();
        task.setValue("short_description", taskName);
        task.setValue("description", taskDesc);
        task.setValue("assigned_to", assignedTo);
        task.setValue("due_date", nextTaskDue);
        task.setValue("u_end_date", endDate);
        task.setValue("assignment_group", assignmentGroup);
        task.setValue("u_activity_defintion", definitionRecord.getUniqueValue());

        var taskID = task.insert();

        if (taskID) {
            gs.eventQueue("task.reminder.created", task, task.assigned_to, task.short_description);
            gs.info("Task created with ID: " + taskID + " and due date: " + nextTaskDue.getDisplayValue());
        } else {
            gs.error("Task insertion failed for due date: " + nextTaskDue.getDisplayValue());
        }

       
        gs.info("Updating next task due date to: " + nextTaskDate.getDisplayValue());
        definitionRecord.setValue("u_next_task_due", nextTaskDate);
        definitionRecord.update();

        // Trigger event if today is the end date 
        if (endDate && today.getDate().getByFormat("yyyy-MM-dd") === endDate.getDate().getByFormat("yyyy-MM-dd")) {
            gs.eventQueue("task.expiring.soon",definitionRecord, assignedTo, taskName);
            gs.info("Successfully triggered task.expiring.soon event for definition: " + taskName + " with end date: " + endDate.getDisplayValue());
        }
    },

    type: 'GenerateTaskTest'
};

 

 

My issue is if i create a definition record with start date 07/03/25 with re occurance pattern weekly the next task due date field should be set to 14/03/25 (as it is a week from now). Why is it set to 13/03/25?? I think might be due to a timezone issue but i cant figure it out. 

 

Can someone please help! #script #schedulejob #scriptinclude

1 REPLY 1

Medi C
Giga Sage

Hi @Nabilah,

 

Please use setValue instead of setDisplayValue when setting your dates and use addWeeksUTC instead of addWeeks:

 

Example:

var gdt = new GlideDateTime();
gdt.setValue(new GlideDate() + " 00:00:00");
gs.info("Current Date: " + gdt);
gdt.addWeeksUTC(1)
gs.info("Next Week Date: " + gdt);

 

Results:

*** Script: Current Date: 2025-03-09 00:00:00
*** Script: Next Week Date: 2025-03-16 00:00:00

 

 


Thanks & Best regards,
Medi