request-management

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Request Management for ServiceNow

ServiceNow 请求管理

Request Management handles service requests from catalog items through fulfillment.
请求管理负责处理从目录项到履行完成的全流程服务请求。

Request Hierarchy

请求层级

Request (sc_request)
    ├── Request Item (sc_req_item) - RITM
    │   ├── Catalog Tasks (sc_task)
    │   └── Variables (sc_item_option_mtom)
    └── Request Item
        └── Catalog Tasks
Request (sc_request)
    ├── Request Item (sc_req_item) - RITM
    │   ├── Catalog Tasks (sc_task)
    │   └── Variables (sc_item_option_mtom)
    └── Request Item
        └── Catalog Tasks

Key Tables

核心表

TablePurpose
sc_request
Parent request record
sc_req_item
Requested items (RITM)
sc_task
Fulfillment tasks
sc_item_option_mtom
Variable values
sc_cat_item
Catalog item definitions
表名用途
sc_request
父请求记录
sc_req_item
请求项(RITM)
sc_task
履行任务
sc_item_option_mtom
变量值
sc_cat_item
目录项定义

Request Items (ES5)

请求项(ES5)

Create Request Programmatically

以编程方式创建请求

javascript
// Create request and RITM (ES5 ONLY!)
function createServiceRequest(catalogItemName, requestedFor, variables) {
    // Get catalog item
    var catItem = new GlideRecord('sc_cat_item');
    if (!catItem.get('name', catalogItemName)) {
        gs.error('Catalog item not found: ' + catalogItemName);
        return null;
    }

    // Create request
    var request = new GlideRecord('sc_request');
    request.initialize();
    request.setValue('requested_for', requestedFor);
    request.setValue('opened_by', gs.getUserID());
    request.setValue('description', 'Request for ' + catalogItemName);
    var requestSysId = request.insert();

    // Create RITM
    var ritm = new GlideRecord('sc_req_item');
    ritm.initialize();
    ritm.setValue('request', requestSysId);
    ritm.setValue('cat_item', catItem.getUniqueValue());
    ritm.setValue('requested_for', requestedFor);
    ritm.setValue('quantity', 1);

    var ritmSysId = ritm.insert();

    // Set variables
    if (variables) {
        setRITMVariables(ritmSysId, variables);
    }

    return {
        request: request.getValue('number'),
        ritm: ritm.getValue('number'),
        request_sys_id: requestSysId,
        ritm_sys_id: ritmSysId
    };
}

function setRITMVariables(ritmSysId, variables) {
    var ritm = new GlideRecord('sc_req_item');
    if (!ritm.get(ritmSysId)) return;

    for (var varName in variables) {
        if (variables.hasOwnProperty(varName)) {
            ritm.variables[varName] = variables[varName];
        }
    }
    ritm.update();
}
javascript
// Create request and RITM (ES5 ONLY!)
function createServiceRequest(catalogItemName, requestedFor, variables) {
    // Get catalog item
    var catItem = new GlideRecord('sc_cat_item');
    if (!catItem.get('name', catalogItemName)) {
        gs.error('Catalog item not found: ' + catalogItemName);
        return null;
    }

    // Create request
    var request = new GlideRecord('sc_request');
    request.initialize();
    request.setValue('requested_for', requestedFor);
    request.setValue('opened_by', gs.getUserID());
    request.setValue('description', 'Request for ' + catalogItemName);
    var requestSysId = request.insert();

    // Create RITM
    var ritm = new GlideRecord('sc_req_item');
    ritm.initialize();
    ritm.setValue('request', requestSysId);
    ritm.setValue('cat_item', catItem.getUniqueValue());
    ritm.setValue('requested_for', requestedFor);
    ritm.setValue('quantity', 1);

    var ritmSysId = ritm.insert();

    // Set variables
    if (variables) {
        setRITMVariables(ritmSysId, variables);
    }

    return {
        request: request.getValue('number'),
        ritm: ritm.getValue('number'),
        request_sys_id: requestSysId,
        ritm_sys_id: ritmSysId
    };
}

function setRITMVariables(ritmSysId, variables) {
    var ritm = new GlideRecord('sc_req_item');
    if (!ritm.get(ritmSysId)) return;

    for (var varName in variables) {
        if (variables.hasOwnProperty(varName)) {
            ritm.variables[varName] = variables[varName];
        }
    }
    ritm.update();
}

Query Request Items

查询请求项

javascript
// Get user's open requests (ES5 ONLY!)
function getUserRequests(userSysId, includeCompleted) {
    var requests = [];

    var ritm = new GlideRecord('sc_req_item');
    ritm.addQuery('requested_for', userSysId);

    if (!includeCompleted) {
        ritm.addQuery('state', '!=', '3');  // Not Closed Complete
        ritm.addQuery('state', '!=', '4');  // Not Closed Incomplete
    }

    ritm.orderByDesc('sys_created_on');
    ritm.query();

    while (ritm.next()) {
        requests.push({
            sys_id: ritm.getUniqueValue(),
            number: ritm.getValue('number'),
            short_description: ritm.getValue('short_description'),
            cat_item: ritm.cat_item.getDisplayValue(),
            state: ritm.state.getDisplayValue(),
            stage: ritm.stage.getDisplayValue(),
            opened_at: ritm.getValue('sys_created_on'),
            due_date: ritm.getValue('due_date')
        });
    }

    return requests;
}
javascript
// Get user's open requests (ES5 ONLY!)
function getUserRequests(userSysId, includeCompleted) {
    var requests = [];

    var ritm = new GlideRecord('sc_req_item');
    ritm.addQuery('requested_for', userSysId);

    if (!includeCompleted) {
        ritm.addQuery('state', '!=', '3');  // Not Closed Complete
        ritm.addQuery('state', '!=', '4');  // Not Closed Incomplete
    }

    ritm.orderByDesc('sys_created_on');
    ritm.query();

    while (ritm.next()) {
        requests.push({
            sys_id: ritm.getUniqueValue(),
            number: ritm.getValue('number'),
            short_description: ritm.getValue('short_description'),
            cat_item: ritm.cat_item.getDisplayValue(),
            state: ritm.state.getDisplayValue(),
            stage: ritm.stage.getDisplayValue(),
            opened_at: ritm.getValue('sys_created_on'),
            due_date: ritm.getValue('due_date')
        });
    }

    return requests;
}

Fulfillment Tasks (ES5)

履行任务(ES5)

Create Catalog Tasks

创建目录任务

javascript
// Create fulfillment tasks for RITM (ES5 ONLY!)
function createFulfillmentTasks(ritmSysId, taskDefinitions) {
    var ritm = new GlideRecord('sc_req_item');
    if (!ritm.get(ritmSysId)) {
        return [];
    }

    var createdTasks = [];

    for (var i = 0; i < taskDefinitions.length; i++) {
        var taskDef = taskDefinitions[i];

        var task = new GlideRecord('sc_task');
        task.initialize();
        task.setValue('request_item', ritmSysId);
        task.setValue('request', ritm.getValue('request'));
        task.setValue('short_description', taskDef.description);
        task.setValue('assignment_group', taskDef.assignmentGroup);
        task.setValue('order', (i + 1) * 100);

        // Calculate due date if specified
        if (taskDef.daysToComplete) {
            var dueDate = new GlideDateTime();
            dueDate.addDaysLocalTime(taskDef.daysToComplete);
            task.setValue('due_date', dueDate);
        }

        var taskSysId = task.insert();
        createdTasks.push({
            sys_id: taskSysId,
            number: task.getValue('number')
        });
    }

    return createdTasks;
}

// Example usage
var tasks = createFulfillmentTasks(ritmSysId, [
    { description: 'Verify request details', assignmentGroup: 'Service Desk', daysToComplete: 1 },
    { description: 'Provision access', assignmentGroup: 'IAM Team', daysToComplete: 2 },
    { description: 'Notify user', assignmentGroup: 'Service Desk', daysToComplete: 1 }
]);
javascript
// Create fulfillment tasks for RITM (ES5 ONLY!)
function createFulfillmentTasks(ritmSysId, taskDefinitions) {
    var ritm = new GlideRecord('sc_req_item');
    if (!ritm.get(ritmSysId)) {
        return [];
    }

    var createdTasks = [];

    for (var i = 0; i < taskDefinitions.length; i++) {
        var taskDef = taskDefinitions[i];

        var task = new GlideRecord('sc_task');
        task.initialize();
        task.setValue('request_item', ritmSysId);
        task.setValue('request', ritm.getValue('request'));
        task.setValue('short_description', taskDef.description);
        task.setValue('assignment_group', taskDef.assignmentGroup);
        task.setValue('order', (i + 1) * 100);

        // Calculate due date if specified
        if (taskDef.daysToComplete) {
            var dueDate = new GlideDateTime();
            dueDate.addDaysLocalTime(taskDef.daysToComplete);
            task.setValue('due_date', dueDate);
        }

        var taskSysId = task.insert();
        createdTasks.push({
            sys_id: taskSysId,
            number: task.getValue('number')
        });
    }

    return createdTasks;
}

// Example usage
var tasks = createFulfillmentTasks(ritmSysId, [
    { description: 'Verify request details', assignmentGroup: 'Service Desk', daysToComplete: 1 },
    { description: 'Provision access', assignmentGroup: 'IAM Team', daysToComplete: 2 },
    { description: 'Notify user', assignmentGroup: 'Service Desk', daysToComplete: 1 }
]);

Auto-close RITM on Task Completion

任务完成后自动关闭RITM

javascript
// Business Rule: after, update, sc_task (ES5 ONLY!)
(function executeRule(current, previous) {
    // Check if task was just closed
    if (current.state.changesTo('3') || current.state.changesTo('4')) {
        checkAndCloseRITM(current.getValue('request_item'));
    }
})(current, previous);

function checkAndCloseRITM(ritmSysId) {
    // Check if all tasks are complete
    var openTasks = new GlideAggregate('sc_task');
    openTasks.addQuery('request_item', ritmSysId);
    openTasks.addQuery('state', 'NOT IN', '3,4,7');  // Not closed or cancelled
    openTasks.addAggregate('COUNT');
    openTasks.query();

    if (openTasks.next()) {
        var count = parseInt(openTasks.getAggregate('COUNT'), 10);
        if (count === 0) {
            // All tasks complete, close RITM
            var ritm = new GlideRecord('sc_req_item');
            if (ritm.get(ritmSysId)) {
                ritm.state = 3;  // Closed Complete
                ritm.update();
            }
        }
    }
}
javascript
// Business Rule: after, update, sc_task (ES5 ONLY!)
(function executeRule(current, previous) {
    // Check if task was just closed
    if (current.state.changesTo('3') || current.state.changesTo('4')) {
        checkAndCloseRITM(current.getValue('request_item'));
    }
})(current, previous);

function checkAndCloseRITM(ritmSysId) {
    // Check if all tasks are complete
    var openTasks = new GlideAggregate('sc_task');
    openTasks.addQuery('request_item', ritmSysId);
    openTasks.addQuery('state', 'NOT IN', '3,4,7');  // Not closed or cancelled
    openTasks.addAggregate('COUNT');
    openTasks.query();

    if (openTasks.next()) {
        var count = parseInt(openTasks.getAggregate('COUNT'), 10);
        if (count === 0) {
            // All tasks complete, close RITM
            var ritm = new GlideRecord('sc_req_item');
            if (ritm.get(ritmSysId)) {
                ritm.state = 3;  // Closed Complete
                ritm.update();
            }
        }
    }
}

Variable Management (ES5)

变量管理(ES5)

Access RITM Variables

访问RITM变量

javascript
// Get variable values from RITM (ES5 ONLY!)
function getRITMVariables(ritmSysId) {
    var variables = {};

    var ritm = new GlideRecord('sc_req_item');
    if (!ritm.get(ritmSysId)) {
        return variables;
    }

    // Get all variable values
    var varValue = new GlideRecord('sc_item_option_mtom');
    varValue.addQuery('request_item', ritmSysId);
    varValue.query();

    while (varValue.next()) {
        var varName = varValue.sc_item_option.item_option_new.name.toString();
        var value = varValue.getValue('sc_item_option');

        // Get display value for reference fields
        var varDef = varValue.sc_item_option.item_option_new.getRefRecord();
        if (varDef.getValue('type') === '8') {  // Reference
            var refRecord = new GlideRecord(varDef.getValue('reference'));
            if (refRecord.get(value)) {
                variables[varName] = {
                    value: value,
                    display_value: refRecord.getDisplayValue()
                };
            }
        } else {
            variables[varName] = {
                value: value,
                display_value: varValue.sc_item_option.getDisplayValue()
            };
        }
    }

    return variables;
}
javascript
// Get variable values from RITM (ES5 ONLY!)
function getRITMVariables(ritmSysId) {
    var variables = {};

    var ritm = new GlideRecord('sc_req_item');
    if (!ritm.get(ritmSysId)) {
        return variables;
    }

    // Get all variable values
    var varValue = new GlideRecord('sc_item_option_mtom');
    varValue.addQuery('request_item', ritmSysId);
    varValue.query();

    while (varValue.next()) {
        var varName = varValue.sc_item_option.item_option_new.name.toString();
        var value = varValue.getValue('sc_item_option');

        // Get display value for reference fields
        var varDef = varValue.sc_item_option.item_option_new.getRefRecord();
        if (varDef.getValue('type') === '8') {  // Reference
            var refRecord = new GlideRecord(varDef.getValue('reference'));
            if (refRecord.get(value)) {
                variables[varName] = {
                    value: value,
                    display_value: refRecord.getDisplayValue()
                };
            }
        } else {
            variables[varName] = {
                value: value,
                display_value: varValue.sc_item_option.getDisplayValue()
            };
        }
    }

    return variables;
}

Validate Variables

验证变量

javascript
// Validate RITM variables (ES5 ONLY!)
function validateRITMVariables(ritmSysId) {
    var errors = [];

    var ritm = new GlideRecord('sc_req_item');
    if (!ritm.get(ritmSysId)) {
        return ['RITM not found'];
    }

    // Get catalog item variable definitions
    var catItem = ritm.cat_item.getRefRecord();

    var varDef = new GlideRecord('item_option_new');
    varDef.addQuery('cat_item', catItem.getUniqueValue());
    varDef.addQuery('mandatory', true);
    varDef.query();

    while (varDef.next()) {
        var varName = varDef.getValue('name');
        var varValue = ritm.variables[varName];

        if (!varValue || varValue.toString() === '') {
            errors.push('Missing required variable: ' + varDef.getValue('question_text'));
        }
    }

    return errors;
}
javascript
// Validate RITM variables (ES5 ONLY!)
function validateRITMVariables(ritmSysId) {
    var errors = [];

    var ritm = new GlideRecord('sc_req_item');
    if (!ritm.get(ritmSysId)) {
        return ['RITM not found'];
    }

    // Get catalog item variable definitions
    var catItem = ritm.cat_item.getRefRecord();

    var varDef = new GlideRecord('item_option_new');
    varDef.addQuery('cat_item', catItem.getUniqueValue());
    varDef.addQuery('mandatory', true);
    varDef.query();

    while (varDef.next()) {
        var varName = varDef.getValue('name');
        var varValue = ritm.variables[varName];

        if (!varValue || varValue.toString() === '') {
            errors.push('Missing required variable: ' + varDef.getValue('question_text'));
        }
    }

    return errors;
}

Request Approvals (ES5)

请求审批(ES5)

Check Approval Status

检查审批状态

javascript
// Get approval status for request (ES5 ONLY!)
function getRequestApprovalStatus(requestSysId) {
    var approvals = [];

    var approval = new GlideRecord('sysapproval_approver');
    approval.addQuery('sysapproval', requestSysId);
    approval.query();

    while (approval.next()) {
        approvals.push({
            approver: approval.approver.getDisplayValue(),
            state: approval.state.getDisplayValue(),
            comments: approval.getValue('comments'),
            sys_updated_on: approval.getValue('sys_updated_on')
        });
    }

    // Determine overall status
    var pending = 0;
    var approved = 0;
    var rejected = 0;

    for (var i = 0; i < approvals.length; i++) {
        var state = approvals[i].state;
        if (state === 'Requested') pending++;
        else if (state === 'Approved') approved++;
        else if (state === 'Rejected') rejected++;
    }

    return {
        approvals: approvals,
        summary: {
            pending: pending,
            approved: approved,
            rejected: rejected,
            overall: rejected > 0 ? 'Rejected' : (pending > 0 ? 'Pending' : 'Approved')
        }
    };
}
javascript
// Get approval status for request (ES5 ONLY!)
function getRequestApprovalStatus(requestSysId) {
    var approvals = [];

    var approval = new GlideRecord('sysapproval_approver');
    approval.addQuery('sysapproval', requestSysId);
    approval.query();

    while (approval.next()) {
        approvals.push({
            approver: approval.approver.getDisplayValue(),
            state: approval.state.getDisplayValue(),
            comments: approval.getValue('comments'),
            sys_updated_on: approval.getValue('sys_updated_on')
        });
    }

    // Determine overall status
    var pending = 0;
    var approved = 0;
    var rejected = 0;

    for (var i = 0; i < approvals.length; i++) {
        var state = approvals[i].state;
        if (state === 'Requested') pending++;
        else if (state === 'Approved') approved++;
        else if (state === 'Rejected') rejected++;
    }

    return {
        approvals: approvals,
        summary: {
            pending: pending,
            approved: approved,
            rejected: rejected,
            overall: rejected > 0 ? 'Rejected' : (pending > 0 ? 'Pending' : 'Approved')
        }
    };
}

MCP Tool Integration

MCP工具集成

Available Tools

可用工具

ToolPurpose
snow_query_table
Query requests and RITMs
snow_find_artifact
Find catalog items
snow_execute_script_with_output
Test request scripts
snow_create_catalog_item
Create catalog items
工具用途
snow_query_table
查询请求和RITM
snow_find_artifact
查找目录项
snow_execute_script_with_output
测试请求脚本
snow_create_catalog_item
创建目录项

Example Workflow

示例工作流

javascript
// 1. Query open requests
await snow_query_table({
    table: 'sc_req_item',
    query: 'state!=3^state!=4^requested_for=javascript:gs.getUserID()',
    fields: 'number,short_description,cat_item,state,stage'
});

// 2. Get request details
await snow_execute_script_with_output({
    script: `
        var vars = getRITMVariables('ritm_sys_id');
        gs.info(JSON.stringify(vars));
    `
});

// 3. Check approvals
await snow_query_table({
    table: 'sysapproval_approver',
    query: 'sysapproval=request_sys_id',
    fields: 'approver,state,comments'
});
javascript
// 1. Query open requests
await snow_query_table({
    table: 'sc_req_item',
    query: 'state!=3^state!=4^requested_for=javascript:gs.getUserID()',
    fields: 'number,short_description,cat_item,state,stage'
});

// 2. Get request details
await snow_execute_script_with_output({
    script: `
        var vars = getRITMVariables('ritm_sys_id');
        gs.info(JSON.stringify(vars));
    `
});

// 3. Check approvals
await snow_query_table({
    table: 'sysapproval_approver',
    query: 'sysapproval=request_sys_id',
    fields: 'approver,state,comments'
});

Best Practices

最佳实践

  1. Clear Descriptions - User-friendly short descriptions
  2. Variable Validation - Validate before processing
  3. Task Ordering - Logical fulfillment sequence
  4. SLA Tracking - Set appropriate due dates
  5. Notifications - Keep requesters informed
  6. Approval Rules - Configure appropriate approvals
  7. Auto-closure - Close RITMs when tasks complete
  8. ES5 Only - No modern JavaScript syntax
  1. 清晰描述 - 使用用户友好的简短描述
  2. 变量验证 - 处理前验证变量
  3. 任务排序 - 合理的履行顺序
  4. SLA跟踪 - 设置合适的截止日期
  5. 通知提醒 - 及时告知请求发起者
  6. 审批规则 - 配置合适的审批流程
  7. 自动关闭 - 任务完成后关闭RITM
  8. 仅支持ES5 - 禁止使用现代JavaScript语法