Business Rules
Auto-numbering with Custom Prefix
Generate custom record numbers with prefixes based on category, type, or other fields (e.g., HW0001, SW0002, NET0003).
(function executeRule(current, previous /*null when async*/) {
// Configuration: Define number prefixes based on category
var prefixMap = {
'hardware': 'HW',
'software': 'SW',
'network': 'NET',
'database': 'DB',
'inquiry': 'INQ',
'default': 'INC' // Default prefix if category not found
};
try {
// Get category to determine prefix
var category = current.getValue('category') || 'default';
var prefix = prefixMap[category] || prefixMap['default'];
// Alternative: Use different field for prefix determination
// var type = current.getValue('u_type');
// var prefix = prefixMap[type] || prefixMap['default'];
// Get current year for prefix (optional)
var year = new GlideDateTime().getYear().toString().substring(2); // Last 2 digits
prefix = prefix + year; // e.g., HW24
// Query for the highest number with this prefix
var ga = new GlideAggregate('incident');
ga.addQuery('number', 'STARTSWITH', prefix);
ga.addAggregate('MAX', 'number');
ga.query();
var nextNumber = 1;
if (ga.next()) {
var maxNumber = ga.getAggregate('MAX', 'number');
if (maxNumber) {
// Extract numeric part from the number
// Assumes format: PREFIX-NNNN (e.g., HW24-0001)
var parts = maxNumber.split('-');
if (parts.length > 1) {
var numericPart = parseInt(parts[1], 10);
if (!isNaN(numericPart)) {
nextNumber = numericPart + 1;
}
}
}
}
// Format number with leading zeros (e.g., 0001, 0042, 1234)
var paddedNumber = String(nextNumber).padStart(4, '0');
// Construct final number
var customNumber = prefix + '-' + paddedNumber;
// Set the number
current.setValue('number', customNumber);
gs.info('Auto-numbering: Generated number ' + customNumber +
' for category: ' + category);
// Optional: Set a display number field if you want to keep standard number
// current.setValue('u_custom_number', customNumber);
} catch (e) {
gs.error('Auto-numbering BR error: ' + e.message);
// Fallback to default numbering
// Let ServiceNow handle the number generation
}
// Alternative approach: Use number maintenance records
/*
function getNextNumber(prefix) {
// Create/use a custom table to track number sequences
var grCounter = new GlideRecord('u_number_counter');
grCounter.addQuery('prefix', prefix);
grCounter.query();
var nextNum = 1;
if (grCounter.next()) {
nextNum = parseInt(grCounter.current_number) + 1;
grCounter.current_number = nextNum;
grCounter.update();
} else {
// Create new counter record
grCounter.initialize();
grCounter.prefix = prefix;
grCounter.current_number = nextNum;
grCounter.insert();
}
return nextNum;
}
var nextNum = getNextNumber(prefix);
var paddedNumber = String(nextNum).padStart(4, '0');
current.setValue('number', prefix + '-' + paddedNumber);
*/
})(current, previous);How to use it
1. Create a before Business Rule on your table 2. Check "Insert" checkbox only 3. Set Order to 100 to run early 4. Customize prefixMap with your categories and prefixes 5. Decide on number format (with/without year, padding length) 6. Test number generation across different categories 7. Verify uniqueness and sequence continuity 8. Consider concurrency issues in high-volume environments 9. Alternative: Create custom counter table for better control 10. Document numbering scheme for users
Adapt the table names, fields, and conditions to your instance. Test the behavior in a development environment before using it in production.