indexOf in business rule
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-01-2024 01:35 AM
Hi All,
I have two fields on the change form as below
Business Service
Maintenance Window (this is a list type field and taking values from scheduled entries table)
Whenever user selects any business service which is having below keywords, it should check the maintenance field values and skip the related choices.
'B2B', 'B2C', 'RES ESB', 'IRIS', 'Loyalty', 'Availability ESB', 'Concerto', 'Network'
From the below example, I have selected 'Loyalty Admin UI' as business service.
So, from the maintenance window field it should hide/remove below choices and populate remaining choices.
Loyalty Maintenance Window - PM,
Loyalty Maintenance Window - AM
And if user selects any other choice as business service apart from the above-mentioned keywords it should populate all the values in the maintenance window field.
Could you please check my below script and correct me if I am wrong.
Script:
(function executeRule(current, previous /*null when async*/ ) {
var arr = [];
var uniqueSchedules = {};
var x = ['Availability ESB Maintenance Window', 'B2B Maintenance Window', 'B2C Web Maintenance Window', 'Concerto Maintenance Window', 'Network/Infrastructure Maintenance Window', 'Network Maintenance Window', 'Network Firewall Maintenance', 'Loyalty Maintenance Window - PM', 'Loyalty Maintenance Window - AM', 'IRIS Weekly Maintenance Window', 'RES ESB Maintenance Window'];
var y = current.u_business_service.name.split(',');
var z = ['B2B', 'B2C', 'RES ESB', 'IRIS', 'Loyalty', 'Availability ESB', 'Concerto', 'Network'];
for (var j = 0; j < z.length; j++) {
if (z[j].indexOf(y.toString()) == -1) {
arr.push(z[j]);
gs.log("Print Y: " + y.toString());
if (!uniqueSchedules.hasOwnProperty(x)) {
uniqueSchedules[x] = true; // Mark schedule name as seen
for (var i = 0; i < x.length; i++) {
if (x[i].indexOf(z.toString()) == -1) {
arr.push(x[i]);
}
}
current.u_maintainence_window = arr.join(',');
}
}
}
})(current, previous);
Output:
Please assist.
Best Regards.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-01-2024 04:53 AM
Hi @Joshuu ,
Please try adding a flag to check if they are matching the keywords and if they are not matching the keywords then write "else" condition.
(function executeRule(current, previous /*null when async*/ ) {
var arr = [];
var uniqueSchedules = {};
var matched = false; // Flag to track if we found a keyword match
// Maintenance windows
var maintenanceWindows = ['Availability ESB Maintenance Window', 'B2B Maintenance Window', 'B2C Web Maintenance Window', 'Concerto Maintenance Window', 'Network/Infrastructure Maintenance Window', 'Network Maintenance Window', 'Network Firewall Maintenance', 'Loyalty Maintenance Window - PM', 'Loyalty Maintenance Window - AM', 'IRIS Weekly Maintenance Window', 'RES ESB Maintenance Window'];
// Keywords to match against the selected Business Service
var keywordList = ['B2B', 'B2C', 'RES ESB', 'IRIS', 'Loyalty', 'Availability ESB', 'Concerto', 'Network'];
// Split the current business service name into an array of values
var businessServices = current.u_business_service.name.split(',');
// Loop through each business service
for (var i = 0; i < businessServices.length; i++) {
var service = businessServices[i].trim();
// Check if the current business service contains any keyword
for (var j = 0; j < keywordList.length; j++) {
if (service.includes(keywordList[j])) {
matched = true; // Set the flag to true if a keyword match is found
// If there's a match, filter out the related maintenance windows
for (var k = 0; k < maintenanceWindows.length; k++) {
if (maintenanceWindows[k].includes(keywordList[j])) {
// Skip the related maintenance windows (do not add them to the array)
gs.log("Skipping Maintenance Window: " + maintenanceWindows[k]);
continue;
}
// Add only the remaining maintenance windows to the arr[] (that are not skipped)
if (!uniqueSchedules.hasOwnProperty(maintenanceWindows[k])) {
arr.push(maintenanceWindows[k]);
uniqueSchedules[maintenanceWindows[k]] = true; // Mark schedule as added
}
}
}
}
}
// If no keyword matched, populate all maintenance windows
if (!matched) {
gs.log("No keyword match, populating all maintenance windows.");
for (var k = 0; k < maintenanceWindows.length; k++) {
if (!uniqueSchedules.hasOwnProperty(maintenanceWindows[k])) {
arr.push(maintenanceWindows[k]);
uniqueSchedules[maintenanceWindows[k]] = true; // Mark schedule as added
}
}
}
// Join the array into a comma-separated string and assign it to the field
current.u_maintainence_window = arr.join(',');
gs.log("Final Maintenance Windows: " + arr.join(','));
})(current, previous);
Please mark this solution as "Helpful" and "accepted solution" if this solution helped you in any way.
Thanks and Regards,
K. Sai Charan
Sr. ServiceNow Developer
Deloitte India
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-01-2024 10:17 AM
Hi @Sai_Charan_K ,
Thank you very much, it is working.
I have another query from the same script.
so basically, maintenance window field (list type) is reference to scheduled entries table.
It will check the planned start date (time) and Planned end date (time) from change request and compare it with start date time and end date time and Repeat on field from schedule entries.
It anything is overlaps we are populating the output in the maintenance field and also as a banner/error message in the change form.
Screenshot 1: As per the requirement, the day is selected Thursday in planned start date and end date. Based on the scheduled entries and also within time frame below 2 schedules should populate in the banner.
Availability ESB Maintenance Window
Concerto Maintenance Window
Here the output is correct. working as expected.
Screenshot2: Here, concerto has included in the business service so the same for loops conditions which we have applied for the maintenance window field should be applicable for the banner as well.
expected output: It should show only Availability ESB Maintenance Window and hide Concerto Maintenance Window from banner.
Screenshot 3: Here, the logic which we have written is working fine, but again it should show only the entries which we have for that day and based on planned start date and end date.
expected output: only should show below 2 scheduled entries as no keyword is selected in the business service.
Availability ESB Maintenance Window
Concerto Maintenance Window
Screenshot 4: Here it is hiding Concerto Maintenance Window and showing all other scheduled entries.
expected output: It should show only Availability ESB Maintenance Window and hide Concerto Maintenance Window from maintenance window field.
And the script:
(function executeRule(current, previous /*null when async*/ ) {
var startdate = current.start_date;
var crend = current.getDisplayValue('end_date');
var crstart = current.getDisplayValue('start_date');
var gdt = new GlideDateTime(startdate);
var dow = gdt.getDayOfWeek();
var endate = current.end_date;
var crstarttime = crstart.split(" ");
var onlycrstarttime = crstarttime[1];
var endgdt = new GlideDateTime(endate);
var crendtime = crend.split(" ");
var onlycrendtime = crendtime[1];
var arr = [];
var uniqueSchedules = {}; // Object to track unique schedule names
var matched = false;
current.setValue('u_maintainence_window', '');
if (current.u_business_service.u_priority == 'T1' && current.u_environment == 'production') {
var gr = new GlideRecord("cmn_schedule_span");
gr.addEncodedQuery('schedule.nameINAvailability ESB Maintenance Window,B2B Maintenance Window,B2C Web Maintenance Window,Concerto Maintenance Window,Network/Infrastructure Maintenance Window,Network Maintenance Window,Network Firewall Maintenance,Loyalty Maintenance Window - PM,Loyalty Maintenance Window - AM,IRIS Weekly Maintenance Window,RES ESB Maintenance Window');
gr.addEncodedQuery('days_of_weekCONTAINS' + dow);
gr.query();
while (gr.next()) {
var startmaint = gr.getDisplayValue('start_date_time');
var startdatetime = new GlideDateTime(startmaint);
var endmaint = gr.getDisplayValue('end_date_time');
var startonlymaint = startmaint.split(" ");
var endtimemaint = endmaint.split(" ");
var starttimeonlymaint = startonlymaint[1];
var endtimeonlymaint = endtimemaint[1];
var rec = [];
rec.push(gr.schedule.u_contacts);
var a = rec.join(',');
if ((onlycrstarttime < starttimeonlymaint && starttimeonlymaint < onlycrendtime) ||
(onlycrstarttime < endtimeonlymaint && endtimeonlymaint < onlycrendtime) || (starttimeonlymaint < onlycrstarttime && onlycrstarttime < endtimeonlymaint) ||
(starttimeonlymaint < onlycrendtime && onlycrendtime < endtimeonlymaint)) {
var scheduleName = gr.schedule.name.toString(); // Ensure schedule name is treated as string
// Maintenance windows
var maintenanceWindows = ['Availability ESB Maintenance Window', 'B2B Maintenance Window', 'B2C Web Maintenance Window', 'Concerto Maintenance Window', 'Network/Infrastructure Maintenance Window', 'Network Maintenance Window', 'Network Firewall Maintenance', 'Loyalty Maintenance Window - PM', 'Loyalty Maintenance Window - AM', 'IRIS Weekly Maintenance Window', 'RES ESB Maintenance Window'];
// Keywords to match against the selected Business Service
var keywordList = ['B2B', 'B2C', 'RES ESB', 'IRIS', 'Loyalty', 'Availability ESB', 'Concerto', 'Network'];
// Split the current business service name into an array of values
var businessServices = current.u_business_service.name.split(',');
// Loop through each business service
for (var i = 0; i < businessServices.length; i++) {
var service = businessServices[i].trim();
// Check if the current business service contains any keyword
for (var j = 0; j < keywordList.length; j++) {
if (service.includes(keywordList[j])) {
matched = true; // Set the flag to true if a keyword match is found
gs.log("Business Service matches keyword: " + keywordList[j]);
// If there's a match, filter out the related maintenance windows
for (var k = 0; k < maintenanceWindows.length; k++) {
if (maintenanceWindows[k].includes(keywordList[j])) {
// Skip the related maintenance windows (do not add them to the array)
gs.log("Skipping Maintenance Window: " + maintenanceWindows[k]);
continue;
}
// Add only the remaining maintenance windows to the arr[] (that are not skipped)
if (!uniqueSchedules.hasOwnProperty(maintenanceWindows[k])) {
arr.push(maintenanceWindows[k]);
uniqueSchedules[maintenanceWindows[k]] = true; // Mark schedule as added
}
}
}
}
}
if (!matched) {
gs.log("No keyword match, populating all maintenance windows.");
for (var k = 0; k < maintenanceWindows.length; k++) {
if (!uniqueSchedules.hasOwnProperty(maintenanceWindows[k])) {
arr.push(maintenanceWindows[k]);
uniqueSchedules[maintenanceWindows[k]] = true; // Mark schedule as added
}
}
}
// Join the array into a comma-separated string and assign it to the field
current.u_maintainence_window = arr.join(',');
gs.log("Final Maintenance Windows: " + arr.join(','));
var messageallnew = '<b><font size="3">"The defined Change Request window overlaps Maintenance Window,"</font></b>' +
'<b><font size="4">' + gr.schedule.name + '</font></b>' +
'<b><font size="3">"Coordinate with the Technical Manager"</font></b><br>' +
'<font size="3"><b>Primary Contact - ' + gr.schedule.u_pri_contact.getDisplayValue() + '</b></font><br>' +
'<font size="3"><b>Secondary Contact - ' + gr.schedule.u_ec_contact.getDisplayValue() + '</b></font>';
gs.addErrorMessage(messageallnew);
var link = '<a href="https://XXXXX.service-now.com/now/nav/ui/classic/params/target/cmn_schedule_span_list.do%3Fsysparm_query%3Dschedule.nameLIKEMaintenance%2520Window%26sysparm_first_row%3D1%26sysparm_view%3D%26sysparm_choice_query_raw%3D%26sysparm_list_header_search%3Dtrue">Maintenance Window</a>';
gs.addInfoMessage(link);
gs.log("RK | Schedule Message: " + gr.schedule.name);
gs.eventQueue("noifyownerofchngemaint", current, gr.schedule.name, rec);
}
}
}
})(current, previous);
Could you please check and let me know what needs to be changed in this script.
In short, the script which we have added today(for loops) should also applicable to banner message/error message as well. And the timing conditions should applicable for maintenance window field as well.
I hope I have not confused you. If you are ok, we will connect once if possible.
Thanks for all your help on this.
Best Regards.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-02-2024 09:25 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-01-2024 01:49 AM
Hi @Joshuu,
I don't think you need to split the 'Business Service' field since it's a reference field in your screenshot. It might work for you without splitting it.
Please mark my solution as Helpful and Accepted, if it works for you!
Thanks