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

 

 


If you found this helpful, please hit the thumbs-up button and mark as correct. That helps others find their solutions.