- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-09-2024 01:13 PM
Hello Community,
I need some help with below code.
Requirement: Populate Due date on SC Task records from delivery time (in Business days) specified on catalog item.
I have created below script, it is working as expected however i need to account for just business days.
So if a request is created today for "Ask a Question" item with delivery date (5 business days), due date on task should be July 16th.
Before insert >> Condition - Item.delivery_time is not empty
Script:
var intDuration = current.cat_item.delivery_time.dateNumericValue();
var gdtDueDate = new GlideDateTime();
gdtDueDate.add(intDuration);
current.due_date = gdtDueDate;
current.update();
Please advise,
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-10-2024 06:30 AM
Hello @dvelloriy ,
Here is the updated code. Give it a try.
(function executeRule(current, previous /*null when async*/ ) {
// Add your code here
var duration = parseInt(current.cat_item.delivery_time.getDisplayValue());
var todayDate = new GlideDateTime();
var dueDate = addDays(todayDate, duration);
current.due_date = dueDate;
function addDays(todayDate, duration) {
var count = 0;
var gdt = new GlideDateTime(todayDate);
while (count < duration) {
gdt.addDaysLocalTime(1);
var dayWeek = gdt.getDayOfWeekLocalTime();
if (dayWeek != 6 && dayWeek != 7) { // 6 = Saturday, 7 = Sunday
count++;
}
}
return gdt;
}
})(current, previous);
If this response resolves your query, kindly mark it as both helpful and correct.
Thanks,
Alka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-09-2024 04:21 PM
Hello @dvelloriy ,
Please try the code below in your script. It will add the delivery time (business days only) to today's date.
(function executeRule(current, previous /*null when async*/) {
// Add your code here
var days = parseInt(current.cat_item.delivery_time.getDisplayValue());
var getDueDate = new GlideDateTime();
var duration = new GlideDuration(1000*60*60*8*days);
var schedule = new GlideSchedule('08fcd0830a0a0b2600079f56b1adb9ae');//8-5 weekdays Schedule sys id
var dueDate = schedule.add(getDueDate,duration);
current.due_date = dueDate;
})(current, previous);
If this response resolves your query, kindly mark it as both helpful and correct.
Thanks,
Alka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-10-2024 06:15 AM
Hi Alka,
Results are better now but not accurate.
I just created a request with catalog item having delivery time of 2 business days.
due date on task came as 07/11/2024 16:10:54
Ideally if its 2 business days, and i am creating the request now,
it should come as 07/12/2024 9:10:54
Please advise. i think we might have to update the schedule..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-10-2024 06:30 AM
Hello @dvelloriy ,
Here is the updated code. Give it a try.
(function executeRule(current, previous /*null when async*/ ) {
// Add your code here
var duration = parseInt(current.cat_item.delivery_time.getDisplayValue());
var todayDate = new GlideDateTime();
var dueDate = addDays(todayDate, duration);
current.due_date = dueDate;
function addDays(todayDate, duration) {
var count = 0;
var gdt = new GlideDateTime(todayDate);
while (count < duration) {
gdt.addDaysLocalTime(1);
var dayWeek = gdt.getDayOfWeekLocalTime();
if (dayWeek != 6 && dayWeek != 7) { // 6 = Saturday, 7 = Sunday
count++;
}
}
return gdt;
}
})(current, previous);
If this response resolves your query, kindly mark it as both helpful and correct.
Thanks,
Alka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
07-10-2024 06:49 AM
// Calculate due date (same logic as before)
var intDuration = current.cat_item.delivery_time.dateNumericValue();
var gdtDueDate = new GlideDateTime();
var businessDaysToAdd = Math.ceil(intDuration / (1000 * 60 * 60 * 24));
while (businessDaysToAdd > 0) {
gdtDueDate.addDays(1);
if (!gs.isWeekday(gdtDueDate)) {
continue;
}
businessDaysToAdd--;
}
// Consider holidays (if applicable)
var holidaySchedule = 'your_holiday_schedule_name';
while (new GlideSchedule(holidaySchedule).isInSchedule(gdtDueDate)) {
gdtDueDate.addDays(1);
}
// Set workflow to false before updating
current.setWorkflow(false);
current.due_date = gdtDueDate;
// Update the task record
current.update();
Explanation
1. Get Delivery Time: Same as before, we get the delivery time in milliseconds.
2. Convert to Business Days:
* Divide the milliseconds by the number of milliseconds in a day to get the total number of days.
* Use Math.ceil() to round up to the nearest whole number, ensuring we count partial days as full business days.
3. Iterate and Skip Weekends:
* Use a while loop to keep adding days until we've accounted for the required number of business days.
* Inside the loop:
* Add one day to the current gdtDueDate.
* Use gs.isWeekday(gdtDueDate) to check if the new date is a weekend.
* If it's a weekend, continue skips to the next iteration of the loop without decrementing businessDaysToAdd.
4. Account for Holidays (Optional):
* Replace 'your_holiday_schedule_name' with the name of the schedule you've created in ServiceNow to define your organization's holidays.
* Use a while loop and isInSchedule() to check if the date falls on a holiday. If it does, increment the date until it's not a holiday.
5. Set Due Date: Assign the final calculated gdtDueDate to the current.due_date field and update the record.
Explanation of Changes
The only change made in this script is the addition of the line current.setWorkflow(false); right before the current.update() line.
Here's why this is important:
Isolates Update: By setting current.setWorkflow(false), we ensure that the subsequent update (current.update()) is performed in isolation from the workflow context.
Prevents Conflicts: This prevents the update from triggering any other business rules or workflows that might be associated with the task table.
Ensures Accuracy: It guarantees that the calculated due date is set correctly without interference from other processes.
Optimizes Performance: It's more efficient to make a single update after setting the due date and disabling the workflow, rather than updating multiple times within the workflow context.
Key Points to Remember
Scope: The setWorkflow(false) method only affects the current update operation. Subsequent actions in the script or workflow will operate normally.
Order: It's crucial to place current.setWorkflow(false) immediately before the current.update() line to ensure that the update itself is the only action performed outside the workflow context.
Completeness: If you need to make multiple changes to the record, do so before calling current.update(). Once the record is updated, the workflow context is restored, and subsequent updates will trigger business rules and workflows.