User Criteria based on user manager's company

Angel32
Tera Contributor

Hi,

 

I'm desperately trying to set a user criteria depending of the company of the user and the user's manager.

So far among other things, I've tried adding the following script using the advanced mode of the user criteria with no luck.

Any idea of what I'm doing wrong ?

 

// Condition: utilisateur.company == targetCompanySysId OU manager.company == targetCompanySysId

answer = (function() {
var targetCompanySysId = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; // xxxxxxx

// Current user
var userId = gs.getUserID().toString();
if (!userId) return false;

var u = new GlideRecord('sys_user');
if (!u.get(userId)) return false;

// --- user company ---
var userCompanyId = u.getValue('company');
if (userCompanyId && userCompanyId === targetCompanySysId) {
return true;
}

var managerId = u.getValue('manager'); 
if (!managerId) return false;

var m = new GlideRecord('sys_user');
if (!m.get(managerId)) return false;

var managerCompanyId = m.getValue('company');
if (!managerCompanyId) return false;

return managerCompanyId === targetCompanySysId;
})();

1 ACCEPTED SOLUTION

Brad Bowman
Kilo Patron

To be nit-picky, once you return a GlideRecord you can dot-walk without instantiating another GlideRecord on the same table, and there are some unnecessary checks going on here - just return false if the script makes it to the end without having already returned true is a much more straight-forward and easier approach.  The actual pre-set comments when creating a User Criteria record with a script tell you not to use gs.getUserID(), rather 'user_id' which contains the sys_id.  I assume you're not actually using 'xxx...' as the CompanySysId, and not really sure why one would bother obfuscating that as it only leads to confusion and uncertainty.  To summarize, this will be a lot better script to start with and troubleshoot:

answer = (function() {
    var targetCompanySysId = '58473babc3453010069aec4b7d40dd50'; 
    var u = new GlideRecord('sys_user');
    if (u.get(user_id)) {
        if (u.getValue('company') == targetCompanySysId) {
            return true;
        }
        if (u.manager.company.toString() == targetCompanySysId) {
            return true;
        }
    }
    return false;
})();

 

View solution in original post

8 REPLIES 8

TomKwon
Mega Contributor

In Advanced User Criteria, you should not use gs.getUserID() or other session APIs. The script is evaluated against a user record and ServiceNow provides a predefined variable called user_id for that purpose. Using gs.getUserID() can return the logged in user, which fails in cases where the platform evaluates criteria for someone else. 

 

Use this instead.

 

answer = (function () {
var targetCompanySysId = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

// user_id is provided by User Criteria evaluation context
if (!user_id) return false;

var u = new GlideRecord('sys_user');
if (!u.get(user_id)) return false;

// user company match
if (u.company == targetCompanySysId) return true;

// manager company match
if (!u.manager) return false;

var m = new GlideRecord('sys_user');
if (!m.get(u.manager)) return false;

return m.company == targetCompanySysId;
})();

Angel32
Tera Contributor

I've been trying with :

answer = (function () {
var targetCompanySysId = 'cb221d84db7fdc90228e641d0b96199b';

// user_id is provided by User Criteria evaluation context
if (!user_id) return false;

var u = new GlideRecord('sys_user');
if (!u.get(user_id)) return false;

// user company match
if (u.company == targetCompanySysId) return true;

// manager company match
if (!u.manager) return false;

var m = new GlideRecord('sys_user');
if (!m.get(u.manager)) return false;

return m.company == targetCompanySysId;
})();
 
And it is still not ok when I check with "user criteria diagnostics" with a user which complies with both companies criterias (company and manager's company).
😕

HI @Angel32 

 

Brads script is logically correct. The reason it still fails in User Criteria Diagnostics is that diagnostics does not always evaluate reference dot-walking or manager relationships the same way as runtime execution. It is stricter with ACLs and reference resolution, especially for manager.company.

 

Test the User Criteria by assigning it to an actual object (catalog item, HR service, KB, etc.) and validating real access, not diagnostics alone.If the data is correct, Brad’s script is valid. When diagnostics says “no access” but runtime works, trust runtime.

 

check these once - 

The manager user record is active

The manager has a company populated

The company is exactly the same sys_id (not inherited or overridden)

The user you test with is the same one selected in diagnostics

 

☑️ If this helped, please mark it as Helpful or Accept Solution so others can find the answer too.

Kind Regards,
Azar
Serivenow Rising Star
Developer @ KPMG.

Angel32
Tera Contributor

Hi @Its_Azar 

You are correct. I've tried @Brad Bowman  script directly in the portal impersonating a user that match the user criteria and it does work.

Thanks a lot for your help to both of you and everyone who took the time to answer me in this thread.

 

Angel