gustavopetta
ServiceNow Employee
ServiceNow Employee

 

Goal

This guide walks you through the process of delivering a sample contract using a quote and opportunity in ServiceNow. We are going to use the best practises for Document Templates that was built on Sales and Order Management (SOM) module.


1. Install Document Templates Plugin

To start using templates, make sure the Document Templates plugin is installed.

  • Plugin Name: sc_doc

  • After installation, you'll be able to create reusable templates and attach them to several processes such as: Opportunities and Quotes.

gustavopetta_1-1752890187725.png

Plugin Document Templates


2. Creating a Template

Based on the customer demand, multiple templates can be created and linked to a quote.

In our use case, we created an HTML template to generate a sales contract with:

  • Product descriptions </>
  • Budget spreadsheets </>
  • Technologies involved 📄

  • Contractual clauses 📄

gustavopetta_0-1753018685196.png

gustavopetta_1-1753018809055.png

HTML Document Template View

 

🔗 Official ServiceNow guide on setting up HTML document template


3. Template Scripts Used

In order to retrieve all necessary information, custom scripts may be required to extract details not directly available on the quote record.

Here are two examples:

 

  • Product Descriptions: All the information of the products can be found on the line items.

Here we have an example how to create HTML Template Script:

 

gustavopetta_4-1753019441810.png

(function runTemplateScript(target, docTemplate) {

    var html = '', count = 1;

    // Query all quote line items related to the current quote record
    var gr = new GlideRecord('sn_quote_mgmt_core_quote_line_item');
    gr.addQuery('quote', target.getValue('sys_id'));
    gr.query();

    // Loop through each quote line item
    while (gr.next()) {
        // Get product description and name from the related product offering
        var desc = gr.getDisplayValue('product_offering.description') || '';
        var name = gr.getDisplayValue('product_offering.name');

        // Only include the product if a description exists
        if (desc) {
            // Add the product name with a numbered label
            html += `<p style="font-family: Arial, sans-serif; font-size: 12pt;"><strong>2.${count}</strong> ${name}</p>`;

            // Add the product description
            html += `<p style="font-family: Arial, sans-serif; font-size: 12pt;">${desc}</p>`;
            count++; // Increment the counter
        }
    }

    // Return the final HTML output
    return html;
})(target, docTemplate);

 

  • Budget Spreadsheets: A custom table that shows investments, deadlines, and total values of all quote line itens from the quote.

(function runTemplateScript(target, docTemplate) {
	
    var html = '';
    var totalAmount = 0;

    // Add the section title
    html += '<h3 style="font-family: Arial, sans-serif; font-size: 14pt; text-align: center;">Product Budget</h3>';

    // Start the table with headers
    html += '<table style="width: 100%; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 12pt;" border="1">';
    html += '<thead><tr>';
    html += '<th style="padding: 8px; text-align: center;">Product</th>';
    html += '<th style="padding: 8px; text-align: center;">Quantity</th>';
    html += '<th style="padding: 8px; text-align: center;">Term (months)</th>';
    html += '<th style="padding: 8px; text-align: center;">Unit Price</th>';
    html += '<th style="padding: 8px; text-align: center;">Total Value</th>';
    html += '</tr></thead><tbody>';

    // Query quote line items related to the current quote
    var gr = new GlideRecord('sn_quote_mgmt_core_quote_line_item');
    gr.addQuery("quote", target.getValue('sys_id'));
    gr.query();

    // Loop through each quote line item
    while (gr.next()) {
        var product = gr.getDisplayValue("product_offering");
        var quantity = gr.getValue("quantity");
        var termMonth = gr.getValue("term_month");
        var unitPrice = parseFloat(gr.getValue("list_price") || 0);
        var totalLine = parseFloat(gr.getValue("cumulative_net_price") || 0);
        totalAmount += totalLine;

        // Add a table row for the product
        html += '<tr>';
        html += '<td style="padding: 6px; text-align: center;">' + product + '</td>';
        html += '<td style="padding: 6px; text-align: center;">' + quantity + '</td>';
        html += '<td style="padding: 6px; text-align: center;">' + termMonth + '</td>';
        html += '<td style="padding: 6px; text-align: center;">' + unitPrice.toFixed(2).replace('.', ',') + '</td>';
        html += '<td style="padding: 6px; text-align: center;">' + totalLine.toFixed(2).replace('.', ',') + '</td>';
        html += '</tr>';
    }

    // Add the total row
    html += '<tr>';
    html += '<td colspan="4" style="padding: 8px; text-align: center;"><strong>Total Amount:</strong></td>';
    html += '<td style="padding: 8px; text-align: center;"><strong>R$ ' + totalAmount.toFixed(2).replace('.', ',') + '</strong></td>';
    html += '</tr>';

    // Close the table
    html += '</tbody></table>';

    return html;
})(target, docTemplate);

 

  • To understand a little more about script templates:

🔗 Official ServiceNow guide HTML document Script documentation


4. HTML Document Template Example Content (SOM)

 

gustavopetta_2-1753019223805.png

HTML Document Template Example

 


5. Instance Configuration (SOM)

Before creating opportunities and quotes with attached templates, the sales catalog must be properly set up. Click on the links below, and you will see how to do set up step by step:


🔗 Create Product Catalog

🔗 Create Product Offering Category

🔗 Create Product Offering

🔗 Create Price List

 

Once you've set up an offer, you will have this view of a product:

 

gustavopetta_0-1752893842049.png

Product Configured

 

⚠️ After following the previous steps, go to the catalog and click on the "Regenerate Catalog Hierarchy Cache" UI action (This is specific to the SOM module).


6. Creating an Opportunity and Quote to generate the PDF Contract

To simulate a sale and generate the contract, click on the links and follow the steps:

🔗 How to create a new opportunity

🔗 Create a quote from an Opportunity

 

Steps to reproduce this process:

 

  1. Create an Opportunity.

  2. Add the required products.

  3. Generate the quote.

  4. Generate the Document.

 

oppt.gif

 

quote.gif

 

Furthermore, if you would like to explore more funcionalities, I have done an update set that you can test on your PDI. 

 

If you're working on SOM implementations involving contracts, quotes, or dynamic document generation, this guide is a solid foundation to build on.

 

#servicenow #som #csm 

 

Introduction to ServiceNow SOM (Sales and Order Management) Implementation 

Comments
Krupa Singampal
ServiceNow Employee
ServiceNow Employee

Thank you Gustavo for this very helpful article. This is a great starting point for quote templates. Of course, for more complex sales contracts, red lining with terms& conditions negotiations, our out of the box integration with Contract Management Pro takes it to the next level 🙂

Version history
Last update:
‎08-11-2025 06:09 PM
Updated by:
Contributors