← Script library

Business Rules

Cascade Update to Child Records

Automatically update related child records when parent record changes, maintaining data consistency across relationships.

JavaScript
(function executeRule(current, previous /*null when async*/) {

  // Configuration: Define which fields trigger cascade updates
  var cascadeFields = {
    'priority': true,        // Cascade priority changes to tasks
    'assignment_group': true, // Cascade assignment group to tasks
    'state': false,          // Don't cascade state (could be handled differently)
    'category': true         // Cascade category to tasks
  };

  // Track which fields changed and should cascade
  var fieldsToUpdate = [];

  // Check which configured fields changed
  Object.keys(cascadeFields).forEach(function(fieldName) {
    if (cascadeFields[fieldName] && current[fieldName].changes()) {
      fieldsToUpdate.push(fieldName);
    }
  });

  // Exit if no relevant fields changed
  if (fieldsToUpdate.length === 0) {
    return;
  }

  try {
    // Find related child records (incident tasks)
    var grTask = new GlideRecord('incident_task');
    grTask.addQuery('incident', current.sys_id);
    grTask.addQuery('active', 'true');  // Only update active tasks
    grTask.query();

    var updatedCount = 0;

    while (grTask.next()) {
      var shouldUpdate = false;

      // Update each changed field
      fieldsToUpdate.forEach(function(fieldName) {
        var newValue = current.getValue(fieldName);

        // Only update if task value is different
        if (grTask.getValue(fieldName) !== newValue) {
          grTask.setValue(fieldName, newValue);
          shouldUpdate = true;
        }
      });

      // Save if any fields were updated
      if (shouldUpdate) {
        // Add work note to document cascade update
        grTask.work_notes = 'Automatically updated from parent incident ' + 
                           current.number + '. Fields updated: ' + 
                           fieldsToUpdate.join(', ');

        // Update without triggering business rules to prevent loops
        grTask.setWorkflow(false);
        grTask.autoSysFields(false);  // Don't update sys_updated_by/on
        grTask.update();

        updatedCount++;
      }
    }

    if (updatedCount > 0) {
      gs.info('Cascade update: Updated ' + updatedCount + ' tasks for incident ' + 
              current.number + '. Fields: ' + fieldsToUpdate.join(', '));

      // Optional: Add work note to parent incident
      current.work_notes = 'Cascaded updates to ' + updatedCount + ' related tasks';
      current.setWorkflow(false);
      current.update();
    }

    // Example 2: Cascade to related changes
    // Uncomment if you need to cascade to related change requests
    /*
    var grRelChange = new GlideRecord('change_request');
    grRelChange.addQuery('u_related_incident', current.sys_id);
    grRelChange.addQuery('state', 'NOT IN', '-5,3,4');  // Not closed/cancelled
    grRelChange.query();

    while (grRelChange.next()) {
      if (cascadeFields.priority && current.priority.changes()) {
        grRelChange.priority = current.priority;
        grRelChange.work_notes = 'Priority updated from related incident ' + current.number;
        grRelChange.setWorkflow(false);
        grRelChange.update();
      }
    }
    */

    // Example 3: Cascade to child incidents (parent-child relationship)
    /*
    if (current.getValue('parent_incident')) {
      var grChild = new GlideRecord('incident');
      grChild.addQuery('parent_incident', current.sys_id);
      grChild.addQuery('active', 'true');
      grChild.query();

      while (grChild.next()) {
        // Cascade specific fields to child incidents
        if (cascadeFields.assignment_group && current.assignment_group.changes()) {
          grChild.assignment_group = current.assignment_group;
          grChild.work_notes = 'Assignment group inherited from parent ' + current.number;
          grChild.setWorkflow(false);
          grChild.update();
        }
      }
    }
    */

  } catch (e) {
    gs.error('Cascade update BR error for incident ' + current.number + ': ' + e.message);
  }

})(current, previous);

How to use it

1. Create an after Business Rule on parent table 2. Check only "Update" checkbox 3. Configure which fields should cascade in cascadeFields object 4. Identify child table(s) and relationship field 5. Test with parent record updates 6. Verify child records are updated correctly 7. Monitor for potential infinite loops 8. Use setWorkflow(false) to prevent triggering child BRs 9. Document cascade behavior for users

Adapt the table names, fields, and conditions to your instance. Test the behavior in a development environment before using it in production.