Empty Numbers - and how to solve it
Have you ever seen Controls and Risks generated with Empty numbers?
The problem is simply due to scope, and the lack of global prefix in the default value of the number field on the base sn_grc_item table. The same exists on sn_grc_document, so it could also happen on Policy, Authority Document and Risk Framework. It seems to be OK in most occasions , but because Controls/Risks can be generated at high volumes - it can present itself more-often in Controls and Risks. If you notice it, you can check the logs immediately and you will find some entries reporting a scope prefix issue. (Just strange that it works 9/10 times).
The solution is simple, and I will try and ensure this gets fixed in the core product - until then...
Please see the fix available here: https://developer.servicenow.com/connect.do#!/share/contents/2067273_fix_blank_empty_numbers_in_grc?...
The update on the dictionary records will prevent the issue from occurring, so even if you have not got any examples of the issue - it could occur at any time. Don't fix it with a business rule, and don't make your number field editable (it should always be unique and the system takes care of it for you!)
If you have Controls/Risks with empty numbers, then you might need a fix script to solve.
You can run this directly as background script, the fix script included in the share project above is recorded for rollback also..
var arrTable = ['sn_compliance_policy', 'sn_compliance_authority_document', 'sn_risk_framework', 'sn_compliance_control', 'sn_risk_risk'];
for (var i = 0; i < arrTable.length; i++) {
var grTable = new GlideRecord(arrTable[i]);
if(!grTable.isValid()) continue;
grTable.addNullQuery('number');
grTable.query();
while(grTable.next()) {
grTable.setValue('number', new NumberManager(grTable.getTableName()).getNextObjNumberPadded());
grTable.update();
}
}
The default value javascript: getNextObjNumberPadded(); is actually calling a global business rule. So it is important that scoped entries make this call with the prefix global.getNextObjNumberPadded();
Navigate to /sys_dictionary_list.do?sysparm_query=element=number on your instance and compare Global records with Scoped. All scoped should include the global prefix. In GRC, there might be some that don't.
What does getNextObjNumberPadded mean?
Because it is global Business Rule, it runs on every table and on the dictionary default value means it will only run on insert, but it will have access to current object. It actually makes a call to the global.NumberManager API which is only accessible from Global scope. Take a look at this script include to understand more, but it will effectively keep the number fields on your table maintained!
You can refer to https://docs.servicenow.com/bundle/paris-platform-administration/page/administer/field-administratio... for more information on number maintenance.
https://www.servicenow.com/community/grc-articles/empty-numbers-and-how-to-solve-it/ta-p/2308864