How to create a catalog item with a user specified cost

jamesmcwhinney
Giga Guru

Background:

We are trying to replace our old online capital expenditure request form by using service now.

For some of the use cases, predetermined catalog items like laptops and cell phones will be available in the catalog and can be added to the cart.

However, the majority of the use cases require the user to be able to manually specify line items and descriptions.

Unfortunately, the Service Catalog Variable Pricing - ServiceNow Wiki capability does not allow full-on user entered pricing.

At best, this would allow us to offer a reference box containing a predetermined set of prices and allow the user to choose from those.

Workaround for user entered variable pricing via an actual text box:

First, I created a new table called "user prices" to hold a set of user entered prices.

The table has two columns:

  • "User Cart" which is a reference to the sc_cart table.
  • "u_price" which is an integer field to hold a custom cost.

Next, I created a new catalog item "Manually entered expenses" with 4 text field variables to store the user entered costs for 4 line items.

I also added a reference field variable called u_price with the label "Total Cost" which is a reference to the new "user prices" table and has the "Pricing Implications" box checked.

(Checking the pricing implications box will cause the catalog to add the related u_price value to the total cost of this item).

UserEnteredPricing.JPG

We now have a catalog item that will allow a user to choose the cost of the item from the list of costs in that table.

But we want the user to be able to just type in 4 costs and use the total of those instead....

...So the next step is to create a catalog client script to total those 4 costs up, create a record in the new "user prices" table, and set the total cost box to the new record we created.

I created a catalog client script "Manual Expense Save" as follows:

Name: "Manual Expense Save"

Type: onSubmit

Applies to: catalog item

Catalog item: (Our catalog item "Manually entered expenses")

Applies on Catalog Item view: Yes

Applies on Requested Items: No

Applies on Catalog Tasks: No

Catalog Client Script: "Manual Expense Save"

function onSubmit() {

      //Get Current User

  var UserSysID = g_user.userID;

  //Get Costs from form

  var Cost1 = g_form.getIntValue('variables.item1_cost');

  var Cost2 = g_form.getIntValue('variables.item2_cost');

  var Cost3 = g_form.getIntValue('variables.item3_cost');

  var Cost4 = g_form.getIntValue('variables.item4_cost');

  var TotalCost = Cost1 + Cost2 + Cost3 + Cost4;

  //Add a new record in the custom table (cart id, cost)

  var ga = new GlideAjax('AJAXOtherExpense');

  ga.addParam('sysparm_name','setCatItemCost');

  ga.addParam('sysparm_totalcost',TotalCost);

  ga.addParam('sysparm_usersysid',UserSysID);

  ga.getXMLWait();

  var ReferenceID = "" + ga.getAnswer();

  g_form.setValue('variables.u_price',ReferenceID);

}

Now we need to write a script include to handle for the server side.

This will get the users current cart, and then add a record to the new "user prices" table with the total price of the 4 user entered costs.

It will then return the sys_id of the new row generated, so that the client script can use it to set the reference box to that value.

Script Include: AJAXOtherExpense

var AJAXOtherExpense = Class.create();

AJAXOtherExpense.prototype = Object.extendsObject(AbstractAjaxProcessor, {

  setCatItemCost: function() {

  //Get Users Cart

  var UserSysID = this.getParameter('sysparm_usersysid');

  var CartID = '0';

  var gr = new GlideRecord('sc_cart');

  gr.addQuery('user', UserSysID);

  gr.query();

  while (gr.next()) {

  CartID = gr.getValue('sys_id');

  }

  //Add Total Cost to available Costs and return the sysID of the new row

  var TotalCost = this.getParameter('sysparm_totalcost');

  var gr = new GlideRecord('u_smse_catalogitem_prices');

  gr.initialize();

  gr.u_price = TotalCost;

  gr.u_cart = CartID;

  return gr.insert();

    }

});

We now have full-on user specified pricing for our catalog item.   But we have an ugly "Total Cost" variable which we may not want the user to see or mess with.

To hide the total cost field, we need to create another catalog client script "Manual Expense Onload" to hide the total cost variable:

Name: "Manual Expense Onload"

Type: OnLoad

Applies on Catalog Item View: Yes

Applies on Requested Items: Yes

Applied on Catalog Tasks: No

Catalog Client Script: Manual Expense Onload

function onLoad() {

  g_form.setDisplay('variables.u_price', false);

}

Its a hack for sure,.. but its the best workaround Ive been able to come up with so far.

If anyone has any other suggestions for a better way to go about it Id love to hear them.

Note that I included a reference to the cart in the "user prices" table so that the table could be cleared out periodically if needed without affecting any carts that were still active.

OrderItem.jpg

Checkout.JPG

7 REPLIES 7

Katie A
Mega Guru

I am having the exact same issue. This is surprising that out-of-box there is nothing that will calculate the price for you based on the number of a line item. For example, I am trying to make a SIMPLE form that calculates the price based on the specifications for a VM.



I want to be able to let the user enter in a number for the number of GB, a number for the number of cores, and a number for the amount of storage and have the system calculate the total cost at the end.



Thank you for sharing, although I think the amount of scripting involved may be too tedious as a workaround for our purposes.



I will suggest that we both submit an enhancement request and hopefully more people will do the same.


I submitted an Enhancement Request for that EXACT scenario KDA617! I've seen others with this same scenario trying to figure this out too. It's clearly a common need


Has there been any traction this?   I have a similar situation where the price of a catalog item must be calculated dynamically via client scripts and then updated accordingly and reflected on the catalog item form, but it doesn't appear to be possible.


Not as far as Im aware,. =\