How to redirect user to Requested Item and not the Request

Matt Cordero1
Tera Guru

Hello all, 

I am have a requirement to redirect users submitting requests in the Service Portal AND ITIL View to the Request Item, not the Request.

I have successfully cloned SC Catalog Item and modified it to redirect users in the Service Portal to the Request Item (not the Request), but I am not sure how to get the same behavior to happen in the ITIL View.

Any suggestions?

SC Catalog Item v3 - Client Script

function ($scope, $http, spScUtil, spUtil, nowAttachmentHandler, $rootScope, $sanitize, $window, $sce, i18n, $timeout, $log, spAriaUtil, $document, spModal, $q, spAtf, $location, spAriaFocusManager, spSCNavStateManager) {
	var c = this;
	if (c.data.sc_cat_item && $scope.data.hasOwnProperty("_generatedItemGUID")) {
		c.data.sc_cat_item._attachmentGUID = $scope.data._generatedItemGUID;
	}

	$scope.getFocus = function(field) {
		var focusVar = (field.type == "reference") ? "sp_formfield_reference_" : "sp_formfield_";
		focusVar += (field.name.startsWith("IO:") ? field._children[0]:field.name);
		document.getElementById(focusVar).focus();
	}

	c.quantity = c.data.quantity ? c.data.quantity + "" : "1";
	c.mandatory = [];
	$scope.stickyHeaderTop = '0px';
	c.widget._debugContextMenu = [
		[ i18n.getMessage("Open") + " sc_cat_item", function() {
			var item = c.data.sc_cat_item;
			$window.open("/sp_config?id=form&table=" + item.table + "&sys_id=" + item.sys_id); }]
	];
	
	$rootScope.$on('spModel.gForm.rendered', function() {
		$timeout(function() {
							spAtf.init().then(function(atf) {
								$scope._atf = atf;
								atf.expose('catalog_util', catalogUtil);
							});
		}, 10);
	});
	
	//	ATF helper object
	var catalogUtil = {
		updateGform: function() {
			$scope._atf.expose('g_form', spAtf.augmentForm(g_form));
		},
		
		addRow: function(fieldId, timeoutInMS) {
			if (timeoutInMS <= 0)
				timeoutInMS = 1000;
			var deferred = $q.defer();
			$scope.$broadcast("$sp.sc_multi_row.create_row", fieldId, $scope.data.sc_cat_item.sys_id);
			$scope.$on('spModel.gForm.initialized', function(e, gFormInstance) {
				if (gFormInstance.getSysId() == fieldId)
					deferred.resolve();
			});
			$timeout(function() {
				deferred.reject();
			}, timeoutInMS);
			return deferred.promise;
		},
		
		submit: function (timeout) {
			var deferred = $q.defer();
			$scope.triggerOnSubmit(timeout);
			var cleanup = $scope.$on('$sp.service_catalog.form_submit_failed', function() {
					cleanup();
					deferred.reject("Can't submit form");
			});
			if (g_form) {
					g_form.$private.events.on('submitted', function() {
			var cleanUp = $scope.$on('$sp.sc_cat_item.submitted', function(o, result) {
						$timeout(function() {
							cleanUp();
							deferred.resolve(result);
						}, 10);
					});
				});
			}
			else
				deferred.reject('g_form not initialized');
			
			return deferred.promise;
		},
		
		addToCart: function(timeout) {
			var defer = $q.defer();
			$scope.triggerAddToCart(timeout);
			var cleanup = $scope.$on('$sp.service_catalog.form_submit_failed', function() {
					cleanup();
					defer.reject("Can't submit form");
			});
			if (g_form) {
				g_form.$private.events.on('submitted', function() {
			var cleanup = $scope.$on('$sp.sc_cat_item.add_to_cart', function(o, result) {
				$timeout(function() {
					cleanup();
					defer.resolve(result);
				}, 10);
			});
				});
			}
			else
				defer.reject('g_form not initialized');			
			return defer.promise;
		},
		
		submitCatItem: function(timeout) {
			var defer = $q.defer();
			$scope.triggerOnSubmit(timeout);
			var cleanup = $scope.$on('$sp.service_catalog.form_submit_failed', function() {
					cleanup();
					defer.reject("Can't submit form");
			});
			if (g_form) {
				g_form.$private.events.on('submitted', function() {
				if ($scope.data.sys_properties.twostep && $scope.data.sc_cat_item.request_method != "submit") {
					defer.resolve();
				}
				else{//When not two step, if reached this step means the form validation is done and it is the item submission that should be monitored
					if (typeof cleanup === 'function')
						cleanup();

					var cleanUp = $scope.$on('$sp.sc_cat_item.submitted', function(o, result) {
						$timeout(function() {
							cleanUp();
							result.single_step = true;
							defer.resolve(result);
						}, 10);
					});
					
					var failedSubmitCleanUp = $scope.$on('$sp.sc_cat_item.submit_failed', function() {
						failedSubmitCleanUp();
						defer.reject("Can't submit form");
					});
					
				}
				});
			}
			else
				defer.reject('g_form not initialized');
			return defer.promise;
		},
		
		setQuantity: function(quantity) {
			if ($scope.c.data.sc_cat_item.sys_class_name !== "sc_cat_item_producer" && $scope.c.data.sc_cat_item.sys_class_name !== "std_change_record_producer") {
				$scope.c.quantity = quantity;
				$scope.$apply();
			}
		},
		
		getQuantity: function() {
			return $scope.c.quantity;
		},
		
		getPrice: function() {
			var obj = {};
			obj.price = $scope.data.sc_cat_item.price_display;
			obj.recurring_price = $scope.data.sc_cat_item.recurring_price_display;
			obj.recurring_frequency = $scope.data.sc_cat_item.recurring_frequency;
			return obj;
		}
	}
	
	c.showAddCartBtn = function() {
		return !$scope.submitted &&
		c.options.show_add_cart_button &&
			c.data.sc_cat_item.sys_class_name !== "sc_cat_item_producer" &&
			c.data.sc_cat_item.sys_class_name !== "std_change_record_producer" &&
			!c.data.sc_cat_item.no_cart && !c.data.is_cart_item;
	}
	
	c.showQuantitySelector = function() {
		// Following if block is code for hard-setting an aria-label on the quantity select box
		// for displaying the label "quantity"
		if($('#catItemQuantity') != null) {
			var quantityElement = $('#catItemQuantity');
			quantityElement.prev().find(".select2-offscreen").removeAttr("aria-labelledby").attr("aria-label","Quantity " + c.quantity);
		}
		
		return c.data.sc_cat_item.sys_class_name !== "sc_cat_item_producer" &&
			c.data.sc_cat_item.sys_class_name !== "std_change_record_producer" &&
			!c.data.sc_cat_item.no_quantity &&
			(c.data.sc_cat_item.cart_guide === undefined || c.data.sc_cat_item.cart_guide === null)&&
			(!c.data.sc_cat_item.no_order_now || !c.data.sc_cat_item.no_cart);
	}
	c.showOrderNowButton = function() {
		return !$scope.data.is_cart_item && (c.data.sc_cat_item.use_sc_layout || !c.data.sc_cat_item.no_order_now);
	}
	c.showAddToWishlist = function () {
		return !$scope.submitted  && 
			(c.data.showWishlist && 
			 !c.data.sc_cat_item.no_wishlist && 
			 !c.data.is_cart_item && 
			 c.options.show_add_to_wishlist_button === 'true');
	}
	c.allowOrder = function() {
		if (c.data.sc_cat_item.use_sc_layout)
			return true;
		if (c.data.sc_cat_item.no_order)
			return false;
		if (c.data.sc_cat_item.no_order_now && c.data.sc_cat_item.no_cart)
			return false;
		return true;
	}
	
	c.hideCartMsg = function () {
		$scope.data.showMsg = false;
	}

	c.showAttachments = function() {
		return !$scope.submitted &&
			!c.data.sc_cat_item.no_attachments &&
			c.data.sc_cat_item.sys_class_name !== "std_change_record_producer";
	};
	$scope.$on('dialog.upload_too_large.show', function(e) {
		$log.error($scope.m.largeAttachmentMsg);
		spUtil.addErrorMessage($scope.m.largeAttachmentMsg);
	});
	$scope.m = $scope.data.msgs;
	var ah = $scope.attachmentHandler = new nowAttachmentHandler(setAttachments, appendError);
	function appendError(error) {
		spUtil.addErrorMessage(error.msg + error.fileName);
	}
	ah.setParams($scope.data._attachmentTable, $scope.data._generatedItemGUID, 1024 * 1024 * $scope.data.maxAttachmentSize);
	function setAttachments(attachments, action) {
		$scope.attachments = attachments;
		if (action === "added") {
			$scope.setFocusToAttachment();
			if ($scope.attachments.length > 0)
			 $scope.data.sc_cat_item.attachment_submitted = true;
		}
		if (action === "renamed")
			spAriaUtil.sendLiveMessage($scope.m.renameSuccessMsg);
		if (action === "deleted") {
			spAriaUtil.sendLiveMessage($scope.m.deleteSuccessMsg);
			if ($scope.attachments.length == 0)
				$scope.data.sc_cat_item.attachment_submitted = false;
		}
		spUtil.get($scope,{action:"from_attachment"});
	}
	$scope.attachmentHandler.getAttachmentList();
	$scope.confirmDeleteAttachment = function(attachment) {
		spModal.confirm($scope.data.msgs.delete_attachment).then(function() {
			$scope.attachmentHandler.deleteAttachment(attachment);
			$scope.setFocusToAttachmentButton();
		});
	}
	$scope.dismissWishListMessage = function() {
		$scope.is_update_wishlist = false;
	}
	
  if ($scope.data.sc_cat_item) {
		$scope.data.sc_cat_item.description = $sce.trustAsHtml($scope.data.sc_cat_item.description);
		if (angular.equals($scope.data.sc_cat_item._fields, {}))
				$scope.data.no_fields = true;
		if ($scope.data.sc_cat_item.sys_class_name !== "sc_cat_item_producer" && 
				$scope.data.sc_cat_item.sys_class_name !== "std_change_record_producer") {	
			if ($scope.data.sc_cat_item.request_method == "request")
				$scope.submitButtonMsg = $scope.m.requestMsg;
			else if ($scope.data.sc_cat_item.request_method == "submit")
				$scope.submitButtonMsg = $scope.m.submitMsg;
		else
				$scope.submitButtonMsg = $scope.m.orderNowMsg;
		} else
			$scope.submitButtonMsg = $scope.m.submitMsg;
		
		// Breadcrumbs
		if (!$scope.data.categories)
			$scope.data.categories = [];
		$scope.data.categories.forEach(function(category, index, categories) {
			categories[index].url = category.url + '&catalog_id=' + $scope.data.catalog_id;
		});
		if ($scope.data.is_wishlist_item) {
			$scope.data.categories.unshift({label: $scope.m.wishlistMsg, url: '?id=sc_wishlist'});
			$scope.data.categories.push({label: $scope.data.sc_cat_item.name, url: '#'});
		}
		else if ($scope.data.is_cart_item) {
			$scope.data.categories.unshift({label: $scope.m.cartMsg, url: '?id=sc_cart'});
			$scope.data.categories.push({label: $scope.data.sc_cat_item.name, url: '#'});
		}
		else if ($scope.data.categories.length > 0) {
			$scope.data.categories.unshift({label: $scope.data.sc_catalog || $scope.page.title, url: '?id=' + $scope.data.sc_category_page + "&catalog_id=" + $scope.data.catalog_id});
			$scope.data.categories.push({label: $scope.data.sc_cat_item.name, url: '#'});
			if ($scope.data.all_catalog_msg) {
				$scope.data.categories.unshift({label: $scope.data.all_catalog_msg, url: '?id=' + $scope.data.sc_category_page + "&catalog_id=-1"});
			}
		}
		else {
			$scope.data.categories.push({label: $scope.data.sc_cat_item.name, url: '#'});
		}
		
		$timeout(function() {
			$scope.$emit('sp.update.breadcrumbs', $scope.data.categories);
		});
		spUtil.setSearchPage('sc');
	} else {
		var notFoundBC = [{label: $scope.page.title, url: '?id=' + $scope.data.sc_catalog_page}];
		$timeout(function() {
			$scope.$emit('sp.update.breadcrumbs', notFoundBC);
		});
		spUtil.setSearchPage('sc');
	};
	c.getItemId = function () {
		return $scope.data.sc_cat_item ? $scope.data.sc_cat_item.sys_id : -1;
	};
	var g_form;
	$scope.$on('spModel.gForm.initialized', function(e, gFormInstance) {
		if (gFormInstance.getSysId() != -1 && gFormInstance.getSysId() != c.getItemId())
			return;
		g_form = gFormInstance;
		spSCNavStateManager.register(g_form);
		$timeout(function() {
				$rootScope.$emit('spModel.gForm.rendered', g_form);
		}, 175);
		
		// This runs after all onSubmit scripts have executed
		g_form.$private.events.on('submitted', function() {
			cleanFailedSubmit();
			$scope.submitting = true;
			if ($scope.data.sc_cat_item.item_action === "order")
				getOne();
			else if ($scope.data.sc_cat_item.item_action === "add_to_cart")
				addToCart();
			else if ($scope.data.sc_cat_item.item_action == "update_cart")
				updateCart();
		});
	});
	function getVarData(fields) {
		var reqData = {};
		for(var obj in fields)
			reqData[fields[obj].name] = fields[obj].value;
		return reqData;
	}
	function addLink(url, msg) {
		return "<a class='link' href=" + url + ">" + msg + "</a>";
	}
	
	$scope.$on("$sp.service_catalog.wishlist.update", function(evt, item) {
		if (item === $scope.data.sys_id)
			$scope.data.show_wishlist_msg = false;
	});
	$scope.addToWishlist = function() {
		var invalid = false;
		Object.keys($scope.data.sc_cat_item._fields).forEach(function (f) {
			if ($scope.data.sc_cat_item._fields[f].isRegexInvalid && $scope.data.sc_cat_item._fields[f].isInvalid)
				invalid = true;
		})
		if (invalid) {
			spUtil.addErrorMessage($scope.m.regexError);
			return;
		}
		$scope.submitting = true;
		$scope.m.actionMsg = $scope.data.is_wishlist_item ? $scope.m.wishlistUpdateMsg : $scope.m.wishlistAddMsg;
		$scope.m.actionMsg += addLink('?id=sc_wishlist', $scope.m.viewWishListMsg);
		$scope.m.actionMsg += '<i class="fa fa-close pull-right pointer close-notification" aria-label="${Close Notification}" tabindex="0" ng-click="c.hideCartMsg()"/>';
		$scope.m.actionMsg = $sce.trustAsHtml($scope.m.actionMsg);
		$scope.is_update_wishlist = false;
		spScUtil.addToWishlist($scope.data.sc_cat_item.sys_id, c.quantity, getVarData($scope.data.sc_cat_item._fields), $scope.data._generatedItemGUID).then(function(response) {
			var cartItemId = "";
			for (var i=0; i<response.data.result.items.length; i++) {
				var item = response.data.result.items[i];
				if (item.catalog_item_id === $scope.data.sc_cat_item.sys_id) {
					cartItemId = item.cart_item_id;
					break;
				}
			}
			$rootScope.$broadcast("$sp.service_catalog.wishlist.add_item");
			$rootScope.$broadcast("$sp.service_catalog.wishlist.update", cartItemId);
			g_form.$private.userState.clearModifiedFields();
			$scope.data.showMsg = $scope.is_update_wishlist = true;
			$scope.data.is_wishlist_item = true;
			$scope.data.show_wishlist_msg = false;
			$scope.submitting = false;
			spUtil.scrollTo('#sc_cat_item', 300);
		});
	}

	$scope.triggerAddToCart = function(timeout) {
		$scope.data.sc_cat_item.item_action = "add_to_cart";
		$scope.data.sc_cat_item.quantity = c.quantity;
		$scope.$evalAsync(function () {
			if (g_form) {
				$scope.submitting = true;
				if (!g_form.submit()) {
					timeout = timeout || 1000;
					$timeout(function () {
						$scope.$broadcast('$sp.service_catalog.form_submit_failed', {action_name: 'submit'});
					}, timeout);
				}
			}
			
		})
		return false;
	}

	$scope.triggerUpdateCart = function(timeout) {
		$scope.data.sc_cat_item.item_action = "update_cart";
		$scope.data.sc_cat_item.quantity = c.quantity;
		$scope.$evalAsync(function () {
			if (g_form) {
				$scope.submitting = true;
				if (!g_form.submit()) {
					timeout = timeout || 1000;
					$timeout(function () {
						$scope.$broadcast('$sp.service_catalog.form_submit_failed', {action_name: 'submit'});
					}, timeout);
				}
			}
			
		})
		return false;
	}

	$scope.triggerOnSubmit = function(timeout) {
		if ($scope.options.isServiceWorkspace && $window.frameElement) {
			var workspaceParams = {};
			workspaceParams.sysparm_parent_table = $window.frameElement.getAttribute('parent-table');
			workspaceParams.sysparm_parent_sys_id = $window.frameElement.getAttribute('parent-sys-id');
			$scope.data.workspaceParams = workspaceParams;
		}
		$scope.data.sc_cat_item.item_action = "order";
		$scope.data.sc_cat_item.quantity = c.quantity;
		$scope.$evalAsync(function () {
			if (g_form) {
				$scope.submitting = true;
				if (!g_form.submit()) {
					timeout = timeout || 1000;
					$timeout(function () {
						$scope.$broadcast('$sp.service_catalog.form_submit_failed', {action_name: 'submit'});
					}, timeout);
				}
			}
			
		})
		return false;
	}
	function setFieldsReadonly() {
		var allFields = g_form.getFieldNames();
		for (var fieldName in allFields) {
			g_form.setReadonly(allFields[fieldName], true);
		}
	}
	// order / create request
	function getOne() {
		$scope.server.get({
			action: 'log_request',
			itemDetails: {
				sys_id: $scope.data.sc_cat_item.sys_id,
										name: $scope.data.sc_cat_item.name,
				sys_class_name: $scope.data.sc_cat_item.sys_class_name
			}
		});
		//Required to pass as payload for usage as embeddedWidget
		var embeddedWidgetOptions = {
			"auto_redirect" : "true",
			"requested_for_id" : "",
			"requested_for_display" : ""
		};
		if ($scope.data.sc_cat_item.sys_class_name != "sc_cat_item_producer" && $scope.data.sc_cat_item.sys_class_name != "std_change_record_producer") {
			if ($scope.data.sys_properties.twostep && $scope.data.sc_cat_item.request_method != "submit") {
				var payload = {
					cart: 'cart_' + $scope.data.sc_cat_item.sys_id,
					itemDetails: {
						sys_id: $scope.data.sc_cat_item.sys_id, 
						quantity: $scope.data.sc_cat_item.quantity, 
						fields: getVarData($scope.data.sc_cat_item._fields), 
						newRecordID: $scope.data._generatedItemGUID,
						request_method : $scope.data.sc_cat_item.request_method
					},
					action: $scope.data.is_wishlist_item ? "order_wishlist_item" : "order_item",
					workspaceParams: $scope.data.workspaceParams
				};
				for (var embeddedOption in embeddedWidgetOptions) {
					payload[embeddedOption] = c.options[embeddedOption] || embeddedWidgetOptions[embeddedOption];
				}
				$scope.server.get(payload).then(function(response) {
					var orderItemModalCtrl;
					var unregister = $scope.$on('$sp.service_catalog.cart.cancel_order', function() {
						$scope.submitting = false;
						orderItemModalCtrl.close();
					});
					var closeModalOnSubmit = $scope.$on('$sp.service_catalog.cart.submitted', function(){
						orderItemModalCtrl.close();
						setFieldsReadonly();
						$scope.submitted = true;
					});
					var orderItemModal = angular.copy(response.data.orderItemModal);
					orderItemModal.options.afterOpen = function(ctrl){
						orderItemModalCtrl = ctrl;
					};
					orderItemModal.options.afterClose = function() {
							unregister();
							closeModalOnSubmit();
							c.orderItemModal = null;
							orderItemModalCtrl = null;
						};
						c.orderItemModal = orderItemModal;
					});
			} else {
				var additionalParms = {};
				if ($scope.data.workspaceParams) {
					additionalParms.sysparm_parent_sys_id = $scope.data.workspaceParams.sysparm_parent_sys_id;
					additionalParms.sysparm_parent_table = $scope.data.workspaceParams.sysparm_parent_table;
				}
				$scope.submitting = true;
				if ($scope.data.is_wishlist_item) {
					spScUtil.orderWishlistedItem($scope.data.sc_cat_item.sys_id, $scope.data.sc_cat_item.quantity, getVarData($scope.data.sc_cat_item._fields), $scope.data._generatedItemGUID, additionalParms).then(function(response) {
						var a = response.data.result;
						$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') {
							$scope.submitting = false;
							$scope.submitted = true;
							$rootScope.$broadcast("$sp.service_catalog.cart.submitted", true);
							spUtil.addInfoMessage($scope.m.requestSubmitted);
							return;
						} else {
							//$location.search('id=sc_request&is_new_order=true&table=sc_request&sys_id=' + a.sys_id);							
							c.data.myrequest = a.sys_id;
							c.server.update();
							
							setTimeout(function(){
								var ritmId = c.data.ritmId;
								$location.search('sys_id=' + ritmId + '&id=ticket&table=sc_req_item');
							}, 500);
						}
					});
				}
				else {
					spScUtil.orderNow($scope.data.sc_cat_item.sys_id, $scope.data.sc_cat_item.quantity, getVarData($scope.data.sc_cat_item._fields), $scope.data._generatedItemGUID, additionalParms).then(function(response) {
						var a = response.data.result;
						$scope.$emit("$$uiNotification", a.$$uiNotification);
						$scope.$emit("$sp.sc_cat_item.submitted", a);
						if (c.options.auto_redirect == 'false') {
							$scope.submitting = false;
							$scope.submitted = true;
							$rootScope.$broadcast("$sp.service_catalog.cart.submitted", true);
							spUtil.addInfoMessage($scope.m.requestSubmitted);
							return;
						} else if (!$scope._atf) {
							//$location.search('id=sc_request&is_new_order=true&table=sc_request&sys_id=' + a.sys_id);							
							c.data.myrequest = a.sys_id;
							c.server.update();
							
							setTimeout(function(){
								var ritmId = c.data.ritmId;
								$location.search('sys_id=' + ritmId + '&id=ticket&table=sc_req_item');
							}, 500);
						}
					}, function() {
						$scope.$emit('$sp.sc_cat_item.submit_failed');
					});
				}
			}
		} else {
			postCatalogFormRequest().then(function(response) {
				var a = response.data.result;
				if (!$scope.options.isServiceWorkspace)
				$scope.$emit("$$uiNotification", a.$$uiNotification);
				$scope.$emit("$sp.sc_cat_item.submitted", a);
				if ($scope.data.is_wishlist_item)
					$rootScope.$broadcast("$sp.service_catalog.wishlist.update");
				if (c.options.auto_redirect == 'false') {
					setFieldsReadonly();
					$scope.submitted = true;
				} else if (!$scope._atf) 
					{
						//handleRedirect(a.number, a.table, a.sys_id, a.redirect_to, a.redirect_portal_url);						
						c.data.myrequest = a.sys_id;
						c.server.update();
						
						setTimeout(function(){
							var ritmId = c.data.ritmId;
							$location.search('sys_id=' + ritmId + '&id=ticket&table=sc_req_item');
						}, 500);
					}						
				$scope.submitting = false;
				$scope.submitButtonMsg = $scope.m.submittedMsg;
			});
		}
	}

	$scope.$on("$sp.sc_cat_item.submitted", function(){
		g_form.$private.userState.clearModifiedFields();
	});
	
	function addToCart() {
		$scope.server.get({
			action: 'log_request',
			itemDetails: {sys_id: $scope.data.sc_cat_item.sys_id, 
										name: $scope.data.sc_cat_item.name,
										sys_class_name: $scope.data.sc_cat_item.sys_class_name}
		});
		
		postCatalogFormRequest().then(function(response) {
			$rootScope.$broadcast("$sp.service_catalog.cart.add_item");
			$rootScope.$broadcast("$sp.service_catalog.cart.update");
			$scope.$emit("$sp.sc_cat_item.add_to_cart", $scope.data._generatedItemGUID);
			if ($scope.data.is_wishlist_item) {
				$rootScope.$broadcast("$sp.service_catalog.wishlist.update");
				$scope.data.is_wishlist_item = false;
				if ($location.$$search.edit === "wishlist") {
					$location.search("id=sc_wishlist");
					return;
				}
			}
			g_form.$private.userState.clearModifiedFields();
			c.status = i18n.getMessage("Added item to shopping cart");
			$scope.server.get({action: 'init_item'}).then(function(response) {
				$scope.data._generatedItemGUID = response.data._generatedItemGUID;
				ah.setParams($scope.data._attachmentTable, $scope.data._generatedItemGUID, 1024 * 1024 * $scope.data.maxAttachmentSize);
				$scope.attachmentHandler.getAttachmentList();
				$scope.m.actionMsg = $scope.m.cartAddMsg + addLink('?id=sc_cart', $scope.m.viewCartMsg);
				$scope.m.actionMsg += '<i class="fa fa-close pull-right pointer close-notification" aria-label="${Close Notification}" tabindex="0" ng-click="c.hideCartMsg()"/>';
				$scope.m.actionMsg = $sce.trustAsHtml($scope.m.actionMsg);
				$scope.data.showMsg = true;
				$scope.submitting = false;
				cleanFailedSubmit = $scope.$on('$sp.service_catalog.form_submit_failed', function() { $scope.submitting = false; });
				spUtil.scrollTo('#sc_cat_item', 300);
			});
		});
	}
	function updateCart() {
		postCatalogFormRequest().then(function(response) {
			g_form.$private.userState.clearModifiedFields();
			c.status = i18n.getMessage("Updated Item to shopping cart.");
			$location.search('id=sc_cart');
		})
	}
	function postCatalogFormRequest() {
		$scope.submitting = true;
		if ($scope.data.is_wishlist_item) {
			$scope.is_update_wishlist = false;
			$scope.data.show_wishlist_msg = false;
			if ($scope.data.sc_cat_item.sys_class_name === "sc_cat_item_producer")
				return spScUtil.submitWishlistedProducer($scope.data.sc_cat_item.sys_id, getVarData($scope.data.sc_cat_item._fields), $scope.data._generatedItemGUID, $scope.data.workspaceParams);
			else if ($scope.data.sc_cat_item.item_action === "add_to_cart")
				return spScUtil.addWishlistedItemToCart($scope.data.sc_cat_item.sys_id, $scope.data.sc_cat_item.quantity, getVarData($scope.data.sc_cat_item._fields), $scope.data._generatedItemGUID);
		}
		else if ($scope.data.is_cart_item)
			return spScUtil.updateCart($scope.data._generatedItemGUID, $scope.data.sc_cat_item.quantity, getVarData($scope.data.sc_cat_item._fields));
		else if ($scope.data.sc_cat_item.sys_class_name === "sc_cat_item_producer")
			return spScUtil.submitProducer($scope.data.sc_cat_item.sys_id, getVarData($scope.data.sc_cat_item._fields), $scope.data._generatedItemGUID, $scope.data.workspaceParams);
		else if ($scope.data.sc_cat_item.sys_class_name === "std_change_record_producer")
			return spScUtil.submitStdChgProducer($scope.data.sc_cat_item.sys_id, $scope.data.stdChg.twoStep, $scope.data.stdChg.currentVersion, $scope.data._generatedItemGUID, $scope.portal.url_suffix);
		else if ($scope.data.sc_cat_item.item_action === "add_to_cart")
			return spScUtil.addToCart($scope.data.sc_cat_item.sys_id, $scope.data.sc_cat_item.quantity, getVarData($scope.data.sc_cat_item._fields), $scope.data._generatedItemGUID);
	}
	// spModel populates mandatory - hasMandatory is called by the submit button
	$scope.hasMandatory = function() {
		return c.mandatory && c.mandatory.length > 0;
	};
	
	//	Listeners
	var cleanFailedSubmit = $scope.$on('$sp.service_catalog.form_submit_failed', function() { $scope.submitting = false; });
	
	// switch catalog items
	var unregister = $scope.$on('$sp.list.click', onListClick);
	$scope.$on("$destroy", function() {
		$rootScope.$broadcast("$sp.service_catalog.item.close");
		unregister();
	});
	function onListClick(evt, arg) {
		$scope.data.sys_id = arg.sys_id;
		spUtil.update($scope);
	}
	
	function formatRedirectUrl(page, table, sys_id) {
		var url;
		var paramObj = {page: page, table: table, sys_id: sys_id};
		url = spUtil.format(c.options.url, paramObj);
		return url;
	}
	
	function handleRedirect(n, table, sys_id, redirectTo, redirectUrl) {
		var page = 'form';
		if (table == 'sc_request')
			page = 'sc_request';
		else if (n)
			page = 'ticket';
		
		if (redirectTo == 'catalog_home') 
			page = 'sc_home';

		//For Standard change, always direct to form if not in Workspace
		if ($scope.data.sc_cat_item.sys_class_name === "std_change_record_producer") {
			if ($scope.options.isServiceWorkspace) {
				var params = {};
				params.msg = 'TARGET_RECORD_SELECTED';
				params.target_table = table;
				params.target_sys_id = -1;
				if (sys_id)
					params.target_sys_id = sys_id;

				if ($scope.data.stdChg.twoStep)
					params.target_query = 'type=standard^std_change_producer_version=' + $scope.data.stdChg.currentVersion;

				window.postMessage(params, location.origin);
				return;
			} else
			page = 'form';
		}

		if (c.options.page) {
			page = c.options.page;
		}
		if (c.options.table) {
			table = c.options.table;
		}
		var url = formatRedirectUrl(page, table, sys_id);
		if ($scope.data.sc_cat_item.sys_class_name === "sc_cat_item_producer" || $scope.data.sc_cat_item.sys_class_name === "std_change_record_producer") {
			if (redirectUrl) {
				$window.location.href = redirectUrl;
			} else {
				var newURL = $location.search(url);
		        spAriaFocusManager.navigateToLink(newURL.url());
			}
			return;
		}
		$location.search(formatRedirectUrl('sc_request', 'sc_request', sys_id));
		return;
	}
    
    $timeout(function() {
        if ($document[0].getElementsByClassName('sc-sticky-item-header').length > 0) {
            var titleHeight = $document[0].getElementsByClassName('sc-sticky-item-header')[0].clientHeight;
            $scope.stickyHeaderTop = '-' + (titleHeight - 20 - $document[0].getElementsByClassName('sc-cat-item-short-description')[0].clientHeight) + 'px;';
        }
    });
}

SC Catalog Item v3 - Server Script

// populate the 'data' variable with catalog item, variables, and variable view
(function() {
	var localInput = input;	//to safeguard pollution of "input" via BR or other scripts
	var embeddedWidgetOptions = ['auto_redirect', 'requested_for_id', 'requested_for_display'];
	if (localInput && localInput.action == "from_attachment")
		return;
	
	if(input && input.myrequest){
		var ritm = new GlideRecord('sc_req_item');
		ritm.addQuery('request', input.myrequest);
		ritm.query();
		if(ritm.next()){
			data.ritmId = ritm.getUniqueValue();
		}
	}
	
	if (localInput && localInput.action == 'init_item') {
		data._generatedItemGUID = gs.generateGUID();
		return;
	}
	else if (localInput && localInput.action === "order_one_step") {

	}
	else if (localInput && localInput.action === "order_item") {
		//Minimum set of widget options supported for Embedded widget
		embeddedWidgetOptions.forEach(function (embeddedWidgetOption) {
			if (typeof localInput[embeddedWidgetOption] != 'undefined')
				options[embeddedWidgetOption] = localInput[embeddedWidgetOption];
		});
		data.orderItemModal = $sp.getWidget('widget-modal', {
			embeddedWidgetId: 'sc-checkout', 
			embeddedWidgetOptions: {
				cart: {name: localInput.cart}, 
				action: 'order_now', 
				item: localInput.itemDetails, 
																																requested_for: {id:options.requested_for_id, displayValue:options.requested_for_display},
																																auto_redirect: options.auto_redirect,
																																parentParams: localInput.workspaceParams
			}, 
			backdrop: 'static', 
			keyboard: false, 
			size: 'md'
		});
		return;
	} else if (localInput && localInput.action == "order_wishlist_item") {
		//Minimum set of widget options supported for Embedded widget
		embeddedWidgetOptions.forEach(function (embeddedWidgetOption) {
			if (typeof localInput[embeddedWidgetOption] != 'undefined')
				options[embeddedWidgetOption] = localInput[embeddedWidgetOption];
		});
		data.orderItemModal = $sp.getWidget('widget-modal', {
			embeddedWidgetId: 'sc-checkout', 
			embeddedWidgetOptions: {
				cart: {name: localInput.cart}, 
				action: 'order_now_wishlisted_item', 
				item: localInput.itemDetails, 
																																	requested_for: {id:options.requested_for_id, displayValue:options.requested_for_display},
																																	auto_redirect: options.auto_redirect,
																																	parentParams: localInput.workspaceParams
			}, 
			backdrop: 'static', 
			keyboard: false, 
			size: 'md'
		});
		return;
	} else if (localInput && localInput.action === 'log_request') {
		 $sp.logStat('Cat Item Request', localInput.itemDetails.sys_class_name, localInput.itemDetails.sys_id, localInput.itemDetails.name);
		 return;
	}
	
	// portal can specify a catalog and catalog category home page
	var catalogID = $sp.getParameter("catalog_id") ? $sp.getParameter("catalog_id") + "" : "-1";
	data.sc_catalog_page = $sp.getDisplayValue("sc_catalog_page") || "sc_home";
	data.sc_category_page = $sp.getDisplayValue("sc_category_page") || "sc_category";
	var edit_parm = $sp.getParameter('edit');
	data.is_cart_item = edit_parm == 'cart';
	data.is_wishlist_item = edit_parm == 'wishlist';
	data.show_wishlist_msg = false;
	data.recordFound = true;
	options.show_add_cart_button = (options.show_add_cart_button == "true");
	
	var clGenerator = new GlideChoiceList();
	var choiceListQuantity = clGenerator.getChoiceList("sc_cart_item", "quantity");
	var choicelistQuantityData = [];
	for (var i = 0; i < choiceListQuantity.size(); i++) {
		var choice = choiceListQuantity.get(i);
		if (!isNaN(choice.getValue()))
			choicelistQuantityData.push({value : parseInt(choice.getValue()), label : choice.getLabel()});
	}
	data.choiceListQuantity = choicelistQuantityData;
	data.quantity = choicelistQuantityData[0].value;
	if (options.page) {
		var pageGR = new GlideRecord("sp_page");
		options.page = (pageGR.get(options.page)) ? pageGR.getValue("id") : null;
	}
	if (options.table) {
		var tableGR = new GlideRecord("sys_db_object");
		options.table = (tableGR.get(options.table)) ? tableGR.getValue("name") : null;
	}
	options.url = options.url || "id={page}&is_new_order=true&table={table}&sys_id={sys_id}";
	
	data.showPrices = $sp.showCatalogPrices();
	var m = data.msgs = {};
	m.submitMsg = gs.getMessage("Submit");
	m.requestMsg = gs.getMessage("Request");
	m.orderNowMsg = gs.getMessage("Order Now");
	m.submittedMsg = gs.getMessage("Submitted");
	m.createdMsg = gs.getMessage("Created");
	m.trackMsg = gs.getMessage("track using 'Requests' in the header or");
	m.clickMsg = gs.getMessage("click here to view");
	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.wishlistMsg = gs.getMessage('Wish List');
	m.cartMsg = gs.getMessage('Cart');
	m.itemWishlistMsg = gs.getMessage('This item is already in your Wish List. If you attempt to add this item to your Wish List it will overwrite the existing item.');
	m.invalidRecordMsg = gs.getMessage('You are either not authorized or record is not valid.');
	m.wishlistUpdateMsg = gs.getMessage('Your Wish List has been updated.');
	m.wishlistAddMsg = gs.getMessage('Your item has been added to your Wish List.');
	m.cartAddMsg = gs.getMessage('Your item has been added to your Cart. To make changes to the items in your cart, click ');
	m.viewWishListMsg = gs.getMessage('View Wish List');
	m.viewCartMsg = gs.getMessage('View Cart');
	m.delete_attachment = gs.getMessage("Delete Attachment?");
	m.regexError = gs.getMessage("Item with invalid variable can't be saved");
	m.requestSubmitted = gs.getMessage("Thank you, your request has been submitted.");
	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 cartName = data.is_cart_item ? 'DEFAULT' : 'saved_items';
	var cart = new sn_sc.CartJS(cartName);
	
	if (edit_parm) {
		var cart_item_id = $sp.getParameter("sys_id");
		var gr = new GlideRecord("sc_cart_item");
		if (!gr.get(cart_item_id) || gr.cart != cart.getCartID()) {
			data.recordFound = false;
			return;
		}
		data.showWishlist = data.is_wishlist_item;
		var catItemData = {};
		catItemData.sys_id = gr.getValue('cat_item');
		catItemData.cart_item_id = gr.getUniqueValue();
		catItemData.table = "sc_cart_item";
		catItemData.is_ordering = true;
		data.sc_cat_item = $sp.getCatalogItem(catItemData);
		data.sc_cat_item.isCartItem = true;
		data.sc_cat_item.cart_guide = gr.getValue('order_guide');
		data.hideDeliveryTime = data.sc_cat_item.no_delivery_time;
		if (!data.hideDeliveryTime)
		data.hideDeliveryTime = (options.hide_delivery_time == "true" || data.sc_cat_item.sys_class_name == 'sc_cat_item_producer' || data.sc_cat_item.sys_class_name == 'sc_cat_item_guide' || data.sc_cat_item.sys_class_name == 'std_change_record_producer');

		var values = getValues(cart_item_id);
		for(var f in data.sc_cat_item._fields) {
			// Put the values into the cat item fields
			var field = data.sc_cat_item._fields[f];
			if (typeof values[f] != "undefined" && typeof values[f].value != "undefined") {
				if (values[f].type == 9 || values[f].type == 10)
					field.value = values[f].displayValue;
				else if (values[f].type == 25)
					field.value = values[f].decrypted_value;
				else
					field.value = values[f].value;
				field.displayValue = values[f].displayValue;
				field.display_value_list = values[f].display_value_list;
			}
			updatePriceOnField(field);
				
		}
		data._generatedItemGUID = cart_item_id;
		data.quantity = '' + gr.quantity;
	} else {
	
		if (localInput)
			data.sys_id = localInput.sys_id;
		else if (options.sys_id)
			data.sys_id = options.sys_id;
		else
			data.sys_id = $sp.getParameter("sys_id") || $sp.getParameter('sl_sys_id');
	
		if (!data.sys_id) {
			data.recordFound = false;
			return;
		}
	
		data._generatedItemGUID = gs.generateGUID();
		var validatedItem = new sn_sc.CatItem('' + data.sys_id);
		if (!validatedItem.canView() || !validatedItem.isVisibleServicePortal()) {
			data.recordFound = false;
			return;
		}
	
		data.sc_cat_item = $sp.getCatalogItem({
			sys_id: data.sys_id + '',
			is_ordering: true
		});
		data.hideDeliveryTime = data.sc_cat_item.no_delivery_time;
		if (!data.hideDeliveryTime) 
		data.hideDeliveryTime = (options.hide_delivery_time == "true" || data.sc_cat_item.sys_class_name == 'sc_cat_item_producer' || data.sc_cat_item.sys_class_name == 'sc_cat_item_guide' || data.sc_cat_item.sys_class_name == 'std_change_record_producer');

		if (data.sc_cat_item.category) {
			var categoryJS;
			var categoryID = validatedItem.getFirstAccessibleCategoryForSearch((catalogID && catalogID != "-1") ? catalogID : $sp.getCatalogs().value + "");
			if (GlideStringUtil.isEligibleSysID($sp.getParameter("sysparm_category"))) {
				categoryJS = new sn_sc.CatCategory($sp.getParameter("sysparm_category") + "");
				categoryID = $sp.getParameter("sysparm_category") + "";
			}
			else if(categoryID) {
				categoryJS = new sn_sc.CatCategory(categoryID);
			}
			if (categoryJS && GlideStringUtil.isEligibleSysID(categoryJS.getID())) {
				if (categoryJS.getCatalog()) {
					catalogID = categoryJS.getCatalog();
					data.catalog_id = catalogID;
					var catalogObj = new sn_sc.Catalog(catalogID);
					data.sc_catalog = catalogObj.getTitle();
					data.showWishlist = new sn_sc.Catalog('' + catalogID).isWishlistEnabled();
				}
				data.category = {
					name: categoryJS.getTitle(),
					url: '?id=' + data.sc_category_page + '&sys_id=' + categoryID
				}
				data.categories = [];
				data.categories.push({
					label: categoryJS.getTitle(),
					url: '?id=' + data.sc_category_page + '&sys_id=' + categoryID
				});
				while(categoryJS.getParent()) {
					var parentId =  categoryJS.getParent();
					categoryJS = new sn_sc.CatCategory(parentId);
					var category = {
						label: categoryJS.getTitle(),
						url: '?id=' + data.sc_category_page + '&sys_id=' + parentId
					};
					data.categories.unshift(category);
				}
				if ((($sp.getCatalogs().value + "").split(",")).length > 1) {
					data.all_catalog_msg = gs.getMessage("All Catalogs");
				}
			}
		}

		var gr = new GlideRecord('sc_cart_item');
		gr.addQuery('cart', cart.getCartID());
		gr.addQuery('cat_item', data.sys_id);
		gr.query();
		if (gr.next() && !options.isServiceWorkspace)
		{
			data.show_wishlist_msg = true;
		}
	}
	data.sys_properties = {
		twostep: gs.getProperty("glide.sc.sp.twostep", "true") == 'true'
	};
	var athTblName = 'sc_cart_item';
	var className = data.sc_cat_item.sys_class_name;
	if (!new global.CatalogItemTypeProcessor().canCreateNormalCartItem(className)) {
		if (className == 'sc_cat_item_producer' || className == 'std_change_record_producer') {
				var gr = new GlideRecord(className);
				gr.get(data.sc_cat_item.sys_id);
				if (gr.isValidRecord())
					athTblName = gr.getValue('table_name');
		}
	}
	
	data._attachmentTable = athTblName;
	data.stdChg = {};
	if (className === 'std_change_record_producer') {
		//Populate scope with the porperty for two step
		data.stdChg.twoStep = false;
		var twoStepProp = new global.StdChangeUtils().getValue('two_step') + '';
		if (twoStepProp)
			data.stdChg.twoStep = twoStepProp === '1';
		var stdChgProducerGr = new GlideRecord('std_change_record_producer');
		stdChgProducerGr.get(data.sc_cat_item.sys_id);
		if (stdChgProducerGr.isValidRecord())
			data.stdChg.currentVersion = stdChgProducerGr.getValue('current_version');
	}

	$sp.logStat('Cat Item View', data.sc_cat_item.sys_class_name, data.sc_cat_item.sys_id, data.sc_cat_item.name);
	
	function getValues(sys_id) {
		var qs = new sn_sc.VariablePoolQuestionSetJS();
		qs.setCartID(sys_id);
		qs.load();
		var values = {};
		var questions = qs.getFlatQuestions();
		for (var i = 0; i < questions.length; i++) {
			var qKey = questions[i].name;
			if (typeof qKey == 'undefined' || qKey == '')
				qKey = "IO:" + questions[i].sys_id;
			values[qKey] = questions[i];
		}
		return values;
	}
	function setPrice(field, p, rp) {
		if (p != undefined)
			field.price = p;
		if (rp != undefined)
			field.recurring_price = rp;
	}
	function updatePriceForReferenceTable(field) {
		var tableName = field.refTable + '';
		if (tableName != undefined && tableName != null && tableName != '') {
			var gr = new GlideRecord(tableName);
			if (gr.isValid()) {
				if (gr.get(field.value) && gr.isValidRecord()) {
					updatePrice(gr, field);
					updateRecurringPrice(gr, field);
				}
			}
		}
	}
	function updatePriceForListCollector(field) {
		var tableName = field.refTable + '';
		if (tableName != undefined && tableName != null && tableName != '') {
			var gr = new GlideRecord(tableName);
			if (gr.isValid()) {
				var values = field.value.split(',');
				gr.addQuery('sys_id', values);
				gr.query();
				var p = 0.0;
				var rp = 0.0;
				var price_value_list = [];
				while(gr.next()) {
						var price_field = {};
						updatePrice(gr, price_field);
						updateRecurringPrice(gr, price_field);
						if (price_field.price)
							p += Number(price_field.price);
						else
							price_field.price = 0.0;
						if (price_field.recurring_price)
							rp += Number(price_field.recurring_price);
						else
							price_field.recurring_price = 0.0;
						price_value_list.push(price_field);
				}
				field.price = p;
				field.recurring_price = rp;
				field.price_value_list = price_value_list;
			}
		}
	}
	function updatePrice(gr, field) {
		if (gr.isValidField('price'))
			field.price = gr.getValue('price');
		else if (gr.isValidField('u_price'))
			field.price = gr.getValue('u_price');
	}
	function updateRecurringPrice(gr, field) {
		if (gr.isValidField('recurring_price'))
			field.recurring_price = gr.getValue('recurring_price');
		else if (gr.isValidField('u_recurring_price'))
			field.recurring_price = gr.getValue('u_recurring_price');
	}
	function updatePriceOnField(field) {
		if (field.type == 'boolean' || field.type == 'boolean_confirm') {
			if (field.value == 'true' || field.value == true)
				setPrice(field, field._pricing.price_if_checked, field._pricing.recurring_price_if_checked);
			else
				setPrice(field, 0, 0);
		} else if (field.choices) {
			field.choices.forEach( function(choice) {
				if (choice.value +'' == field.value + '')
					 setPrice(field, choice.price, choice.recurring_price);
			});
		} else if (field._pricing && field._pricing.pricing_implications === true) {
			if (field.type == 'reference') 
				updatePriceForReferenceTable(field);
			else if (field.type == 'glide_list')
				updatePriceForListCollector(field);
		}
	}
})()

Any suggestions?

5 REPLIES 5

Brad Bowman
Kilo Patron
Kilo Patron

Hi Matt,

I assume you're referring to the Order Status shown after checkout in the native UI (non-Portal)?

find_real_file.pngTo get this to display the RITM# instead of REQ#, go to Service Catalog > Catalog Definition > Maintain Cart Layouts on the left nav.  In the Target type: Browser Screen section, open Order Status Screen.  On the components tab, uncheck Request Number.  On the Columns tab, check Requested Item Number column.

find_real_file.png

find_real_file.png

 

Handy walk-through, but what I really want is for the user to not have to click another link to go to the Request Item.  We want the user to be able to click "Submit" and they are redirected to the Request Item, not the Request level.

Do you have something custom in place now where a user is redirected to the newly-created Request (REQ) record instead of the Order Status pictured above, or are they taken to the Order Status, but you want them to be redirected to the newly-created Requested Item (RITM) record, or is this native Service Catalog UI not what you meant by 'ITIL View'?  In the native Service Catalog, requests can be added to the cart, if enabled, or there's an 'Order Now' button, not 'Submit'.

Users are redirected to the "Order Status" after they click on the "Submit" button to request the item.  The requirement is to redirect the users directly to the RITM (Requested Item) after submission, not the "Order Status" page.

 

find_real_file.png