Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎09-10-2025 08:58 PM
1 ACCEPTED SOLUTION
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎10-22-2025 01:19 AM
Is issue still open @munukuntlak
*************************************************************************************************************
If my response proves useful, please indicate its helpfulness by selecting " Accept as Solution" and " Helpful." This action benefits both the community and me.
Regards
Dr. Atul G. - Learn N Grow Together
ServiceNow Techno - Functional Trainer
LinkedIn: https://www.linkedin.com/in/dratulgrover
YouTube: https://www.youtube.com/@LearnNGrowTogetherwithAtulG
Topmate: https://topmate.io/atul_grover_lng [ Connect for 1-1 Session]
****************************************************************************************************************
If my response proves useful, please indicate its helpfulness by selecting " Accept as Solution" and " Helpful." This action benefits both the community and me.
Regards
Dr. Atul G. - Learn N Grow Together
ServiceNow Techno - Functional Trainer
LinkedIn: https://www.linkedin.com/in/dratulgrover
YouTube: https://www.youtube.com/@LearnNGrowTogetherwithAtulG
Topmate: https://topmate.io/atul_grover_lng [ Connect for 1-1 Session]
****************************************************************************************************************
25 REPLIES 25
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
javascript:
var env = current.variables.database_environment;
var app = current.variables.application_name;
if (!env) {
return 'sys_idISEMPTY';
}
return 'sys_idIN' + new DB_Provisioning_Util().getDatabases(app, env);
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2 weeks ago - last edited 2 weeks ago
// Background Script - Add Catalog Item to Update Set (Current User + Active Only)
// Using GlideUpdateManager2 (CORRECT METHOD)
(function() {
// CONFIGURATION - Change these values
var catalogItemSysId = 'YOUR_CATALOG_ITEM_SYS_ID'; // or use name
var catalogItemName = ''; // Alternative: use name instead of sys_id
var updateSetName = 'YOUR_UPDATE_SET_NAME'; // Specify your update set name
// Get current user
var currentUser = gs.getUserID();
gs.info('Current User: ' + gs.getUserName() + ' (' + currentUser + ')');
// Find the Update Set by name
var updateSetGR = new GlideRecord('sys_update_set');
updateSetGR.addQuery('name', updateSetName);
updateSetGR.addQuery('state', 'in progress');
updateSetGR.query();
if (!updateSetGR.next()) {
gs.error('Update Set not found or not in progress: ' + updateSetName);
return;
}
var updateSetId = updateSetGR.sys_id.toString();
gs.info('Using Update Set: ' + updateSetGR.name + ' (' + updateSetId + ')');
// Set this as the current update set for the session
gs.setCurrentUpdateSetId(updateSetId);
// Find catalog item
var catItem = new GlideRecord('sc_cat_item');
if (catalogItemSysId) {
catItem.get(catalogItemSysId);
} else if (catalogItemName) {
catItem.get('name', catalogItemName);
}
if (!catItem.isValidRecord()) {
gs.error('Catalog Item not found!');
return;
}
gs.info('Processing Catalog Item: ' + catItem.getDisplayValue());
// CORRECT Function to add record to update set
function addToUpdateSet(tableName, sysId) {
try {
var rec = new GlideRecord(tableName);
if (rec.get(sysId)) {
var um = new GlideUpdateManager2();
um.saveRecord(rec);
gs.info('✓ Added: ' + tableName + ' - ' + rec.getDisplayValue());
return true;
}
} catch (e) {
gs.error('Error adding ' + tableName + ': ' + e);
}
return false;
}
// Helper function to check if record was created/updated by current user
function isCurrentUserRecord(gr) {
var createdBy = gr.sys_created_by.toString();
var updatedBy = gr.sys_updated_by.toString();
return (createdBy == gs.getUserName() || updatedBy == gs.getUserName());
}
// Helper function to check if record is active (if active field exists)
function isActiveRecord(gr) {
if (gr.isValidField('active')) {
return gr.active == true || gr.active == 'true';
}
return true; // If no active field, consider it active
}
// Helper function to validate record before adding
function shouldAddRecord(gr) {
return isCurrentUserRecord(gr) && isActiveRecord(gr);
}
// 1. Add the Catalog Item itself (if created/updated by current user and active)
if (shouldAddRecord(catItem)) {
addToUpdateSet('sc_cat_item', catItem.sys_id);
}
// 2. Add Catalog Assignment (sc_cat_item_catalog)
var catalogAssignments = new GlideRecord('sc_cat_item_catalog');
catalogAssignments.addQuery('sc_cat_item', catItem.sys_id);
catalogAssignments.query();
gs.info('Found ' + catalogAssignments.getRowCount() + ' catalog assignments');
while (catalogAssignments.next()) {
if (shouldAddRecord(catalogAssignments)) {
addToUpdateSet('sc_cat_item_catalog', catalogAssignments.sys_id);
}
}
// 3. Add Catalog Item Variables
var variables = new GlideRecord('item_option_new');
variables.addQuery('cat_item', catItem.sys_id);
variables.query();
gs.info('Found ' + variables.getRowCount() + ' variables');
while (variables.next()) {
if (shouldAddRecord(variables)) {
addToUpdateSet('item_option_new', variables.sys_id);
}
}
// 4. Add Variable Sets (if any)
var varSets = new GlideRecord('io_set_item');
varSets.addQuery('sc_cat_item', catItem.sys_id);
varSets.query();
while (varSets.next()) {
if (shouldAddRecord(varSets)) {
addToUpdateSet('io_set_item', varSets.sys_id);
// Add the variable set itself
if (varSets.variable_set) {
var varSetRecord = new GlideRecord('item_option_new_set');
if (varSetRecord.get(varSets.variable_set) && shouldAddRecord(varSetRecord)) {
addToUpdateSet('item_option_new_set', varSets.variable_set);
}
// Add variables within the set
var setVars = new GlideRecord('item_option_new');
setVars.addQuery('variable_set', varSets.variable_set);
setVars.query();
while (setVars.next()) {
if (shouldAddRecord(setVars)) {
addToUpdateSet('item_option_new', setVars.sys_id);
}
}
}
}
}
// 5. Add Catalog UI Policies
var uiPolicies = new GlideRecord('catalog_ui_policy');
uiPolicies.addQuery('catalog_item', catItem.sys_id);
uiPolicies.query();
gs.info('Found ' + uiPolicies.getRowCount() + ' UI Policies');
while (uiPolicies.next()) {
if (shouldAddRecord(uiPolicies)) {
addToUpdateSet('catalog_ui_policy', uiPolicies.sys_id);
// Add UI Policy Actions
var uiActions = new GlideRecord('catalog_ui_policy_action');
uiActions.addQuery('ui_policy', uiPolicies.sys_id);
uiActions.query();
while (uiActions.next()) {
if (shouldAddRecord(uiActions)) {
addToUpdateSet('catalog_ui_policy_action', uiActions.sys_id);
}
}
}
}
// 6. Add Catalog Client Scripts
var clientScripts = new GlideRecord('catalog_script_client');
clientScripts.addQuery('cat_item', catItem.sys_id);
clientScripts.query();
gs.info('Found ' + clientScripts.getRowCount() + ' Client Scripts');
while (clientScripts.next()) {
if (shouldAddRecord(clientScripts)) {
addToUpdateSet('catalog_script_client', clientScripts.sys_id);
}
}
// 7. Add Flow Designer Flow (if attached)
if (catItem.flow_designer_flow) {
var flowRecord = new GlideRecord('sys_hub_flow');
if (flowRecord.get(catItem.flow_designer_flow) && shouldAddRecord(flowRecord)) {
gs.info('Found Flow Designer Flow');
addToUpdateSet('sys_hub_flow', catItem.flow_designer_flow);
// Add Flow Actions
var flowActions = new GlideRecord('sys_hub_action_instance');
flowActions.addQuery('flow', catItem.flow_designer_flow);
flowActions.query();
gs.info('Found ' + flowActions.getRowCount() + ' flow actions');
while (flowActions.next()) {
if (shouldAddRecord(flowActions)) {
addToUpdateSet('sys_hub_action_instance', flowActions.sys_id);
}
}
// Add Flow Variables
var flowVars = new GlideRecord('sys_variable_value');
flowVars.addQuery('document', catItem.flow_designer_flow);
flowVars.addQuery('document_key', 'sys_hub_flow');
flowVars.query();
while (flowVars.next()) {
if (shouldAddRecord(flowVars)) {
addToUpdateSet('sys_variable_value', flowVars.sys_id);
}
}
// Add Flow Triggers
var flowTriggers = new GlideRecord('sys_hub_flow_trigger');
flowTriggers.addQuery('flow', catItem.flow_designer_flow);
flowTriggers.query();
while (flowTriggers.next()) {
if (shouldAddRecord(flowTriggers)) {
addToUpdateSet('sys_hub_flow_trigger', flowTriggers.sys_id);
}
}
}
}
// 8. Add Catalog Categories relationship
var categories = new GlideRecord('sc_cat_item_category');
categories.addQuery('sc_cat_item', catItem.sys_id);
categories.query();
gs.info('Found ' + categories.getRowCount() + ' category assignments');
while (categories.next()) {
if (shouldAddRecord(categories)) {
addToUpdateSet('sc_cat_item_category', categories.sys_id);
}
}
// 9. Add Record Producers (if it's a record producer)
if (catItem.sys_class_name == 'sc_cat_item_producer') {
var producer = new GlideRecord('sc_cat_item_producer');
if (producer.get(catItem.sys_id) && shouldAddRecord(producer)) {
addToUpdateSet('sc_cat_item_producer', producer.sys_id);
}
}
// 10. Add Execution Plans (if any)
var execPlans = new GlideRecord('sc_ic_item_staging');
execPlans.addQuery('cat_item', catItem.sys_id);
execPlans.query();
while (execPlans.next()) {
if (shouldAddRecord(execPlans)) {
addToUpdateSet('sc_ic_item_staging', execPlans.sys_id);
}
}
// 11. Add Catalog Item Tasks / Delivery Plans
var tasks = new GlideRecord('sc_cat_item_delivery_plan');
tasks.addQuery('sc_cat_item', catItem.sys_id);
tasks.query();
while (tasks.next()) {
if (shouldAddRecord(tasks)) {
addToUpdateSet('sc_cat_item_delivery_plan', tasks.sys_id);
}
}
// 12. Add Variable Choices (for choice lists)
var choices = new GlideRecord('question_choice');
choices.addQuery('question.cat_item', catItem.sys_id);
choices.query();
gs.info('Found ' + choices.getRowCount() + ' variable choices');
while (choices.next()) {
if (shouldAddRecord(choices)) {
addToUpdateSet('question_choice', choices.sys_id);
}
}
// 13. Add Legacy Workflow (if attached)
if (catItem.workflow) {
var workflowRecord = new GlideRecord('wf_workflow');
if (workflowRecord.get(catItem.workflow) && shouldAddRecord(workflowRecord)) {
gs.info('Found Legacy Workflow');
addToUpdateSet('wf_workflow', catItem.workflow);
var wfActivities = new GlideRecord('wf_activity');
wfActivities.addQuery('workflow', catItem.workflow);
wfActivities.query();
while (wfActivities.next()) {
if (shouldAddRecord(wfActivities)) {
addToUpdateSet('wf_activity', wfActivities.sys_id);
}
}
}
}
gs.info('===== COMPLETED =====');
gs.info('All catalog item components (created/updated by current user and active) added to update set: ' + updateSetName);
})();
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sunday
(function execute(inputs, outputs) {
var hasOverlap = false;
try {
var scheduleSpanRecord = inputs.schedule_span_record;
if (!scheduleSpanRecord) {
outputs.has_overlap = false;
return;
}
var newStartTime = new GlideDateTime();
newStartTime.setDisplayValue(inputs.start_time_to_compare);
var newEndTime = new GlideDateTime();
newEndTime.setDisplayValue(inputs.end_time_to_compare);
var newDaysNumeric = inputs.days_of_week || '';
var newDayNames = convertNumericDaysToNames(newDaysNumeric);
var existingStartStr = parseDateTime(scheduleSpanRecord.start_date_time);
var existingEndStr = parseDateTime(scheduleSpanRecord.end_date_time);
var existingStart = new GlideDateTime();
existingStart.setDisplayValue(existingStartStr);
var existingEnd = new GlideDateTime();
existingEnd.setDisplayValue(existingEndStr);
var existingAllDay = scheduleSpanRecord.all_day == 'true' || scheduleSpanRecord.all_day == true;
var existingDaysOfWeek = scheduleSpanRecord.days_of_week || '';
var existingRepeatType = scheduleSpanRecord.repeat_type || '';
var existingDayNames = [];
if (existingDaysOfWeek) {
existingDayNames = convertNumericDaysToNames(existingDaysOfWeek);
} else if (existingRepeatType) {
existingDayNames = extractDaysFromRepeatType(existingRepeatType);
} else {
existingDayNames = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
}
// Check time overlap
var timeStartBefore = newStartTime.before(existingEnd);
var timeEndAfter = newEndTime.after(existingStart);
var timeOverlaps = timeStartBefore && timeEndAfter;
if (!timeOverlaps) {
outputs.has_overlap = false;
return;
}
var commonDay = findCommonDay(newDayNames, existingDayNames);
var daysOverlap = commonDay !== null;
if (daysOverlap) {
hasOverlap = true;
}
outputs.has_overlap = hasOverlap;
} catch (ex) {
outputs.has_overlap = false;
}
function parseDateTime(dateTimeValue) {
if (!dateTimeValue) return '';
var dateTimeStr = String(dateTimeValue).trim();
if (dateTimeStr.indexOf('TZID=') === 0) {
var parts = dateTimeStr.split(';');
if (parts.length > 1) dateTimeStr = parts[1];
}
if (dateTimeStr.indexOf('T') > -1 && dateTimeStr.indexOf('-') === -1) {
var y = dateTimeStr.substring(0, 4);
var m = dateTimeStr.substring(4, 6);
var d = dateTimeStr.substring(6, 8);
var h = dateTimeStr.substring(9, 11);
var min = dateTimeStr.substring(11, 13);
var s = dateTimeStr.substring(13, 15);
dateTimeStr = y + '-' + m + '-' + d + ' ' + h + ':' + min + ':' + s;
}
return dateTimeStr;
}
function convertNumericDaysToNames(numericDays) {
var dayMap = {'1':'monday','2':'tuesday','3':'wednesday','4':'thursday','5':'friday','6':'saturday','7':'sunday'};
if (!numericDays) return ['monday','tuesday','wednesday','thursday','friday','saturday','sunday'];
var numericStr = String(numericDays);
var dayNumbers = numericStr.indexOf(',') > -1 ? numericStr.split(',') : numericStr.split('');
var dayNames = [];
for (var i = 0; i < dayNumbers.length; i++) {
var num = dayNumbers[i].trim();
if (dayMap[num]) dayNames.push(dayMap[num]);
}
return dayNames.length > 0 ? dayNames : ['monday','tuesday','wednesday','thursday','friday','saturday','sunday'];
}
function extractDaysFromRepeatType(repeatType) {
if (!repeatType || repeatType == 'NULL_OVERRIDE') {
return ['monday','tuesday','wednesday','thursday','friday','saturday','sunday'];
}
var allDays = ['monday','tuesday','wednesday','thursday','friday','saturday','sunday'];
var repeatStr = String(repeatType).toLowerCase();
if (repeatStr.indexOf('daily') > -1) return allDays;
var foundDays = [];
for (var i = 0; i < allDays.length; i++) {
if (repeatStr.indexOf(allDays[i]) > -1) foundDays.push(allDays[i]);
}
return foundDays.length > 0 ? foundDays : allDays;
}
function findCommonDay(days1, days2) {
if (!days1 || !days2 || days1.length == 0 || days2.length == 0) return 'all';
for (var i = 0; i < days1.length; i++) {
for (var j = 0; j < days2.length; j++) {
if (days1[i] == days2[j]) return days1[i];
}
}
return null;
}
})(inputs, outputs);
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Monday - last edited Tuesday
(function execute(inputs, outputs) {
// This checks for EXACT DUPLICATE weekly schedules
// Compares only: TIME (HH:MM format) and DAYS OF WEEK (no date comparison)
var isDuplicate = false;
try {
var scheduleSpanRecord = inputs.schedule_span_record;
if (!scheduleSpanRecord) {
outputs.has_overlap = false;
gs.info('DUPLICATE_DUPLICATE: no_record_provided');
return;
}
// Get input times (HH:MM format)
var newStartTime = inputs.start_time_to_compare || ''; // e.g., "08:00"
var newEndTime = inputs.end_time_to_compare || ''; // e.g., "17:00"
var newDaysNumeric = inputs.days_of_week || '';
var newDayNames = convertNumericDaysToNames(newDaysNumeric);
gs.info('DUPLICATE_DUPLICATE_INPUT: start_time=' + newStartTime + ', end_time=' + newEndTime + ', days=' + newDaysNumeric + '→' + newDayNames.join(','));
// Parse existing record - extract only TIME from datetime
var existingStartTime = extractTime(scheduleSpanRecord.start_date_time); // Extract HH:MM
var existingEndTime = extractTime(scheduleSpanRecord.end_date_time); // Extract HH:MM
var existingDaysOfWeek = scheduleSpanRecord.days_of_week || '';
var existingRepeatType = scheduleSpanRecord.repeat_type || '';
var existingName = scheduleSpanRecord.name || '';
// Get existing days
var existingDayNames = [];
if (existingDaysOfWeek) {
existingDayNames = convertNumericDaysToNames(existingDaysOfWeek);
} else if (existingRepeatType) {
existingDayNames = extractDaysFromRepeatType(existingRepeatType);
} else {
existingDayNames = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
}
gs.info('DUPLICATE_DUPLICATE_EXISTING: name=' + existingName + ', start_time=' + existingStartTime + ', end_time=' + existingEndTime + ', days=' + existingDaysOfWeek + '→' + existingDayNames.join(','));
// Normalize times to HH:MM format for comparison
var normalizedNewStart = normalizeTime(newStartTime);
var normalizedNewEnd = normalizeTime(newEndTime);
var normalizedExistingStart = normalizeTime(existingStartTime);
var normalizedExistingEnd = normalizeTime(existingEndTime);
// Check if start times match EXACTLY (HH:MM)
var startTimesMatch = normalizedNewStart === normalizedExistingStart;
// Check if end times match EXACTLY (HH:MM)
var endTimesMatch = normalizedNewEnd === normalizedExistingEnd;
// Check if days match EXACTLY (all days must be the same)
var daysMatch = arraysEqual(newDayNames.sort(), existingDayNames.sort());
gs.info('DUPLICATE_DUPLICATE_CHECK: start_time_match=' + startTimesMatch + ' (' + normalizedNewStart + '=' + normalizedExistingStart + '), end_time_match=' + endTimesMatch + ' (' + normalizedNewEnd + '=' + normalizedExistingEnd + '), days_match=' + daysMatch);
// It's a duplicate only if ALL three match (TIME + DAYS, no date check)
if (startTimesMatch && endTimesMatch && daysMatch) {
isDuplicate = true;
gs.warn('DUPLICATE_DUPLICATE_FOUND: exact_duplicate_of=' + existingName + ', matching_time=' + normalizedNewStart + '-' + normalizedNewEnd + ', matching_days=' + newDayNames.join(','));
} else {
var reason = [];
if (!startTimesMatch) reason.push('different_start_time(' + normalizedNewStart + '≠' + normalizedExistingStart + ')');
if (!endTimesMatch) reason.push('different_end_time(' + normalizedNewEnd + '≠' + normalizedExistingEnd + ')');
if (!daysMatch) reason.push('different_days(' + newDayNames.join(',') + '≠' + existingDayNames.join(',') + ')');
gs.info('DUPLICATE_DUPLICATE_RESULT: is_duplicate=false, reason=' + reason.join(','));
}
outputs.has_overlap = isDuplicate;
gs.info('DUPLICATE_DUPLICATE_FINAL: is_duplicate=' + isDuplicate);
} catch (ex) {
outputs.has_overlap = false;
gs.error('DUPLICATE_DUPLICATE_ERROR: ' + ex.message);
}
// Extract time (HH:MM) from various datetime formats
function extractTime(dateTimeValue) {
if (!dateTimeValue) return '';
var dateTimeStr = String(dateTimeValue).trim();
// Remove timezone prefix if present (TZID=US/Central;)
if (dateTimeStr.indexOf('TZID=') === 0) {
var parts = dateTimeStr.split(';');
if (parts.length > 1) dateTimeStr = parts[1];
}
// Handle compact format: 20250910T020000 → extract "02:00"
if (dateTimeStr.indexOf('T') > -1 && dateTimeStr.indexOf('-') === -1) {
// Format: YYYYMMDDTHHMMSS
var hour = dateTimeStr.substring(9, 11);
var minute = dateTimeStr.substring(11, 13);
return hour + ':' + minute;
}
// Handle standard format: "2025-09-10 02:00:00" → extract "02:00"
if (dateTimeStr.indexOf(' ') > -1) {
var timePart = dateTimeStr.split(' ')[1]; // Get time part after space
if (timePart) {
var timeComponents = timePart.split(':');
if (timeComponents.length >= 2) {
return timeComponents[0] + ':' + timeComponents[1]; // HH:MM
}
}
}
// If already in HH:MM or HH:MM:SS format, extract HH:MM
if (dateTimeStr.indexOf(':') > -1) {
var timeComponents2 = dateTimeStr.split(':');
if (timeComponents2.length >= 2) {
return timeComponents2[0] + ':' + timeComponents2[1];
}
}
return dateTimeStr;
}
// Normalize time to HH:MM format (ensure leading zeros)
function normalizeTime(timeStr) {
if (!timeStr) return '00:00';
timeStr = String(timeStr).trim();
// Split by colon
var parts = timeStr.split(':');
if (parts.length < 2) return timeStr;
var hour = parts[0].padStart(2, '0');
var minute = parts[1].padStart(2, '0');
return hour + ':' + minute;
}
// Convert numeric days to names: "1,3,5" or "135" → ["monday","wednesday","friday"]
function convertNumericDaysToNames(numericDays) {
var dayMap = {'1':'monday','2':'tuesday','3':'wednesday','4':'thursday','5':'friday','6':'saturday','7':'sunday'};
if (!numericDays) return ['monday','tuesday','wednesday','thursday','friday','saturday','sunday'];
var numericStr = String(numericDays);
var dayNumbers = numericStr.indexOf(',') > -1 ? numericStr.split(',') : numericStr.split('');
var dayNames = [];
for (var i = 0; i < dayNumbers.length; i++) {
var num = dayNumbers[i].trim();
if (dayMap[num]) dayNames.push(dayMap[num]);
}
return dayNames.length > 0 ? dayNames : ['monday','tuesday','wednesday','thursday','friday','saturday','sunday'];
}
// Extract days from repeat type
function extractDaysFromRepeatType(repeatType) {
if (!repeatType || repeatType == 'NULL_OVERRIDE') {
return ['monday','tuesday','wednesday','thursday','friday','saturday','sunday'];
}
var allDays = ['monday','tuesday','wednesday','thursday','friday','saturday','sunday'];
var repeatStr = String(repeatType).toLowerCase();
if (repeatStr.indexOf('daily') > -1) return allDays;
var foundDays = [];
for (var i = 0; i < allDays.length; i++) {
if (repeatStr.indexOf(allDays[i]) > -1) foundDays.push(allDays[i]);
}
return foundDays.length > 0 ? foundDays : allDays;
}
// Check if two arrays are exactly equal
function arraysEqual(arr1, arr2) {
if (arr1.length !== arr2.length) return false;
for (var i = 0; i < arr1.length; i++) {
if (arr1[i] !== arr2[i]) return false;
}
return true;
}
})(inputs, outputs);
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Wednesday
(function execute(inputs, outputs) {
// This checks for EXACT DUPLICATE weekly schedules with timezone conversion
// Compares: TIME (HH:MM in specified timezone) and DAYS OF WEEK
var isDuplicate = false;
try {
var scheduleSpanRecord = inputs.schedule_span_record;
if (!scheduleSpanRecord) {
outputs.has_overlap = false;
gs.info('ARUN_DUPLICATE: no_record_provided');
return;
}
// Get input values
var newStartTime = inputs.start_time_to_compare || ''; // e.g., "08:00"
var newEndTime = inputs.end_time_to_compare || ''; // e.g., "17:00"
var newDaysNumeric = inputs.days_of_week || '';
var newTimezone = inputs.timezone || 'US/Eastern'; // US/Eastern, US/Central, US/Pacific
var existingTimezone = inputs.existing_timezone || 'US/Eastern'; // Existing record's timezone
var newDayNames = convertNumericDaysToNames(newDaysNumeric);
gs.info('ARUN_DUPLICATE_INPUT: start_time=' + newStartTime + ', end_time=' + newEndTime + ', days=' + newDaysNumeric + '→' + newDayNames.join(',') + ', new_timezone=' + newTimezone + ', existing_timezone=' + existingTimezone);
// Parse existing record - extract TIME
var existingStartTimeRaw = scheduleSpanRecord.start_date_time.toString();
var existingEndTimeRaw = scheduleSpanRecord.end_date_time.toString();
var existingDaysOfWeek = scheduleSpanRecord.days_of_week || '';
var existingRepeatType = scheduleSpanRecord.repeat_type || '';
var existingName = scheduleSpanRecord.name || '';
// Extract time in existing timezone (no need to extract from TZID, using input)
var existingStartTimeInOwnTZ = extractTime(existingStartTimeRaw);
var existingEndTimeInOwnTZ = extractTime(existingEndTimeRaw);
// Convert existing times to input timezone for comparison
var existingStartTimeConverted = convertTimeToTimezone(existingStartTimeInOwnTZ, existingTimezone, newTimezone);
var existingEndTimeConverted = convertTimeToTimezone(existingEndTimeInOwnTZ, existingTimezone, newTimezone);
// Get existing days
var existingDayNames = [];
if (existingDaysOfWeek) {
existingDayNames = convertNumericDaysToNames(existingDaysOfWeek);
} else if (existingRepeatType) {
existingDayNames = extractDaysFromRepeatType(existingRepeatType);
} else {
existingDayNames = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
}
gs.info('ARUN_DUPLICATE_EXISTING: name=' + existingName + ', start_time=' + existingStartTimeInOwnTZ + ' (' + existingTimezone + '), end_time=' + existingEndTimeInOwnTZ + ' (' + existingTimezone + '), days=' + existingDaysOfWeek + '→' + existingDayNames.join(','));
gs.info('ARUN_DUPLICATE_CONVERTED: existing_start=' + existingStartTimeConverted + ' (' + newTimezone + '), existing_end=' + existingEndTimeConverted + ' (' + newTimezone + ')');
// Normalize times to HH:MM format for comparison
var normalizedNewStart = normalizeTime(newStartTime);
var normalizedNewEnd = normalizeTime(newEndTime);
var normalizedExistingStart = normalizeTime(existingStartTimeConverted);
var normalizedExistingEnd = normalizeTime(existingEndTimeConverted);
// Check if start times match EXACTLY (HH:MM in same timezone)
var startTimesMatch = normalizedNewStart === normalizedExistingStart;
// Check if end times match EXACTLY (HH:MM in same timezone)
var endTimesMatch = normalizedNewEnd === normalizedExistingEnd;
// Check if days match EXACTLY
var daysMatch = arraysEqual(newDayNames.sort(), existingDayNames.sort());
gs.info('ARUN_DUPLICATE_CHECK: start_time_match=' + startTimesMatch + ' (' + normalizedNewStart + '=' + normalizedExistingStart + '), end_time_match=' + endTimesMatch + ' (' + normalizedNewEnd + '=' + normalizedExistingEnd + '), days_match=' + daysMatch);
// It's a duplicate only if ALL three match
if (startTimesMatch && endTimesMatch && daysMatch) {
isDuplicate = true;
gs.warn('ARUN_DUPLICATE_FOUND: exact_duplicate_of=' + existingName + ', matching_time=' + normalizedNewStart + '-' + normalizedNewEnd + ' (' + newTimezone + '), matching_days=' + newDayNames.join(','));
} else {
var reason = [];
if (!startTimesMatch) reason.push('different_start_time(' + normalizedNewStart + '≠' + normalizedExistingStart + ')');
if (!endTimesMatch) reason.push('different_end_time(' + normalizedNewEnd + '≠' + normalizedExistingEnd + ')');
if (!daysMatch) reason.push('different_days(' + newDayNames.join(',') + '≠' + existingDayNames.join(',') + ')');
gs.info('ARUN_DUPLICATE_RESULT: is_duplicate=false, reason=' + reason.join(','));
}
outputs.has_overlap = isDuplicate;
gs.info('ARUN_DUPLICATE_FINAL: is_duplicate=' + isDuplicate);
} catch (ex) {
outputs.has_overlap = false;
gs.error('ARUN_DUPLICATE_ERROR: ' + ex.message);
}
// Extract timezone from datetime string (DEPRECATED - now using input parameter)
// Keeping for backward compatibility
function extractTimezone(dateTimeValue) {
if (!dateTimeValue) return 'US/Eastern';
var dateTimeStr = String(dateTimeValue).trim();
if (dateTimeStr.indexOf('TZID=') === 0) {
var parts = dateTimeStr.split(';');
if (parts.length > 0) {
var tzPart = parts[0].replace('TZID=', '');
return tzPart;
}
}
return 'US/Eastern';
}
// Extract time (HH:MM) from various datetime formats
function extractTime(dateTimeValue) {
if (!dateTimeValue) return '';
var dateTimeStr = String(dateTimeValue).trim();
// Remove timezone prefix if present
if (dateTimeStr.indexOf('TZID=') === 0) {
var parts = dateTimeStr.split(';');
if (parts.length > 1) dateTimeStr = parts[1];
}
// Handle compact format: 20250910T020000 → extract "02:00"
if (dateTimeStr.indexOf('T') > -1 && dateTimeStr.indexOf('-') === -1) {
var hour = dateTimeStr.substring(9, 11);
var minute = dateTimeStr.substring(11, 13);
return hour + ':' + minute;
}
// Handle standard format: "2025-09-10 02:00:00" → extract "02:00"
if (dateTimeStr.indexOf(' ') > -1) {
var timePart = dateTimeStr.split(' ')[1];
if (timePart) {
var timeComponents = timePart.split(':');
if (timeComponents.length >= 2) {
return timeComponents[0] + ':' + timeComponents[1];
}
}
}
// If already in HH:MM or HH:MM:SS format, extract HH:MM
if (dateTimeStr.indexOf(':') > -1) {
var timeComponents2 = dateTimeStr.split(':');
if (timeComponents2.length >= 2) {
return timeComponents2[0] + ':' + timeComponents2[1];
}
}
return dateTimeStr;
}
// Convert time from one timezone to another
function convertTimeToTimezone(timeStr, fromTZ, toTZ) {
if (!timeStr) return '00:00';
// If same timezone, no conversion needed
if (fromTZ === toTZ) {
return timeStr;
}
// Parse time
var timeParts = timeStr.split(':');
if (timeParts.length < 2) return timeStr;
var hour = parseInt(timeParts[0], 10);
var minute = parseInt(timeParts[1], 10);
// Timezone offset mapping (hours difference from UTC)
var tzOffsets = {
'US/Eastern': -5, // EST (UTC-5)
'US/Central': -6, // CST (UTC-6)
'US/Pacific': -8 // PST (UTC-8)
};
var fromOffset = tzOffsets[fromTZ] || -5;
var toOffset = tzOffsets[toTZ] || -5;
// Calculate hour difference
var hourDiff = toOffset - fromOffset;
// Apply conversion
var newHour = hour + hourDiff;
// Handle day wrap-around
if (newHour < 0) {
newHour += 24;
} else if (newHour >= 24) {
newHour -= 24;
}
return normalizeTime(newHour + ':' + minute);
}
// Normalize time to HH:MM format (ensure leading zeros)
function normalizeTime(timeStr) {
if (!timeStr) return '00:00';
timeStr = String(timeStr).trim();
var parts = timeStr.split(':');
if (parts.length < 2) return timeStr;
var hour = String(parts[0]);
var minute = String(parts[1]);
// Pad with leading zeros
if (hour.length === 1) hour = '0' + hour;
if (minute.length === 1) minute = '0' + minute;
return hour + ':' + minute;
}
// Convert numeric days to names: "1,3,5" or "135" → ["monday","wednesday","friday"]
function convertNumericDaysToNames(numericDays) {
var dayMap = {'1':'monday','2':'tuesday','3':'wednesday','4':'thursday','5':'friday','6':'saturday','7':'sunday'};
if (!numericDays) return ['monday','tuesday','wednesday','thursday','friday','saturday','sunday'];
var numericStr = String(numericDays);
var dayNumbers = numericStr.indexOf(',') > -1 ? numericStr.split(',') : numericStr.split('');
var dayNames = [];
for (var i = 0; i < dayNumbers.length; i++) {
var num = dayNumbers[i].trim();
if (dayMap[num]) dayNames.push(dayMap[num]);
}
return dayNames.length > 0 ? dayNames : ['monday','tuesday','wednesday','thursday','friday','saturday','sunday'];
}
// Extract days from repeat type
function extractDaysFromRepeatType(repeatType) {
if (!repeatType || repeatType == 'NULL_OVERRIDE') {
return ['monday','tuesday','wednesday','thursday','friday','saturday','sunday'];
}
var allDays = ['monday','tuesday','wednesday','thursday','friday','saturday','sunday'];
var repeatStr = String(repeatType).toLowerCase();
if (repeatStr.indexOf('daily') > -1) return allDays;
var foundDays = [];
for (var i = 0; i < allDays.length; i++) {
if (repeatStr.indexOf(allDays[i]) > -1) foundDays.push(allDays[i]);
}
return foundDays.length > 0 ? foundDays : allDays;
}
// Check if two arrays are exactly equal
function arraysEqual(arr1, arr2) {
if (arr1.length !== arr2.length) return false;
for (var i = 0; i < arr1.length; i++) {
if (arr1[i] !== arr2[i]) return false;
}
return true;
}
})(inputs, outputs);