Back to Blog

CPQ Quote Template Totals and Subtotals Without Visualforce

CPQ Quote Template Totals and Subtotals Without Visualforce

Salesforce CPQ quote templates cannot compute a monthly recurring total or subtotal a group of lines without a rollup field or a Visualforce section. Here is why, and how to get both declaratively.

ZeroExport Team

Salesforce CPQ quote templates are fine right up to the moment you need one to do arithmetic. Show a monthly recurring total separate from one-time fees. Subtotal a group of lines. Put a named header above a table and hide it when the table is empty. These are ordinary asks for a quote, and the native template answers all of them the same way: add a field, or write a Visualforce section.

You can watch it happen in the community. Someone asks how to show a total monthly price on the quote template and the answers point at custom rollup fields. Someone else asks how to build a custom quote template at all and hits the same wall.

This article covers why the native template works that way, what each workaround costs, and which parts of the problem are genuinely solvable declaratively today.

Why the native CPQ template cannot compute totals

CPQ quote templates are assembled from Template Sections and Line Columns. That model is deliberately simple, and the simplicity is the ceiling.

  • Totals are field-bound, not computed. A line column renders a field. A total renders a field. If you want "sum of amount where charge type is recurring," there is no place in the template to express it, so you create a field on the Quote whose only purpose is to hold that number, and something else has to populate it.
  • There is no grouping with subtotals. You can sort and filter quote lines, but "split these lines into groups and subtotal each group" is not part of the model. The template renders one list.
  • Conditional layout is limited. A named table header that hides when its table is empty, or a section that appears only for certain products, is not cleanly expressible, so teams fall back to HTML or a Visualforce section.

The consistent pattern: the moment the document needs to calculate or organize rather than place, CPQ hands you back to fields or code.

The three workarounds and what they cost

1. Precompute everything into fields. Add a rollup or formula field for every subtotal and total variant you need. It works, and it is the most common answer. The cost is that a layout requirement is now a schema change: a new total on the PDF means a new field, a deployment, and a field that lives in your org forever. This is the beginning of docgen debt, where a meaningful share of your custom fields exist only to feed a document.

2. Visualforce template sections. Hand-write the grouping and totals in a VF section embedded in the template. You now own a Visualforce page, its test coverage, and its deployment, and the output inherits the PDF rendering engine's constraints on CSS, fonts, and images.

3. A third-party docgen tool. Conga, S-Docs, and similar tools can produce grouped subtotals, but most of them move template maintenance into a Word file and charge per document. You have traded a calculation problem for a Word template problem.

Each ships the quote and adds something permanent to maintain.

What a quote template should let you do

If arithmetic and organization are table stakes for quotes, the bar is:

  1. Compute totals in the template, not in fields minted for the purpose.
  2. Subtotal a set of lines without precomputing the subtotal elsewhere.
  3. Separate recurring from one-time without a rollup field per charge type.
  4. Hide headers and sections when they have no rows.
  5. Do it without a Visualforce page to test and deploy.

Doing it declaratively: totals as template logic

The fix is to let the document compute. In ZeroExport, totals are expressions in the template rather than fields on the record, and the data the template sees is shaped at the data source rather than in your schema.

Step 1: Bind to the Quote and its lines. Point the template at the Quote and pull Quote Lines with the fields you need: charge type, term, amounts. No pre-flattening into custom fields.

Step 2: Filter at the data source, total within it. This is the part that answers the monthly-total question. A template can carry more than one child data source over the same relationship, each with its own filter. Define one for recurring charges and one for one-time charges, render each as its own table, and place a sum() under each. You get a monthly recurring total and a one-time total as computed values, with no rollup field created and nothing to keep in sync.

Step 3: Let subtotals scope themselves. Aggregates (sum, count, min, max, avg) re-scope inside a repeating region, so a subtotal placed under a parent totals only that parent's own rows. For a bundle with components, or an opportunity with several child collections, the subtotal follows the relationship without you scoping it by hand.

Step 4: Make headers conditional. Put the header inside the section that renders the rows and give the section a condition. When there are no qualifying lines, the header disappears with the table instead of sitting above nothing. Section conditions cascade to everything nested inside them.

Step 5: Generate from the Quote. A button, a Flow, or an Agentforce action produces the PDF from any quote. The packaged invocable action takes a record ID and a template ID.

The boundary, stated plainly

Two different things get called "grouping," and only one of them ships:

  • Subtotals that follow a relationship (per bundle, per parent record) work today. So does splitting a list by a known filter into separate data sources, which is what the recurring-versus-one-time case above actually needs.
  • Partitioning one flat list by a field value at render time, discovering the groups from the data and emitting a subtotal per discovered group, is on the roadmap and not shipped.

The practical test: if you know the categories when you design the template, the filtered data source pattern covers you. If the categories are whatever happens to be in the data that day, and each needs its own subtotal row, that specific layout is not available yet. Plan around it rather than finding out late.

Note on scope: ZeroExport generates the documents. CPQ still does the configuration and pricing, and this does not replace it. On rendering performance at very high volume and pixel-exact page-break control we publish no claims, so evaluate any candidate, including this one, against your own requirements.

When the native template is still fine

If your quotes are flat, one list of lines with one grand total and rare changes, the standard CPQ quote template is the right tool and you should not add anything. The case for moving the logic into the document starts when you have multiple total types, subtotals, conditional sections, or a Visualforce quote template you are tired of maintaining.

FAQ

How do I show a total monthly price on a Salesforce CPQ quote template?

Natively you create a rollup or formula field on the Quote that sums only the recurring lines, then merge that field into the template, because the template itself cannot compute a conditional total. A structure-aware document tool avoids the field by filtering the lines at the data source and summing them in the template.

Can a CPQ quote template group line items and subtotal each group?

Not natively. The template renders one list of quote lines with sorting and filtering, but it has no grouping model that emits a subtotal per group. Teams either precompute the subtotals into fields or write a Visualforce section.

How do I subtotal quote lines without creating rollup fields?

Use a document tool where aggregates are template expressions rather than record fields. Subtotals that follow a parent relationship scope automatically inside a repeating region, and a list you can define by a filter can carry its own total, so no rollup field is needed for either case.

Why does my quote line table header show when the table is empty?

Because the native template has no way to tie a header's visibility to whether its table has rows. The fix is to keep the header inside a section that carries the condition, so the header and the table appear or disappear together.

Do I need Visualforce to customize a CPQ quote template?

For anything structural, natively yes: grouped subtotals, computed totals, and conditional headers generally push you into a Visualforce template section. That is what puts a page, its tests, and its deployment on your maintenance list, along with the PDF engine's CSS and font constraints.

Related Reading

Ready to try ZeroExport?

Start generating documents directly in your Salesforce org. No integrations, no setup overhead, no complexity.