Skip to content

Example Quote Template

This page brings everything together in a complete quote template. It uses the example quote from the Data Reference: a welding robot configuration with a BoM price table, a discounts table, commercial terms and product images.

You can use it in two ways: upload the HTML version as-is and adjust the styling, or use the Word blueprint to build the same quote in Word.

What the template produces

SectionSource in the data
Logo, quote number, customer and datesd.id, d.revision_number, d.name, d.email, d.created_at, d.user
Price table grouped by Essentials, Software, Accessories, …d.form_submissions[0].form.bom.tables[0]
Discount lines with total discount (removed when there are no discounts)d.form_submissions[0].form.bom.tables[label='Discounts']
Grand totald.form_submissions[0].form.bom.summary
Commercial terms with a fallback textd.extra_fields[name='Commercial Terms'].fields
Product details page with image and descriptiond.form_submissions[0].form.data.elements[].options[]

HTML template

  1. Download the template or copy the code below into a file called quote-template.html.

  2. Replace the logo URL with the URL of your own logo, and adjust colours and fonts in the <style> block.

  3. If your BoM tables have different names, change tables[0] and tables[label='Discounts'] to match your BoM Builder setup. Change Commercial Terms to the name of your request field tab.

  4. Upload the file in Settings → Document Templates and generate a quote to test it.

quote-template.html
<!DOCTYPE html>
<html lang="{d.languageSlug}">
<head>
<meta charset="utf-8">
<title>Quote {d.id}-{d.revision_number}</title>
<style>
body { font-family: Arial, sans-serif; font-size: 11px; color: #1f2933; margin: 0; }
h1 { font-size: 22px; margin: 0 0 4px; }
.muted { color: #6b7280; }
.header { display: flex; justify-content: space-between; margin-bottom: 24px; }
table { width: 100%; border-collapse: collapse; margin-bottom: 16px; }
th { text-align: left; border-bottom: 2px solid #1f2933; padding: 6px 4px; }
td { padding: 5px 4px; border-bottom: 1px solid #e5e7eb; vertical-align: top; }
.group td { background: #f3f4f6; font-weight: bold; }
.num { text-align: right; white-space: nowrap; }
.center { text-align: center; }
.total td { font-weight: bold; border-top: 2px solid #1f2933; border-bottom: none; }
.description { white-space: pre-line; }
.logo { height: 40px; margin-bottom: 16px; }
.page-break { page-break-before: always; break-before: page; }
</style>
</head>
<body>
<!-- Replace with the URL of your own logo -->
<img class="logo" src="https://yourcompany.com/logo.png" alt="Logo">
<div class="header">
<div>
<h1>{d.languageSlug:ifEQ('da'):show('Tilbud'):elseShow('Quote')} {d.id}-{d.revision_number}</h1>
<div class="muted">{d.configuration_name}</div>
</div>
<div>
<div><strong>{d.name}</strong></div>
<div>{d.email}</div>
<div class="muted">Date: {d.created_at:formatD('DD-MM-YYYY')}</div>
<div class="muted">Valid until: {d.created_at:addD(30, 'day'):formatD('DD-MM-YYYY')}</div>
<div class="muted">Your contact: {d.user.name} ({d.user.email})</div>
</div>
</div>
<!-- Price table from the BoM: one heading row per group, one row per option -->
<h2>{d.form_submissions[0].form.bom.tables[0].label}</h2>
<table>
<thead>
<tr>
<th>{d.form_submissions[0].form.bom.tables[0].headerColumns[i].label}</th>
<th>{d.form_submissions[0].form.bom.tables[0].headerColumns[i+1].label}</th>
</tr>
</thead>
<tbody>
<tr class="group">
<td colspan="3">{d.form_submissions[0].form.bom.tables[0].groups[i].label}</td>
</tr>
<tr>
<td>{d.form_submissions[0].form.bom.tables[0].groups[i].rows[i].optionRows[i].optionColumns[field='name'].value}</td>
<td class="center">{d.form_submissions[0].form.bom.tables[0].groups[i].rows[i].optionRows[i].optionColumns[field='sku'].value}</td>
<td class="num">{d.form_submissions[0].form.bom.tables[0].groups[i].rows[i].optionRows[i].optionColumns[field='sales_price'].value}</td>
</tr>
<tr><td>{d.form_submissions[0].form.bom.tables[0].groups[i].rows[i].optionRows[i+1]}</td></tr>
<tr><td>{d.form_submissions[0].form.bom.tables[0].groups[i].rows[i+1]}</td></tr>
<tr><td>{d.form_submissions[0].form.bom.tables[0].groups[i+1]}</td></tr>
</tbody>
</table>
<!-- Removed automatically when the quote has no discounts -->
<table>
<thead>
<tr>
<th colspan="2">Discounts{d.form_submissions[0].form.bom.tables[label='Discounts'].groups[0].rows:ifEM():drop(table)}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{d.form_submissions[0].form.bom.tables[label='Discounts'].groups[0].rows[i].label}</td>
<td class="num">{d.form_submissions[0].form.bom.tables[label='Discounts'].groups[0].rows[i].optionRows[0].optionColumns[field='sales_price'].value}{d.form_submissions[0].form.bom.tables[label='Discounts'].groups[0].rows[i].subtotals[field='sales_price'].value}</td>
</tr>
<tr><td>{d.form_submissions[0].form.bom.tables[label='Discounts'].groups[0].rows[i+1]}</td></tr>
</tbody>
</table>
<table>
<tbody>
<tr class="total">
<td>{d.form_submissions[0].form.bom.summary.rows[i].label}</td>
<td class="num">{d.form_submissions[0].form.bom.summary.rows[i].value}</td>
</tr>
<tr><td>{d.form_submissions[0].form.bom.summary.rows[i+1]}</td></tr>
</tbody>
</table>
<h2>Commercial terms</h2>
<table>
<tbody>
<tr>
<td>{d.extra_fields[name='Commercial Terms'].fields[i].name}</td>
<td class="description">{d.extra_fields[name='Commercial Terms'].fields[i].value:ifEM():show('To be agreed')}</td>
</tr>
<tr><td>{d.extra_fields[name='Commercial Terms'].fields[i+1]}</td></tr>
</tbody>
</table>
<!-- Product details with images: only options that have an image -->
<div class="page-break"></div>
<h2>Product details</h2>
<table>
<tbody>
<tr>
<td style="width: 120px;"><img src="{d.form_submissions[0].form.data.elements[i].options[i, image!=''].image}" style="width: 110px; height: auto;"></td>
<td>
<strong>{d.form_submissions[0].form.data.elements[i].options[i, image!=''].label}</strong>
<div class="description">{d.form_submissions[0].form.data.elements[i].options[i, image!=''].description}</div>
</td>
</tr>
<tr><td>{d.form_submissions[0].form.data.elements[i].options[i+1, image!='']}</td></tr>
<tr><td>{d.form_submissions[0].form.data.elements[i+1]}</td></tr>
</tbody>
</table>
</body>
</html>

Word blueprint

To build the same quote in Word, create the following blocks. Each table below represents a Word table; each line in a cell is a paragraph.

1. Header

Put your logo in the Word header. In the body, add:

{d.languageSlug:ifEQ('da'):show('Tilbud'):elseShow('Quote')} {d.id}-{d.revision_number}
{d.configuration_name}
{d.name}
{d.email}
Date: {d.created_at:formatD('DD-MM-YYYY')}
Valid until: {d.created_at:addD(30, 'day'):formatD('DD-MM-YYYY')}
Your contact: {d.user.name} ({d.user.email})

2. Price table

A table with three columns and five rows. Style row 2 as a group heading (for example bold with a grey background) and row 3 as a normal product row. Rows 4 to 6 are removed from the output, so their style doesn’t matter.

RowDescriptionArticle No.Sales price
1DescriptionArticle No.Sales price
2{d.form_submissions[0].form.bom.tables[0].groups[i].label}
3{d.form_submissions[0].form.bom.tables[0].groups[i].rows[i].optionRows[i].optionColumns[field='name'].value}{d.form_submissions[0].form.bom.tables[0].groups[i].rows[i].optionRows[i].optionColumns[field='sku'].value}{d.form_submissions[0].form.bom.tables[0].groups[i].rows[i].optionRows[i].optionColumns[field='sales_price'].value}
4{d.form_submissions[0].form.bom.tables[0].groups[i].rows[i].optionRows[i+1]}
5{d.form_submissions[0].form.bom.tables[0].groups[i].rows[i+1]}
6{d.form_submissions[0].form.bom.tables[0].groups[i+1]}

3. Discounts table

A table with two columns. The tag in row 1 removes the whole table when there are no discounts. Row 3 is for subtotals and can be styled in bold.

RowDescriptionDiscount
1Discounts {d.form_submissions[0].form.bom.tables[label='Discounts'].groups[0].rows:ifEM():drop(table)}
2{d.form_submissions[0].form.bom.tables[label='Discounts'].groups[0].rows[i].label} {d.form_submissions[0].form.bom.tables[label='Discounts'].groups[0].rows[i].type:ifEQ('subtotal'):drop(row)}{d.form_submissions[0].form.bom.tables[label='Discounts'].groups[0].rows[i].optionRows[0].optionColumns[field='sales_price'].value}
3{d.form_submissions[0].form.bom.tables[label='Discounts'].groups[0].rows[i].label} {d.form_submissions[0].form.bom.tables[label='Discounts'].groups[0].rows[i].type:ifNE('subtotal'):drop(row)}{d.form_submissions[0].form.bom.tables[label='Discounts'].groups[0].rows[i].subtotals[field='sales_price'].value}
4{d.form_submissions[0].form.bom.tables[label='Discounts'].groups[0].rows[i+1]}

4. Total

{d.form_submissions[0].form.bom.summary.rows[0].label}: {d.form_submissions[0].form.bom.summary.rows[0].value}

5. Commercial terms

RowTermValue
1{d.extra_fields[name='Commercial Terms'].fields[i].name}{d.extra_fields[name='Commercial Terms'].fields[i].value:ifEM():show('To be agreed'):convCRLF}
2{d.extra_fields[name='Commercial Terms'].fields[i+1]}

6. Product details

Start this block on a new page. Insert a placeholder image (set to In line with text) in the first cell and put the tag from the table below in its alternative text.

RowImageProduct
1placeholder image, alt text: {d.form_submissions[0].form.data.elements[i].options[i, image!=''].image:imageFit(contain)}{d.form_submissions[0].form.data.elements[i].options[i, image!=''].label} {d.form_submissions[0].form.data.elements[i].options[i, image!=''].description:convCRLF}
2{d.form_submissions[0].form.data.elements[i].options[i+1, image!='']}
3{d.form_submissions[0].form.data.elements[i+1]}

Result

Generated with the example quote, the price section looks like this:

Quote 2586-1 Jane Doe
Project name jane.doe@example.com
Date: 17-09-2026
Valid until: 17-10-2026
Your contact: Alex Seller (alex@yourcompany.com)
CoWelder Quote
Description Article No. Sales price
Essentials
UR12e 36940412 398,870.00 kr
Select 400 SV Synergic DC 1.0V 79542563 78,050.00 kr
AB ROB W500 22gr, 36072505 28,440.00 kr
Software
Pulse Function 10682002 7,650.00 kr
PowerArc 10682003 2,450.00 kr
PowerArc Pulse 10682005 6,040.00 kr
Sequence Repeat 10683002 1,300.00 kr
Weaving 10950000 25,840.00 kr
Offset 10950010 13,300.00 kr
Accessories
Wear Parts Box - W500 - 1.2mm 81100260 2,870.00 kr
Torch bundle - ABIROB® W5F 36072508 13,760.00 kr
UR12E/8L KIT FOR 3PE 45050547 2,830.00 kr
Services
Basic Training Package 99906111 9,680.00 kr
Freight
Delivery incl. packaging - Basic - DK - Zone 1 Basic_DK_1 3,761.00 kr
Discounts
Software discount -28,290.00 kr
Additional Discount -50,000.00 kr
Total discount -78,290.00 kr
Total price 516,551.00 kr
Commercial terms
Warranty To be agreed
Payment To be agreed
Delivery To be agreed
Delivery Conditions To be agreed

Ideas to extend the template