Business Rule Query

Joshuu
Kilo Sage

Hi All,

 

I have a query in a business rule.

 

so basically, we have a field called Maintenance window (list type) on the Change form which is reference to scheduled entries table. 

 

priyarao_0-1727799705003.png

 

1) Whenever user selects planned start date (time) and Planned end date (time) from change request and it will compare with start date time and end date time and Repeat on fields from above shown schedule entries table.

 

2 ) Also, any business service from change form 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'

 

Then if anything overlaps, we are populating the output in the maintenance field.

 

Example 1: As per the planned date and end date is selected also the business service, it should show below 2 scheduled entries as no keyword is selected in the business service. 

Availability ESB Maintenance Window

Concerto Maintenance Window

 

priyarao_2-1727801475689.png

 

Example 2: It should show only Availability ESB Maintenance Window and hide Concerto Maintenance Window from maintenance window field since Concerto choice is selected in the business service.

 

 

priyarao_4-1727801560840.png

And the script:

 

(function executeRule(current, previous /*null when async*/ ) {
    var arr = [];
    var uniqueSchedules = {};
    var matched = false; // Flag to track if we found a keyword match

    current.setValue('u_maintainence_window', '');

    if (current.u_business_service.u_priority == 'T1' && current.u_environment == 'production') {

        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 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();

                // 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);

 

Could you please check and help me what needs to be changed in this script.

 

Thank you,

Best Regards.

2 REPLIES 2

Siddhesh Jadhav
Kilo Sage

Hi @Joshuu ,

 

Your logic looks mostly correct, but you can optimize a few parts:

1. Reset `matched` flag in each loop: Move `matched = false;` inside the loop where you check business services, so it resets for each service.

2. Avoid skipping maintenance windows after a match: Instead of `continue` inside the inner loop, you can conditionally push the windows to `arr` only if they don't match the keyword.

3. Fix the `matched` check: The check for `!matched` might need reworking to ensure unmatched services still populate all windows.

 

(function executeRule(current, previous /*null when async*/) {
    var arr = [];
    var uniqueSchedules = {};

    current.setValue('u_maintainence_window', '');

    if (current.u_business_service.u_priority == 'T1' && current.u_environment == 'production') {
        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 onlycrstarttime = crstart.split(" ")[1];
        var onlycrendtime = crend.split(" ")[1];

        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 endmaint = gr.getDisplayValue('end_date_time');
            var starttimeonlymaint = startmaint.split(" ")[1];
            var endtimeonlymaint = endmaint.split(" ")[1];

            if ((onlycrstarttime < starttimeonlymaint && starttimeonlymaint < onlycrendtime) ||
                (onlycrstarttime < endtimeonlymaint && endtimeonlymaint < onlycrendtime) || 
                (starttimeonlymaint < onlycrstarttime && onlycrstarttime < endtimeonlymaint) ||
                (starttimeonlymaint < onlycrendtime && onlycrendtime < endtimeonlymaint)) {
                
                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'];
                var keywordList = ['B2B', 'B2C', 'RES ESB', 'IRIS', 'Loyalty', 'Availability ESB', 'Concerto', 'Network'];
                var businessServices = current.u_business_service.name.split(',');

                for (var i = 0; i < businessServices.length; i++) {
                    var service = businessServices[i].trim();
                    var matched = false;

                    for (var j = 0; j < keywordList.length; j++) {
                        if (service.includes(keywordList[j])) {
                            matched = true;

                            for (var k = 0; k < maintenanceWindows.length; k++) {
                                if (!maintenanceWindows[k].includes(keywordList[j]) && !uniqueSchedules[maintenanceWindows[k]]) {
                                    arr.push(maintenanceWindows[k]);
                                    uniqueSchedules[maintenanceWindows[k]] = true;
                                }
                            }
                        }
                    }
                }

                if (!matched) {
                    for (var k = 0; k < maintenanceWindows.length; k++) {
                        if (!uniqueSchedules[maintenanceWindows[k]]) {
                            arr.push(maintenanceWindows[k]);
                            uniqueSchedules[maintenanceWindows[k]] = true;
                        }
                    }
                }

                current.u_maintainence_window = arr.join(',');
            }
        }
    }
})(current, previous);

This will reset the `matched` flag inside each business service loop and conditionally add maintenance windows based on matches.

 

Best regards,
Siddhesh Jadhav

If this is helpful, please mark the response as helpful and accepted.

Hi @Siddhesh Jadhav ,

 

Thank you very much for your response.

 

But I can see the same output after updating the code.