📤 Built a useful command? Submit it here — we'll review & add it to the library.

Assign RITM & Close SC Tasks

Hint: Assign the current RITM to you, then assign and close its open SC Tasks

Trigger: \closeritmtasks

(function() {
  var MY_SYS_ID = (window.g_user && g_user.userID) ? g_user.userID : '';
  if (!MY_SYS_ID) { alert('Could not detect the current user.'); return; }

  var match = decodeURIComponent(window.location.href).match(/sys_id[=%3D]+([a-f0-9]{32})/i);
  if (!match) { alert('Could not find a sys_id in the URL. Open an RITM record first.'); return; }
  var ritmSysId = match[1];

  var overlay = document.createElement('div');
  overlay.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.65);z-index:99999;display:flex;align-items:center;justify-content:center;font-family:sans-serif;';
  var box = document.createElement('div');
  box.style.cssText = 'background:#fff;border-radius:8px;padding:24px;width:560px;max-height:80vh;display:flex;flex-direction:column;box-shadow:0 4px 28px rgba(0,0,0,0.35);';
  var title = document.createElement('div');
  title.textContent = 'Processing RITM & SC Tasks...';
  title.style.cssText = 'font-size:16px;font-weight:bold;margin-bottom:12px;color:#1a1a1a;';
  var barWrap = document.createElement('div');
  barWrap.style.cssText = 'background:#e0e0e0;border-radius:4px;height:12px;margin-bottom:10px;overflow:hidden;';
  var bar = document.createElement('div');
  bar.style.cssText = 'background:#0070d2;height:100%;width:0%;transition:width 0.4s ease;';
  barWrap.appendChild(bar);
  var statusText = document.createElement('div');
  statusText.style.cssText = 'font-size:13px;color:#555;margin-bottom:10px;';
  statusText.textContent = 'Starting...';
  var log = document.createElement('div');
  log.style.cssText = 'flex:1;overflow-y:auto;font-size:12px;font-family:monospace;background:#f4f4f4;border-radius:4px;padding:8px;max-height:320px;';
  var btnRow = document.createElement('div');
  btnRow.style.cssText = 'display:flex;justify-content:flex-end;gap:8px;margin-top:14px;';
  var reloadBtn = document.createElement('button');
  reloadBtn.textContent = 'Reload Form';
  reloadBtn.style.cssText = 'padding:8px 20px;background:#0070d2;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:14px;display:none;';
  reloadBtn.onclick = function() { window.location.reload(); };
  var closeBtn = document.createElement('button');
  closeBtn.textContent = 'Close';
  closeBtn.style.cssText = 'padding:8px 20px;background:#555;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:14px;display:none;';
  closeBtn.onclick = function() { document.body.removeChild(overlay); window.location.reload(); };
  btnRow.appendChild(reloadBtn); btnRow.appendChild(closeBtn);
  box.appendChild(title); box.appendChild(barWrap); box.appendChild(statusText); box.appendChild(log); box.appendChild(btnRow);
  overlay.appendChild(box); document.body.appendChild(overlay);

  function addLog(msg, color) { var line = document.createElement('div'); line.style.color = color || '#333'; line.textContent = msg; log.appendChild(line); log.scrollTop = log.scrollHeight; }
  function setProgress(pct, status) { bar.style.width = pct + '%'; statusText.textContent = status; }
  function patchRecord(table, sysId, payload, onSuccess, onFail) {
    var xhr = new XMLHttpRequest();
    xhr.open('PATCH', '/api/now/table/' + table + '/' + sysId, true);
    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.setRequestHeader('Accept', 'application/json');
    xhr.setRequestHeader('X-UserToken', window.g_ck);
    xhr.onload = function() { if (xhr.status === 200) onSuccess(JSON.parse(xhr.responseText).result); else onFail(xhr.status); };
    xhr.onerror = function() { onFail('network'); };
    xhr.send(JSON.stringify(payload));
  }
  function finish(success) {
    setProgress(100, success ? 'All done.' : 'Completed with errors.');
    title.textContent = success ? 'Done' : 'Completed with errors';
    reloadBtn.style.display = 'block'; closeBtn.style.display = 'block';
  }

  // Step 1: assign the RITM to me
  addLog('Step 1: Assigning RITM to me...', '#0070d2');
  setProgress(10, 'Assigning RITM...');
  patchRecord('sc_req_item', ritmSysId, { assigned_to: MY_SYS_ID }, function(ritmResult) {
    addLog('RITM ' + (ritmResult.number || ritmSysId) + ' assigned to me.', '#2e7d32');
    setProgress(25, 'Fetching open SC Tasks...');

    // Step 2: fetch open SC Tasks under this RITM
    var taskQuery = 'request_item=' + ritmSysId + '^active=true^state!=4^state!=7';
    var fetchUrl = '/api/now/table/sc_task?sysparm_query=' + encodeURIComponent(taskQuery) + '&sysparm_fields=sys_id,number,state&sysparm_limit=50';
    var fXhr = new XMLHttpRequest();
    fXhr.open('GET', fetchUrl, true);
    fXhr.setRequestHeader('Accept', 'application/json');
    fXhr.setRequestHeader('X-UserToken', window.g_ck);
    fXhr.onload = function() {
      if (fXhr.status !== 200) { addLog('Failed to fetch SC Tasks (HTTP ' + fXhr.status + ')', '#c62828'); finish(false); return; }
      var tasks = JSON.parse(fXhr.responseText).result;
      addLog('Found ' + tasks.length + ' open SC Task(s).', tasks.length ? '#2e7d32' : '#888');
      if (!tasks.length) { addLog('No open SC Tasks. RITM assigned. Done.', '#888'); finish(true); return; }
      setProgress(40, 'Assigning & closing SC Tasks...');

      // Step 3: assign then close each SC Task
      var idx = 0, successCount = 0, failCount = 0;
      function processNextTask() {
        if (idx >= tasks.length) {
          bar.style.width = '90%';
          addLog('Closed: ' + successCount + (failCount ? ('   Failed: ' + failCount) : ''), '#0070d2');
          finish(true); return;
        }
        var task = tasks[idx];
        var taskNum = task.number || task.sys_id;
        setProgress(40 + Math.round((idx / tasks.length) * 50), 'Processing ' + taskNum);
        patchRecord('sc_task', task.sys_id, { assigned_to: MY_SYS_ID }, function() {
          patchRecord('sc_task', task.sys_id, { state: '3', close_notes: 'Request Fulfilled' }, function() {
            addLog(taskNum + ' closed.', '#2e7d32'); successCount++; idx++; processNextTask();
          }, function(s) { addLog(taskNum + ' close failed (HTTP ' + s + ')', '#c62828'); failCount++; idx++; processNextTask(); });
        }, function(s) { addLog(taskNum + ' assign failed (HTTP ' + s + ')', '#c62828'); failCount++; idx++; processNextTask(); });
      }
      processNextTask();
    };
    fXhr.onerror = function() { addLog('Network error fetching SC Tasks.', '#c62828'); finish(false); };
    fXhr.send();
  }, function(status) { addLog('Failed to assign RITM (HTTP ' + status + ')', '#c62828'); finish(false); });
})();