Phil Swann
Tera Guru
Tera Guru

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. 

Comments
Nicklas Jepsen
Giga Guru

Hi Phil,

 

This is an amazing discovery, and quite a worrisome bug.

It has been something that I have wondered about.

Thanks for the fix.

 

Nicklas Jepsen

Phil Swann
Tera Guru
Tera Guru

Thanks Nicklas, no problem at all...  sorry for not sharing sooner 🙂

Phil Swann
Tera Guru
Tera Guru

Please raise with your HI support team, and also vote up the idea on the portal:

https://community.servicenow.com/community?id=view_idea&sysparm_idea_id=35ea91541b2f9018305fea89bd4b...

 

We can get this fixed in the core release! 

Bram2
Mega Contributor

Hello Phil, 

Thanks for this fix. I first saw this issue a couple of weeks ago and it seems to be occuring more and more. I voted on your idea as well. Hopefully its fixed soon.

Phil Swann
Tera Guru
Tera Guru

thanks - yes it needs fixing in the core! vote up , up and away!! 

nagydan2
Tera Contributor

Why does then Number assignment work in some cases, and leaves Empty numbers in some other cases?

If GRC cannot call that GLobal business rule, then why not all numbers are empty?

Phil Swann
Tera Guru
Tera Guru

it is intermittent, and seems to happen when performing mass operations, e.g. the first time you map entity type with lots of entities to lots of content... i think if it failed every time then it would have been identified and fixed sooner! but this is pure speculation 🙂 

nagydan2
Tera Contributor

Your solution might be working (adding "global" in front of the script) but I don't understand why. 🙂

I guess there are some "meme" pictures on this already around the internets :)))

Phil Swann
Tera Guru
Tera Guru

the reason why... I hope I can explain this easily enough 

 

Because GRC is built in scoped apps, so the sn_grc_item table in sn_grc scope; this table is extended into the sn_compliance scope as sn_compliance_control and into sn_risk for sn_risk_risk... 

The number field is on the sn_grc_item table, but is available to both control and risk. The number field is set with the default value which calls a GLOBAL function which returns the correct, next, unique number.. it is being called FROM a different SCOPE app, so the prefix is important because the function does not truly exist IN the scope.. the prefix tells sn_grc / sn_compliance / sn_risk to GO TO.... GLOBAL first 

Version history
Last update:
‎09-24-2020 09:49 PM
Updated by: