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

Wendy12
Tera Contributor

Look at the Service Portal > Page Route Map.  Would routing from the sc_request direct to the sc_req_item work for you? (and checking/deactivating any maps you may find that stop at the order status)