Prevent duplicate requests from being submitted

Nicholas Omoruy
Tera Contributor

I want to avoid end users creating duplicate requests if they've already made a submission by displaying a message that informs them of the duplicate request. To achieve this, I tried replicating a Catalog Client Script + Ajax example I found on this forum but to no avail.

 

The Unique value that I'm using is the field 'computer'. It's a list collector thats referencing a hardware table. Nothing appears to happen when moving a previously submitted item in the list collector from the Available section to the Selected section.

 

Any assistance will be extremely appreciated!

 

 

onChange Catalog Client Script for the Computer field

 

function onChange(control, oldValue, newValue, isLoading) {
      if (isLoading)
              return;
      g_form.hideFieldMsg('computer', true);
      if (newValue == '')
              return;
      var ga = new GlideAjax('AjaxFunctions');
      ga.addParam('sysparm_name', 'checkUserRequest');
      ga.addParam('sysparm_user', newValue); // User
      ga.addParam('sysparm_item', g_form.getUniqueValue()); // Item
      ga.getXMLAnswer(function(answer) {
              if (answer && answer != 'none')
                      var msg = 'The user already has an open Request(s) for this item: ' + answer;
                      g_form.showFieldMsg('computer', msg, 'error');
              }
      });
}
 
 
Script Include:
Name: AjaxFunctions
Client-callable: true
 
var AjaxFunctions = Class.create();
AjaxFunctions.prototype = Object.extendsObject(AbstractAjaxProcessor, {
checkUserRequest: function() {
          var user = this.getParameter('sysparm_user');
          var item = this.getParameter('sysparm_item');
          var requests = [];
          var ritm = new GlideRecord('sc_req_item');
          ritm.addActiveQuery();
          ritm.addQuery('request.requested_for', user);
          ritm.addQuery('cat_item', item);
          ritm.query();
          while (ritm.next()) {
                  requests.push(String(ritm.number));
          }
          if (requests.length > 0)
                  return requests.join(', ');
          return 'none';
  },
    type: 'AjaxFunctions'
});
 
7 REPLIES 7

Right, if that's the case, I would recommend using the ordered item/catalog item, not its short description as short description can change.

i.e. replace the following line in the client script

ga.addParam('sysparm_short_description', g_form.getValue('short_description'));

TO

ga.addParam('sysparm_item', g_form.getUniqueValue());

 

In regards to the 'Affected Computer(s) or Server(s)', I am assuming it will return an error if there is at least one computer/server that has been already requested.

Below is the updated Script Include:

var AjaxFunctions = Class.create();
AjaxFunctions.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    checkUserRequest: function() {
        var computer = this.getParameter('sysparm_computer');
		computer = computer.split(',');
        var item = this.getParameter('sysparm_item');
        var user = this.getParameter('sysparm_requested_for');
		var arrayUtil = new ArrayUtil();

        var requests = [];
        
		var ritm = new GlideRecord('sc_item_option_mtom');
		ritm.addQuery('request_item.active', true);
		ritm.addQuery('request_item.request.requested_for', user);
		ritm.addQuery('request_item.cat_item.sys_id', desc);
        ritm.addQuery('sc_item_option.item_option_new.name', 'question_text');
        ritm.query();

		while (ritm.next()) {
			//Check if any of the requested computer/server overlaps
			var requestedComputer = ritm.sc_item_option.value.toString();
			requestedComputer = requestedComputer.split(',');

			var overlapComputer = arrayUtil.intersect(requestedComputer, computer);
			if(overlapComputer.length > 0)
			{
				requests.push(ritm.request_item.number.toString());
			}
        }

        if (requests.length > 0)
            return requests.join(', ');
        return 'none';
    },
    type: 'AjaxFunctions'
});

Cheers

 

Sumanth16
Kilo Patron

Hi @Nicholas Omoruy ,

 

Client script:

function onChange(control, oldValue, newValue, isLoading) {

if (isLoading)
return;

g_form.hideFieldMsg('requested_for', true);

if (newValue == '')
return;
var ga = new GlideAjax('AjaxFunctions');
ga.addParam('sysparm_name', 'checkUserRequest');
ga.addParam('sysparm_user', newValue); // User
ga.addParam('sysparm_item', g_form.getUniqueValue()); // Item
ga.getXMLAnswer(function(answer) {

if (answer && answer != 'none') {
var msg = 'This person already has an open Request(s) for this item: ' + answer;
g_form.showFieldMsg('requested_for', msg, 'error', false);
}
});
}

 

Script Include:

 

(It is Client Callable and accessible from all application scopes)

 

 

var AjaxFunctions = Class.create();
AjaxFunctions.prototype = Object.extendsObject(AbstractAjaxProcessor, {
checkUserRequest: function() {
var user = this.getParameter('sysparm_user');
var item = this.getParameter('sysparm_item');

var requests = [];
var ritm = new GlideRecord('sc_req_item');
ritm.addActiveQuery();
ritm.addQuery('request.requested_for', user);
ritm.addQuery('cat_item', item);
ritm.query();
while (ritm.next()) {
requests.push(String(ritm.number));
}
if (requests.length > 0)
return requests.join(', ');
return 'none';
},
type: 'AjaxFunctions'
});

 

If I could help you with your Query then, please hit the Thumb Icon and mark it as Correct !!

 

Thanks & Regards,

Sumanth Meda

 

 

Its_Azar
Tera Guru

Hi there

In your client script onChange, make sure to properly handle the response from the AJAX call. The message display logic should be inside the if (answer && answer != 'none') block. Additionally, consider using getDisplayBox() instead of getUniqueValue() to get the unique value of the catalog item.

 

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading)
        return;
    g_form.hideFieldMsg('computer', true);
    if (newValue == '')
        return;
    var ga = new GlideAjax('AjaxFunctions');
    ga.addParam('sysparm_name', 'checkUserRequest');
    ga.addParam('sysparm_user', newValue); // User
    ga.addParam('sysparm_item', g_form.getDisplayBox('computer').value); // Item
    ga.getXMLAnswer(function(answer) {
        if (answer && answer != 'none') {
            var msg = 'The user already has an open Request(s) for this item: ' + answer;
            g_form.showFieldMsg('computer', msg, 'error');
        }
    });
}

 

In the checkUserRequest function of your script include, check that you're returning the response in the correct format. Instead of directly returning the array of request numbers, convert it to JSON format before returning.

script include below.

 

var AjaxFunctions = Class.create();
AjaxFunctions.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    checkUserRequest: function() {
        var user = this.getParameter('sysparm_user');
        var item = this.getParameter('sysparm_item');
        var requests = [];
        var ritm = new GlideRecord('sc_req_item');
        ritm.addActiveQuery();
        ritm.addQuery('request.requested_for', user);
        ritm.addQuery('cat_item', item);
        ritm.query();
        while (ritm.next()) {
            requests.push(String(ritm.number));
        }
        if (requests.length > 0)
            return JSON.stringify(requests); // Return as JSON string
        return 'none';
    },
    type: 'AjaxFunctions'
});

 

 

If this helps kindly accept the response thanks much.

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




Kind Regards,

Mohamed Azarudeen Z

Developer @ KPMG

 Microsoft MVP (AI Services), India