Quotation creation using n8n for O2C

I am new to n8n and I am trying to build a quotation generation workflow.

My goal is:

  1. Receive customer details (name, email, service, quantity, price)

  2. Calculate totals automatically

  3. Generate a quotation number

  4. Create a PDF quotation

  5. Send the quotation to the customer by email

Currently, I am confused about how to configure the Set node and pass data between nodes. I am not sure where I should add the customer information and how to map the fields correctly.

Could someone guide me on:

  • Which nodes should I use for each step?

  • How should I structure the workflow?

  • How can I generate a PDF from the quotation data?

Hi @Sifrabasayar_12

You can use this thread as your starting point

The workflow generated should meet most of your needs

Start with the data shape, not the PDF node. Make one test item with the exact quote fields you need: customer_name, customer_email, service, quantity, unit_price, total, and quote_number.

Once that item exists, the next node only has to map those field names into the PDF/email step. Where will the first customer details enter n8n: form, webhook, spreadsheet, or manual test item?

Welcome @Sifrabasayar_12! To add to what @oimrqs_ops said - for the PDF step specifically, the easiest approach in n8n is to use an HTML Template node to build the quote layout with your mapped fields, then pipe that HTML into an HTTP Request node calling a free PDF API like html2pdf.it or a self-hosted Gotenberg instance. The HTML template approach gives you full control over the quote design without any extra license cost. For the quote number, generate it in a Code node using something like 'Q-' + Date.now() or a sequential counter stored in a static workflow variable. Once you have the PDF as binary data, attach it directly in the Gmail node’s attachment field using {{ $binary.data }}.

Hey @Sifrabasayar_12, to tie everything together with a clear structure:
Trigger → Form Trigger or Webhook (captures customer name, email, service, qty, price)
Calculate totals → Set node: add a field total = {{ $json.quantity * $json.unit_price }}
Generate quote number → Code node: return [{ json: { …$input.first().json, quote_number: ‘Q-’ + Date.now() } }]
Build PDF → HTML node to design the quote layout using {{ $json.customer_name }} etc., then HTTP Request node → html2pdf.it (free, no signup) to convert it to a PDF binary
Send email → Gmail node with To: {{ $json.customer_email }}, attach the PDF binary from the previous node
The key thing for passing data between nodes: every node receives $json from the node before it. Use the Set node to add or rename fields, and they’ll be available in every node downstream. Once your test item has all the fields set correctly in step 1, the rest just maps those same field names through.

Welcome @Sifrabasayar_12!

Here’s a clean node structure for this:

  1. n8n Form trigger to collect customer name, email, service, quantity, price
  2. Code node to calculate totals and generate a quote number: "Q-" + Date.now()
  3. For the PDF - the easiest beginner-friendly path is Google Docs: create a template doc with placeholders like {{customer_name}}, {{total}}, use the Google Docs node (Replace Text operation) to fill them in, then export to PDF via the Google Drive node (Download operation, set output format to PDF)
  4. Gmail node to send the email with the exported PDF as attachment

Start by testing just steps 1 and 2 first to make sure your fields are shaped correctly before adding the PDF step.