Quote Builder by Vexco

Formats, fields and formulas

Everything you import becomes a template (even if used once) and is calculated by the same engine.

CRM fields

FieldWhat it is
{{deal.dealname}}, {{deal.amount}}, {{deal.my_property}}Deal properties (custom ones too)
{{company.name}}, {{company.city}}The deal's primary company
{{contact.firstname}}, {{contact.fullname}}, {{contact.email}}The deal's first contact
{{owner.fullname}}, {{owner.email}}Deal owner
{{inputs.key}}Inputs asked by the template
{{today()}}, {{addDays(30)}}, {{addMonths(12)}}Dates

Filters: upper, lower, capitalize, money, money:'USD', number:2, round:2, date, default:'—', truncate:40.

Formulas (quantity, price, discounts, conditions)

inputs.users * 12
deal.amount > 5000 && inputs.training
inputs.plan == 'pro' ? 49 : 29
tier(quantity, [[1, 30], [20, 25], [100, 21]])     tiered price
lookup(inputs.plan, 'basic', 10, 'pro', 20, 0)      value table
round(product.price * 0.9, 2)                       HubSpot product price
max(0, inputs.users - 100)                          quantity 0 = line not included

Operators: + - * / %, == != < <= > >=, && || ! (also and or not), condition ? a : b. Functions: min max round ceil floor abs if coalesce number text upper lower len contains concat tier lookup today addDays addMonths. Inside a line: quantity, price and product.*.

HTML with quote markup

<article data-quote data-title="Proposal {{company.name}}" data-expires="30" data-currency="EUR">
  <var data-variable="users" data-type="number" data-default="10" data-required>Number of users</var>
  <section data-group="Licences">
    <div data-line data-sku="LIC-PRO" data-qty="{{inputs.users}}" data-frequency="monthly" data-term="12">Pro licence</div>
  </section>
  <table>
    <tr data-line data-optional><td data-field="name">Training</td><td data-field="qty">2</td><td data-field="price">450.00</td></tr>
  </table>
  <div data-quote-comments>Prices exclude VAT.</div>
</article>

Line attributes: data-name, data-sku, data-product-id, data-qty, data-price, data-total, data-discount (“10 %” or amount), data-tax, data-frequency, data-term, data-condition, data-group, data-optional; or child elements with data-field. Without markup, the table that looks most like quote lines is used (recognised headers in English, Spanish and Catalan), skipping totals and taxes.

CSV, TSV and pasted spreadsheets

Delimiter detected automatically; with or without a header row; comma or dot decimals. Single-cell rows become sections.

Plain text and Markdown

# ACME corporate website
Valid until: 31/12/2026
Email: purchasing@acme.com

## Design
- 3 x Page templates at 400
- Logo: 350

## Maintenance
Hosting and support 49/month, 12 months
Training 2 h × 60 (10% off)

JSON

{
  "title": "Web order",
  "expires": 15,
  "currency": "EUR",
  "buyer": { "email": "purchasing@acme.com" },
  "lines": [
    { "sku": "LIC-PRO", "quantity": 10, "billing_frequency": "monthly", "term": 12 },
    { "name": "Training", "quantity": 2, "price": 450, "discount_percent": 10 }
  ]
}

Any JSON with a list of lines (items, line_items, products…) works too — e.g. a Shopify or WooCommerce order.

Excel

Through the API (multipart, field file) or a URL. The sheet with most lines is used.