Only one primary contact for each company

Rajendar3
Tera Contributor

Only one primary contact for each table when ever we hit on new button to create a new vendor contact it should check the primary contact check box for existing records with the same vendor name("company" backend name) , If exists it should not allow us to make it true for other users it needs to be done in list layout and form layout.

find_real_file.png

find_real_file.png

 

find_real_file.png

Thanks in advance for your guidance.,

Rajendar.

@Ankur Bawiskar @Pradeep Sharma  @Aman Kumar @Jaspal Singh @Sandeep Dutta 

1 ACCEPTED SOLUTION

Markus Kraus
Kilo Sage

Please note @Ahmed Drar answers. If you still want to implement this, you will need the following artifacts:

  1. Script Include (implements the necessary lookup used by Business Rule and Client Script):
    Name: PrimaryContactCheckHelper
    Client callable: true
    Script:
    var PrimaryContactCheckHelper = Class.create();
    PrimaryContactCheckHelper.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
    	
    	getPrimaryContact: function (company) {
    		company = company || this.getParameter('company');
    		if (company) {
    			var contactGr = new GlideRecord('vm_vdr_contact');
    			contactGr.addQuery('company', company);
    			contactGr.addQuery('primary_contact', true);
    			contactGr.setLimit(1);
    			contactGr.query();
    			if (contactGr.next()) {
    				return JSON.stringify({
    					sys_id: contactGr.getUniqueValue(),
    					display_value: contactGr.getDisplayValue()
    				});
    			}
    		}
    		
    		return '';
    	},
    
        type: 'PrimaryContactCheckHelper'
    });​
  2. Business Rule (prevents List Edit and for generally enforcing the "only one primary contact" rule):
    Name: Only one primary contact
    Advanced: true
    Insert: true
    Update: true
    When: before (default)
    Filter Conditions: Vendor <is not empty> [AND] Primary contact <is> true
    Advanced > Script:
    (function executeRule(current, previous /*null when async*/) {
    
    	var helper = new PrimaryContactCheckHelper();
    	var contact = helper.getPrimaryContact(current.company);
    	if (contact) {
    		contact = JSON.parse(contact);
    		if (contact.sys_id != current.sys_id) {
    			gs.addErrorMessage('Only one primary contact is allowed. Current primary contact: ' + contact.display_value);
    			current.setAbortAction(true);
    		}
    	}
    
    })(current, previous);
  3. Client Script (will set the 'Primary contact' to readonly whenever required):
    Name: Check Primary Contact
    Table: vm_vdr_contact
    UI Type: All
    Type: onChange
    Field name: Vendor
    Script: 
    function onChange(control, oldValue, newValue, isLoading, isTemplate) {
    	if (newValue === '') {
    		g_form.setReadOnly('primary_contact', false);
    		return;
    	}
    
    	var ga = new GlideAjax('PrimaryContactCheckHelper');
    	ga.addParam('sysparm_name', 'getPrimaryContact');
    	ga.addParam('company', newValue);
    	ga.getXMLAnswer(function (contact) {
    		if (contact) {
    			contact = JSON.parse(contact);
    			if (contact.sys_id != g_form.getUniqueValue()) {
    				if (!isLoading) {
    					// only show the message for changed values (the readonly-part is desired on the initial load!)
    					g_form.addInfoMessage('Only one primary contact per Vendor is allowed. Current primary contact: ' + contact.display_value);
    				}
    				
    				g_form.setValue('primary_contact', false);
    				g_form.setReadOnly('primary_contact', true);
    				return;
    			}
    		}
    
    		g_form.setReadOnly('primary_contact', false);
    	});
    }

     

Please let us know if this solution solved your problem.

View solution in original post

7 REPLIES 7

Jaspal Singh
Mega Patron
Mega Patron

You need below.

1. onChange() client script that runs when Vendor field is changed

2. This onChange() script will call a Script include which will have a Server side logic to pick current vendor selected & then compare it in Vendor contact table with a combination of Vendor & Primary Contact: True.

If so, return true or False accordingly.

3. This will then be passed to onChange() script that you can use to set field read-only on the form.

In other words it will use combination of Client Script & Script include

I'm confused here ,Could you please provide the code

Ahmed Drar
Tera Guru
Tera Guru

Hello,

Out of the box, ServiceNow allowed multiple primary contacts for a Vendor - that's not a defect, it has been implemented this way for a reason.

you might have 20 vendor contacts,  5 of them are primary - each one of them is responsible for a different area of risk.

 

here is example

Let's say you're dealing with a vendor(let's call it A1). the vendor has two primary contacts, and each one of them responds to one area of risk - let's say Cyber Risk(User1) and Financial Risk(User2).

When you send out an assessment to your vendor, you are going to choose User1 or User2 based on the area of risk you are trying to assess.

Thanks,

Ahmed

Hello, @Ahmed Drar . May I ask you, referring to your example, how you choose to send an assessment to User1 OR User2? When I send, I do not get a choice of who to send to. And that would be great if it is possible to choose.

Thanks,

Edmund