Send user to RITM instead of REQ when submitting a catalog item

j3ssicav
Kilo Expert

We are running Madrid and have the OOB widgets for sc-checkout and widget-sc-cat-item-v2.

We are about to go live with Service Portal for our IT catalog for the first time (have been using CMS).  We would like a catalog item submit to redirect to the RITM instead of REQ. REQs only seem relevant to us when they are using Order Guides and we have not gone live with any yet- just single submit catalog items. Also there are no notifications sent for REQ comments so we don't want to confuse customers.

I have cloned both widgets and have attempted to follow the instructions for https://community.servicenow.com/community?id=community_question&sys_id=5052e878db679bc0fff8a345ca96... 

It is slightly outdated though and I feel like I might be missing a piece of the puzzle. It redirects to the correct page now but shows the request instead of the RITM. The function they mention looks different on my version so I updated to the best of my ability. I was unclear about what to update on the checkout widget as well.

1 ACCEPTED SOLUTION

Josh Virelli
Tera Guru

Okay I have it figured out, it is very similar to my other post.

First, make sure your clone of the Catalog Checkout widget has a unique ID. We'll need this is in our other widget. I've named mine "jessicas-checkout"

find_real_file.png

Whatever the ID is, copy it and we'll put it in line 21 of the server script of the other widget (the clone of SC Catalog Item)

find_real_file.png

This will associate the two widgets so that when you click "Order Now" our custom Catalog Checkout widget will display.

Then it's time to edit the Checkout widget to insert a check for one RITM before the redirect, and if it finds one, redirect to the ticket page with the RITM, instead of the sc_request.

We do this by updating the data object in the server synchronously, so we have to wait until the server returns a value before we redirect with the $location service. You can simply copy and paste these into your Server script and Client controller respectively, I just wanted to explain a bit of what's happening here since you will have to support it going forward 🙂  It also looks like there is a redirect handled on the SC Catalog Item widget, but I believe that only applies if you are not using the modal Checkout widget. In any case, make sure to test this with Order guides, record producers, and any type of catalog item you can think of before moving it to production.

 

Server script

(function() {
	data.action = options.action;
	if (data.action)
		data.item = options.item;
	else
		data.action = 'checkout';
	
	if (input && input.action == "from_attachment")
		return;

	var cartName = '';
	if (input)
		cartName = input.cart.name;
	else if (options.cart)
		cartName = options.cart.name;

	var m = data.msgs = {};
	m.dialogTitle = gs.getMessage("Delete Attachment");
	m.dialogMessage = gs.getMessage("Are you sure?");
	m.dialogOK = gs.getMessage("OK");
	m.dialogCancel = gs.getMessage("Cancel");
	m.renameSuccessMsg = gs.getMessage("Attachment renamed successfully");
	m.deleteSuccessMsg = gs.getMessage("Attachment deleted successfully");
	m.delete_attachment = gs.getMessage("Delete Attachment?");
	m.requestSubmitted = gs.getMessage("Thank you, your request has been submitted.");
	if (data.item.request_method == "request") {
		m.checkOutMsg = gs.getMessage("Request");
		m.checkoutPopupTitle = gs.getMessage("Request Confirmation");
	} else {
		m.checkOutMsg = gs.getMessage("Checkout");
		m.checkoutPopupTitle = gs.getMessage("Order Confirmation");
	}

	data.maxAttachmentSize = parseInt(gs.getProperty("com.glide.attachment.max_size", 1024));
	if (isNaN(data.maxAttachmentSize))
		data.maxAttachmentSize = 24;
	m.largeAttachmentMsg = gs.getMessage("Attached files must be smaller than {0} - please try again", "" + data.maxAttachmentSize + "MB");
	
	var cartJS;
	if (data.action !== 'order_now') {
		cartJS = new sn_sc.CartJS(cartName, '' + gs.getUser().getID());
		
		if (input && input.action === "change_shipping_info") {
			cartJS.setSpecialInstructions(input.special_instructions);
			cartJS.setRequestedFor(input.requestedFor);
			cartJS.setDeliveryAddress(input.deliverTo);
		}
	}
	
	if (input && input.action == 'order_guide') {
		var guideJS = new sn_sc.OrderGuide('' + cartName);
		cartJS = new sn_sc.CartJS('' + cartName);
		for(var i = 0; i < input.item.items.length; i++) {
			guideJS.navigateFromMap(input.item.items[i]);
		}
		cartJS.activateGuide();
		cartJS.setRequestedFor(input.requested_for);
		cartJS.setDeliveryAddress(input.delivery_address);
		cartJS.setSpecialInstructions(input.special_instructions);
		cartJS.setParentParams(input.parentParams);
		var request = cartJS.checkoutGuide();
		data.result = {sys_id: request.request_id, number: request.request_number, table: 'sc_request'};
		$sp.logStat('Checkout Request', 'sc_request', request.request_id);
		return;
	}
	
	if (input && input.action === 'checkout') {
		var request = cartJS.checkoutCart(true);
		data.result = {sys_id: request.request_id, number: request.request_number, table: 'sc_request'};
		$sp.logStat('Checkout Request', 'sc_request', request.request_id);
		return;
	}

//This is where we determine if there is one RITM associated and return something in data.ritmId if so for the client controller
		if(input && input.requestId){
			//Search for related RITMs
			var ritm = new GlideRecord('sc_req_item');
			ritm.addQuery('request',input.requestId);
			ritm.query();
			//If exactly one RITM is returned, pass to the Client Controller to redirect user
			if(ritm.next() && (ritm.getRowCount() == 1)){
				data.ritmId = ritm.getUniqueValue();
			}
		}
	
	if (data.action !== 'order_now')
		data.cart = cartJS.getCartDetails(false);
	else
		data.cart = {name: cartName, sys_id: gs.generateGUID(), requested_for: gs.getUser().getID(), requested_for_display_name: gs.getUser().getDisplayName(), delivery_address: sn_sc.CartJS.getRequestedForAddress(gs.getUser().getID())};

	if (options && options.parentParams && options.parentParams.sysparm_parent_table && options.parentParams.sysparm_parent_sys_id && options.parentParams.sysparm_parent_sys_id != -1) { //if parent is passed
			var gr = new GlideRecord('request_parent_mapping');
			gr.get('parent_table', options.parentParams.sysparm_parent_table);
			gr.query();
			if (gr.next()) {
				var parent = new GlideRecord(options.parentParams.sysparm_parent_table);
				parent.get(options.parentParams.sysparm_parent_sys_id);
				if (JSUtil.notNil(parent.getValue(gr.requested_for_field))) {
					data.cart.requested_for = parent.getValue(gr.requested_for_field);
					data.cart.requested_for_display_name = parent.getDisplayValue(gr.requested_for_field);
					data.cart.delivery_address = sn_sc.CartJS.getRequestedForAddress(data.cart.requested_for);
				}
				data.parentParams = options.parentParams;
			}
	}
	
	if (options && options.requested_for && options.requested_for.id) { //If Passed via options
			data.cart.requested_for = options.requested_for.id;
			data.cart.requested_for_display_name = options.requested_for.displayValue;
			data.cart.delivery_address = sn_sc.CartJS.getRequestedForAddress(options.requested_for.id);
	}

	if (data.request_for) { //if value is changed by user
		var user = GlideUser.getUserByID(data.request_for);
		if (user.exists()) {
			data.cart.requested_for = data.request_for;
			data.cart.requested_for_display_name = user.getDisplayName();
			data.cart.delivery_address = sn_sc.CartJS.getRequestedForAddress(data.request_for);
		}
	}

	data.disable_req_for = sn_sc.CartJS.canViewRF();
	var reqForDispCols = gs.getProperty("glide.sc.request_for.columns");
	if (reqForDispCols && reqForDispCols.length > 0) {
		 reqForDispCols = reqForDispCols.replace(/;/g, ",")
		 reqForDispCols = "name," + reqForDispCols;
	}
	data.reqForDispCols = reqForDispCols || "name";
	data.reqForQuery = gs.getProperty("glide.sc.request_for.query");
	
})();

 

Client Controller

function($scope, $http, $timeout, $location, spScUtil, nowAttachmentHandler, spUtil, $log, spAriaUtil, $q, spAtf, spModal, spAriaFocusManager) {
	var c = this;
	c.showSpecialInstructions = false;
	c.showDeliveryAddr = false;

	c.updateDetails = function() {
		c.deliverTo = c.data.cart.delivery_address;
		c.special_instructions = c.data.cart.special_instructions;
		c.requestedFor = {
			displayValue: c.data.cart.requested_for_display_name,
			value: c.data.cart.requested_for,
			name: 'requested_for'
		};
	}


	spAtf.init().then(function(atf) {
		$scope._atf = atf;
		atf.expose('checkout_util', checkoutUtil);
	});

	var checkoutUtil = {
		checkout: function() {
			var defer = $q.defer();
			$scope.c.triggerCheckout();
			var cleanUp;
			var isOrderGuide = c.data.action == 'order_guide';
			if(isOrderGuide)
				cleanUp = $scope.$on('$sp.sc_order_guide.submitted', function(o, result) {
					$timeout(function() {
						cleanUp();
						defer.resolve(result);
					}, 10);
				});
			else
				cleanUp = $scope.$on('$sp.sc_cat_item.submitted', function(o, result) {
					$timeout(function() {
						cleanUp();
						defer.resolve(result);
					}, 10);
				});
			return defer.promise;
		}
	}

	$scope.$on('dialog.upload_too_large.show', function(e){
		$log.error($scope.m.largeAttachmentMsg);
		spUtil.addErrorMessage($scope.m.largeAttachmentMsg);
	});

	$scope.m = $scope.data.msgs;
	$scope.checkOutMsg = $scope.m.checkOutMsg;
	$scope.checkoutPopupTitle = $scope.m.checkoutPopupTitle;
	var ah = $scope.attachmentHandler = new nowAttachmentHandler(function (attachments, action) {
		$scope.attachments = attachments;
		if (action === "added")
			$scope.setFocusToAttachment();
		if (action === "renamed")
			spAriaUtil.sendLiveMessage($scope.m.renameSuccessMsg);
		if (action === "deleted")
			spAriaUtil.sendLiveMessage($scope.m.deleteSuccessMsg);
		spUtil.get($scope, {action: "from_attachment"});
	}, function (error) {
		spUtil.addErrorMessage(error.msg + error.fileName);
	});

	ah.setParams('sc_cart', c.data.cart.sys_id, 1024 * 1024 * $scope.data.maxAttachmentSize);

	$scope.attachmentHandler.getAttachmentList();

	$scope.confirmDeleteAttachment = function(attachment) {
		spModal.confirm($scope.data.msgs.delete_attachment).then(function() {
			$scope.attachmentHandler.deleteAttachment(attachment);
			$scope.setFocusToAttachmentButton();
		});
	}

	c.changeShippingInfo = function() {
		if (c.data.action !== 'order_now')
			c.server.get({
				action: "change_shipping_info",
				requestedFor: c.requestedFor.value,
				special_instructions: c.special_instructions,
				deliverTo: c.deliverTo,
				cart: {name: c.data.cart.name}
			}).then(function(response) {
				c.data.cart = response.data.cart;
				c.updateDetails();
			});
	}

	c.triggerCheckout = function() {
		var newURL;
		var page = 'sc_request';
		var table = 'sc_request';

		c.checkoutInProgress = true;
		var additionalParms = {'sysparm_requested_for': c.requestedFor.value,
							   'special_instructions': c.special_instructions,
							   'delivery_address': c.deliverTo
							  };
		if (c.data.parentParams) {
			additionalParms.sysparm_parent_sys_id =  c.data.parentParams.sysparm_parent_sys_id;
			additionalParms.sysparm_parent_table = c.data.parentParams.sysparm_parent_table;
		}
		if (c.data.action == 'order_now') {
			spScUtil.orderNow(c.data.item.sys_id, c.data.item.quantity, c.data.item.fields, c.data.item.newRecordID, additionalParms).then(function(response) {
				var a = response.data.result;
				if (!$scope.data.parentParams)
					$scope.$emit("$$uiNotification", a.$$uiNotification);
				$scope.$emit("$sp.sc_cat_item.submitted", a);
				if (c.options.auto_redirect == 'false') {
					$rootScope.$broadcast("$sp.service_catalog.cart.submitted", true);
					spUtil.addInfoMessage($scope.m.requestSubmitted);
					return;
				} else if (!$scope._atf) {
					//Update the server and see if exactly one RITM is returned, 
					c.data.requestId = a.sys_id;
					c.server.update().then(function(){
						var redirectSysId = c.data.requestId;
						//if one RITM is returned, redirect to ticket page for that RITM. Otherwise redirect to sc_request
						if(c.data.ritmId){
							page = 'ticket';
							table = 'sc_req_item';
							redirectSysId = c.data.ritmId;
						}
						newURL = $location.search('&id=' + page + '&is_new_order=true&table='+ table + '&sys_id=' + redirectSysId);
						spAriaFocusManager.navigateToLink(newURL.url());
					});
				}
			});
		} else if (c.data.action == 'order_now_wishlisted_item') {
			spScUtil.orderWishlistedItem(c.data.item.sys_id, c.data.item.quantity, c.data.item.fields, c.data.item.newRecordID, additionalParms).then(function(response) {
				var a = response.data.result;
				if (!$scope.data.parentParams)
					$scope.$emit("$$uiNotification", a.$$uiNotification);
				$scope.$emit("$sp.sc_cat_item.submitted", a);
				$rootScope.$broadcast("$sp.service_catalog.wishlist.update");
				if (c.options.auto_redirect == 'false') {
					$rootScope.$broadcast("$sp.service_catalog.cart.submitted", true);
					spUtil.addInfoMessage($scope.m.requestSubmitted);
					return;
				} else {
					c.data.requestId = a.sys_id;
					c.server.update().then(function(){
						var redirectSysId = c.data.requestId;
						//if one RITM is returned, redirect to ticket page for that RITM. Otherwise redirect to sc_request
						if(c.data.ritmId){
							page = 'ticket';
							table = 'sc_req_item';
							redirectSysId = c.data.ritmId;
						}
						newURL = $location.search('&id=' + page + '&is_new_order=true&table='+ table + '&sys_id=' + redirectSysId);
						spAriaFocusManager.navigateToLink(newURL.url());
					});
				}
			});
		}
		else {
			c.data.delivery_address = c.deliverTo;
			c.data.special_instructions = c.special_instructions;
			c.data.requested_for = c.requestedFor.value;
			var isOrderGuide = c.data.action == 'order_guide';
			c.server.update().then(function(response) {
				c.data.action = null;
				if (isOrderGuide)
					$scope.$emit("$sp.sc_order_guide.submitted", $scope.data.result);
				else
					$scope.$emit("$sp.cart.submitted", $scope.data.result);
				if (c.options.auto_redirect == 'false') {
					$rootScope.$broadcast("$sp.service_catalog.cart.update");
					$rootScope.$broadcast("$sp.service_catalog.cart.submitted", true);
					spUtil.addInfoMessage($scope.m.requestSubmitted);
					return;
				}
				else {
					if ($scope.data.result.sys_id) 
						$location.search('id=sc_request&is_new_order=true&table=sc_request&sys_id=' + $scope.data.result.sys_id);
					else 
						$location.search('id=requests');

					$timeout(function(){
						$rootScope.$broadcast("$sp.service_catalog.cart.update");
						$rootScope.$broadcast("$sp.service_catalog.cart.submitted", true);						
					})

				}
			});
		}
	}

	$scope.$on("field.change", function(evt, parms) {
		if (parms.field.name == 'requested_for') {
			c.data.cart.requested_for = parms.newValue;
			var getShippingAddrURL = '/api/sn_sc/v1/servicecatalog/cart/delivery_address/' + parms.newValue;
			$http.get(getShippingAddrURL).then(function handleSuccess(response) {
				if (response.data.result) {
					c.deliverTo = response.data.result.trim();
				} else {
					c.deliverTo = '';
				}
				c.changeShippingInfo();
			});
		}
	});

	c.cancel = function() {
		$rootScope.$broadcast("$sp.service_catalog.cart.cancel_order", true);
	}

	c.allowDeliveryAddress = function () {
		if (c.data.item)
			return c.data.item.request_method != "request"
			return true;
	}

	c.updateDetails();
}

 

I was able to get this working, let me know if it works for you!

If my answer was helpful or answered your question, please mark it as 'Helpful' or 'Correct'

Thanks!

Josh

View solution in original post

12 REPLIES 12

Josh Virelli
Tera Guru

Hi Jessica,

I actually just answered this for someone else the other day. Here's the link to that post: https://community.servicenow.com/community?id=community_question&sys_id=336f5740db8e3b001cd8a345ca96...

 

 

Edit: I just realized you are using the "widget-sc-cat-item-v2" widget instead of the widget referred to in my above post. The answer should be very similar to what I described in that post, but give me a few minutes and I'll take a crack at handling the redirect in this widget for you 🙂

 

If my answer was helpful or answered your question, please mark it as 'Helpful' or 'Correct'

Thanks!

Josh

Thank you so much for the reply. I am combing through your code and comparing it to the widget I have to see if I can figure it out.

Sorry, I got pulled away after I replied to you. If I get time this afternoon I'll try again.

I looked into it a little bit and I noticed there is a redirect in the "widget-sc-cat-item-v2" widget, but if you're using the "sc-checkout" that redirect wins out. So try editing the "sc-checkout" widget, look for $location in the client script. The basis of my code was to update the server synchronously (using a .then function after server.update()) and then if exactly one RITM exists related to that REQ and then return that RITM sys id and redirect to the ticket page.

Start there, and if I get some time I can figure it out entirely for you 🙂

Josh

Josh Virelli
Tera Guru

Okay I have it figured out, it is very similar to my other post.

First, make sure your clone of the Catalog Checkout widget has a unique ID. We'll need this is in our other widget. I've named mine "jessicas-checkout"

find_real_file.png

Whatever the ID is, copy it and we'll put it in line 21 of the server script of the other widget (the clone of SC Catalog Item)

find_real_file.png

This will associate the two widgets so that when you click "Order Now" our custom Catalog Checkout widget will display.

Then it's time to edit the Checkout widget to insert a check for one RITM before the redirect, and if it finds one, redirect to the ticket page with the RITM, instead of the sc_request.

We do this by updating the data object in the server synchronously, so we have to wait until the server returns a value before we redirect with the $location service. You can simply copy and paste these into your Server script and Client controller respectively, I just wanted to explain a bit of what's happening here since you will have to support it going forward 🙂  It also looks like there is a redirect handled on the SC Catalog Item widget, but I believe that only applies if you are not using the modal Checkout widget. In any case, make sure to test this with Order guides, record producers, and any type of catalog item you can think of before moving it to production.

 

Server script

(function() {
	data.action = options.action;
	if (data.action)
		data.item = options.item;
	else
		data.action = 'checkout';
	
	if (input && input.action == "from_attachment")
		return;

	var cartName = '';
	if (input)
		cartName = input.cart.name;
	else if (options.cart)
		cartName = options.cart.name;

	var m = data.msgs = {};
	m.dialogTitle = gs.getMessage("Delete Attachment");
	m.dialogMessage = gs.getMessage("Are you sure?");
	m.dialogOK = gs.getMessage("OK");
	m.dialogCancel = gs.getMessage("Cancel");
	m.renameSuccessMsg = gs.getMessage("Attachment renamed successfully");
	m.deleteSuccessMsg = gs.getMessage("Attachment deleted successfully");
	m.delete_attachment = gs.getMessage("Delete Attachment?");
	m.requestSubmitted = gs.getMessage("Thank you, your request has been submitted.");
	if (data.item.request_method == "request") {
		m.checkOutMsg = gs.getMessage("Request");
		m.checkoutPopupTitle = gs.getMessage("Request Confirmation");
	} else {
		m.checkOutMsg = gs.getMessage("Checkout");
		m.checkoutPopupTitle = gs.getMessage("Order Confirmation");
	}

	data.maxAttachmentSize = parseInt(gs.getProperty("com.glide.attachment.max_size", 1024));
	if (isNaN(data.maxAttachmentSize))
		data.maxAttachmentSize = 24;
	m.largeAttachmentMsg = gs.getMessage("Attached files must be smaller than {0} - please try again", "" + data.maxAttachmentSize + "MB");
	
	var cartJS;
	if (data.action !== 'order_now') {
		cartJS = new sn_sc.CartJS(cartName, '' + gs.getUser().getID());
		
		if (input && input.action === "change_shipping_info") {
			cartJS.setSpecialInstructions(input.special_instructions);
			cartJS.setRequestedFor(input.requestedFor);
			cartJS.setDeliveryAddress(input.deliverTo);
		}
	}
	
	if (input && input.action == 'order_guide') {
		var guideJS = new sn_sc.OrderGuide('' + cartName);
		cartJS = new sn_sc.CartJS('' + cartName);
		for(var i = 0; i < input.item.items.length; i++) {
			guideJS.navigateFromMap(input.item.items[i]);
		}
		cartJS.activateGuide();
		cartJS.setRequestedFor(input.requested_for);
		cartJS.setDeliveryAddress(input.delivery_address);
		cartJS.setSpecialInstructions(input.special_instructions);
		cartJS.setParentParams(input.parentParams);
		var request = cartJS.checkoutGuide();
		data.result = {sys_id: request.request_id, number: request.request_number, table: 'sc_request'};
		$sp.logStat('Checkout Request', 'sc_request', request.request_id);
		return;
	}
	
	if (input && input.action === 'checkout') {
		var request = cartJS.checkoutCart(true);
		data.result = {sys_id: request.request_id, number: request.request_number, table: 'sc_request'};
		$sp.logStat('Checkout Request', 'sc_request', request.request_id);
		return;
	}

//This is where we determine if there is one RITM associated and return something in data.ritmId if so for the client controller
		if(input && input.requestId){
			//Search for related RITMs
			var ritm = new GlideRecord('sc_req_item');
			ritm.addQuery('request',input.requestId);
			ritm.query();
			//If exactly one RITM is returned, pass to the Client Controller to redirect user
			if(ritm.next() && (ritm.getRowCount() == 1)){
				data.ritmId = ritm.getUniqueValue();
			}
		}
	
	if (data.action !== 'order_now')
		data.cart = cartJS.getCartDetails(false);
	else
		data.cart = {name: cartName, sys_id: gs.generateGUID(), requested_for: gs.getUser().getID(), requested_for_display_name: gs.getUser().getDisplayName(), delivery_address: sn_sc.CartJS.getRequestedForAddress(gs.getUser().getID())};

	if (options && options.parentParams && options.parentParams.sysparm_parent_table && options.parentParams.sysparm_parent_sys_id && options.parentParams.sysparm_parent_sys_id != -1) { //if parent is passed
			var gr = new GlideRecord('request_parent_mapping');
			gr.get('parent_table', options.parentParams.sysparm_parent_table);
			gr.query();
			if (gr.next()) {
				var parent = new GlideRecord(options.parentParams.sysparm_parent_table);
				parent.get(options.parentParams.sysparm_parent_sys_id);
				if (JSUtil.notNil(parent.getValue(gr.requested_for_field))) {
					data.cart.requested_for = parent.getValue(gr.requested_for_field);
					data.cart.requested_for_display_name = parent.getDisplayValue(gr.requested_for_field);
					data.cart.delivery_address = sn_sc.CartJS.getRequestedForAddress(data.cart.requested_for);
				}
				data.parentParams = options.parentParams;
			}
	}
	
	if (options && options.requested_for && options.requested_for.id) { //If Passed via options
			data.cart.requested_for = options.requested_for.id;
			data.cart.requested_for_display_name = options.requested_for.displayValue;
			data.cart.delivery_address = sn_sc.CartJS.getRequestedForAddress(options.requested_for.id);
	}

	if (data.request_for) { //if value is changed by user
		var user = GlideUser.getUserByID(data.request_for);
		if (user.exists()) {
			data.cart.requested_for = data.request_for;
			data.cart.requested_for_display_name = user.getDisplayName();
			data.cart.delivery_address = sn_sc.CartJS.getRequestedForAddress(data.request_for);
		}
	}

	data.disable_req_for = sn_sc.CartJS.canViewRF();
	var reqForDispCols = gs.getProperty("glide.sc.request_for.columns");
	if (reqForDispCols && reqForDispCols.length > 0) {
		 reqForDispCols = reqForDispCols.replace(/;/g, ",")
		 reqForDispCols = "name," + reqForDispCols;
	}
	data.reqForDispCols = reqForDispCols || "name";
	data.reqForQuery = gs.getProperty("glide.sc.request_for.query");
	
})();

 

Client Controller

function($scope, $http, $timeout, $location, spScUtil, nowAttachmentHandler, spUtil, $log, spAriaUtil, $q, spAtf, spModal, spAriaFocusManager) {
	var c = this;
	c.showSpecialInstructions = false;
	c.showDeliveryAddr = false;

	c.updateDetails = function() {
		c.deliverTo = c.data.cart.delivery_address;
		c.special_instructions = c.data.cart.special_instructions;
		c.requestedFor = {
			displayValue: c.data.cart.requested_for_display_name,
			value: c.data.cart.requested_for,
			name: 'requested_for'
		};
	}


	spAtf.init().then(function(atf) {
		$scope._atf = atf;
		atf.expose('checkout_util', checkoutUtil);
	});

	var checkoutUtil = {
		checkout: function() {
			var defer = $q.defer();
			$scope.c.triggerCheckout();
			var cleanUp;
			var isOrderGuide = c.data.action == 'order_guide';
			if(isOrderGuide)
				cleanUp = $scope.$on('$sp.sc_order_guide.submitted', function(o, result) {
					$timeout(function() {
						cleanUp();
						defer.resolve(result);
					}, 10);
				});
			else
				cleanUp = $scope.$on('$sp.sc_cat_item.submitted', function(o, result) {
					$timeout(function() {
						cleanUp();
						defer.resolve(result);
					}, 10);
				});
			return defer.promise;
		}
	}

	$scope.$on('dialog.upload_too_large.show', function(e){
		$log.error($scope.m.largeAttachmentMsg);
		spUtil.addErrorMessage($scope.m.largeAttachmentMsg);
	});

	$scope.m = $scope.data.msgs;
	$scope.checkOutMsg = $scope.m.checkOutMsg;
	$scope.checkoutPopupTitle = $scope.m.checkoutPopupTitle;
	var ah = $scope.attachmentHandler = new nowAttachmentHandler(function (attachments, action) {
		$scope.attachments = attachments;
		if (action === "added")
			$scope.setFocusToAttachment();
		if (action === "renamed")
			spAriaUtil.sendLiveMessage($scope.m.renameSuccessMsg);
		if (action === "deleted")
			spAriaUtil.sendLiveMessage($scope.m.deleteSuccessMsg);
		spUtil.get($scope, {action: "from_attachment"});
	}, function (error) {
		spUtil.addErrorMessage(error.msg + error.fileName);
	});

	ah.setParams('sc_cart', c.data.cart.sys_id, 1024 * 1024 * $scope.data.maxAttachmentSize);

	$scope.attachmentHandler.getAttachmentList();

	$scope.confirmDeleteAttachment = function(attachment) {
		spModal.confirm($scope.data.msgs.delete_attachment).then(function() {
			$scope.attachmentHandler.deleteAttachment(attachment);
			$scope.setFocusToAttachmentButton();
		});
	}

	c.changeShippingInfo = function() {
		if (c.data.action !== 'order_now')
			c.server.get({
				action: "change_shipping_info",
				requestedFor: c.requestedFor.value,
				special_instructions: c.special_instructions,
				deliverTo: c.deliverTo,
				cart: {name: c.data.cart.name}
			}).then(function(response) {
				c.data.cart = response.data.cart;
				c.updateDetails();
			});
	}

	c.triggerCheckout = function() {
		var newURL;
		var page = 'sc_request';
		var table = 'sc_request';

		c.checkoutInProgress = true;
		var additionalParms = {'sysparm_requested_for': c.requestedFor.value,
							   'special_instructions': c.special_instructions,
							   'delivery_address': c.deliverTo
							  };
		if (c.data.parentParams) {
			additionalParms.sysparm_parent_sys_id =  c.data.parentParams.sysparm_parent_sys_id;
			additionalParms.sysparm_parent_table = c.data.parentParams.sysparm_parent_table;
		}
		if (c.data.action == 'order_now') {
			spScUtil.orderNow(c.data.item.sys_id, c.data.item.quantity, c.data.item.fields, c.data.item.newRecordID, additionalParms).then(function(response) {
				var a = response.data.result;
				if (!$scope.data.parentParams)
					$scope.$emit("$$uiNotification", a.$$uiNotification);
				$scope.$emit("$sp.sc_cat_item.submitted", a);
				if (c.options.auto_redirect == 'false') {
					$rootScope.$broadcast("$sp.service_catalog.cart.submitted", true);
					spUtil.addInfoMessage($scope.m.requestSubmitted);
					return;
				} else if (!$scope._atf) {
					//Update the server and see if exactly one RITM is returned, 
					c.data.requestId = a.sys_id;
					c.server.update().then(function(){
						var redirectSysId = c.data.requestId;
						//if one RITM is returned, redirect to ticket page for that RITM. Otherwise redirect to sc_request
						if(c.data.ritmId){
							page = 'ticket';
							table = 'sc_req_item';
							redirectSysId = c.data.ritmId;
						}
						newURL = $location.search('&id=' + page + '&is_new_order=true&table='+ table + '&sys_id=' + redirectSysId);
						spAriaFocusManager.navigateToLink(newURL.url());
					});
				}
			});
		} else if (c.data.action == 'order_now_wishlisted_item') {
			spScUtil.orderWishlistedItem(c.data.item.sys_id, c.data.item.quantity, c.data.item.fields, c.data.item.newRecordID, additionalParms).then(function(response) {
				var a = response.data.result;
				if (!$scope.data.parentParams)
					$scope.$emit("$$uiNotification", a.$$uiNotification);
				$scope.$emit("$sp.sc_cat_item.submitted", a);
				$rootScope.$broadcast("$sp.service_catalog.wishlist.update");
				if (c.options.auto_redirect == 'false') {
					$rootScope.$broadcast("$sp.service_catalog.cart.submitted", true);
					spUtil.addInfoMessage($scope.m.requestSubmitted);
					return;
				} else {
					c.data.requestId = a.sys_id;
					c.server.update().then(function(){
						var redirectSysId = c.data.requestId;
						//if one RITM is returned, redirect to ticket page for that RITM. Otherwise redirect to sc_request
						if(c.data.ritmId){
							page = 'ticket';
							table = 'sc_req_item';
							redirectSysId = c.data.ritmId;
						}
						newURL = $location.search('&id=' + page + '&is_new_order=true&table='+ table + '&sys_id=' + redirectSysId);
						spAriaFocusManager.navigateToLink(newURL.url());
					});
				}
			});
		}
		else {
			c.data.delivery_address = c.deliverTo;
			c.data.special_instructions = c.special_instructions;
			c.data.requested_for = c.requestedFor.value;
			var isOrderGuide = c.data.action == 'order_guide';
			c.server.update().then(function(response) {
				c.data.action = null;
				if (isOrderGuide)
					$scope.$emit("$sp.sc_order_guide.submitted", $scope.data.result);
				else
					$scope.$emit("$sp.cart.submitted", $scope.data.result);
				if (c.options.auto_redirect == 'false') {
					$rootScope.$broadcast("$sp.service_catalog.cart.update");
					$rootScope.$broadcast("$sp.service_catalog.cart.submitted", true);
					spUtil.addInfoMessage($scope.m.requestSubmitted);
					return;
				}
				else {
					if ($scope.data.result.sys_id) 
						$location.search('id=sc_request&is_new_order=true&table=sc_request&sys_id=' + $scope.data.result.sys_id);
					else 
						$location.search('id=requests');

					$timeout(function(){
						$rootScope.$broadcast("$sp.service_catalog.cart.update");
						$rootScope.$broadcast("$sp.service_catalog.cart.submitted", true);						
					})

				}
			});
		}
	}

	$scope.$on("field.change", function(evt, parms) {
		if (parms.field.name == 'requested_for') {
			c.data.cart.requested_for = parms.newValue;
			var getShippingAddrURL = '/api/sn_sc/v1/servicecatalog/cart/delivery_address/' + parms.newValue;
			$http.get(getShippingAddrURL).then(function handleSuccess(response) {
				if (response.data.result) {
					c.deliverTo = response.data.result.trim();
				} else {
					c.deliverTo = '';
				}
				c.changeShippingInfo();
			});
		}
	});

	c.cancel = function() {
		$rootScope.$broadcast("$sp.service_catalog.cart.cancel_order", true);
	}

	c.allowDeliveryAddress = function () {
		if (c.data.item)
			return c.data.item.request_method != "request"
			return true;
	}

	c.updateDetails();
}

 

I was able to get this working, let me know if it works for you!

If my answer was helpful or answered your question, please mark it as 'Helpful' or 'Correct'

Thanks!

Josh