Document/PDF Merge & Mail
Batch personalised PDF/letter mail-merge from any recordset and a template
Producing personalised letters, statements or notices in bulk usually means exporting Odoo data to a spreadsheet, running a Word mail-merge, then re-importing or emailing by hand, a slow, error-prone round trip that lives entirely outside your system of record. Operations, HR, finance and marketing teams hit this wall whenever they need hundreds of tailored documents. This module builds reusable token-based templates on gb.merge.template, points them at any Odoo recordset, and generates one rendered document per record in a tracked batch run with optional per-record email dispatch. It is pure format-generation that sends through Odoo's own mail layer using your SMTP.
Key Features
Token-Based Letter Templates
A gb.merge.template holds an HTML body with {{record.field}} tokens matched by a regex and resolved through Odoo's sandboxed safe_eval. Dotted paths like {{record.partner_id.name}} work, dates and amounts are formatted, and a detected-tokens helper lists every placeholder so non-developers can build templates safely.
Merge Against Any Model
The template's target model is any ir.model record, so you can mail-merge partners, invoices, sale orders, employees or custom models. Configurable record_alias, partner_path and email_field_path tell the engine how to reach the record's data and email address for that model.
Per-Record Rendering with Fallbacks
render_for_record substitutes every token per record, applying gb.merge.template.token default values when a token resolves empty. With require_all_tokens on, a record missing required data raises a clear error instead of producing a blank letter, keeping batch output clean.
Tracked Batch Runs
A gb.merge.run resolves records from explicit IDs or a domain and creates one gb.merge.run.line per record, each carrying its rendered subject, body, resolved email and a rendered/sent/error state. Stored line, sent and error counts give a clear at-a-glance view of every batch.
Per-Record Email Dispatch
With auto_email enabled, each rendered line sends through mail.mail using your own SMTP, attaching the document and recording the mail and any error per line. Failed lines can be retried individually via action_retry, so a single bad address never blocks the run.
PDF & HTML Document Attachments
Each template has an Output Format setting (PDF or HTML). In PDF mode the merged body is passed through Odoo's built-in QWeb/wkhtmltopdf engine and stored as a .pdf ir.attachment per record, ready to download or attach to outgoing emails. HTML mode stores a lightweight .html file. Every generated document is archived against its run line giving a permanent record of exactly what each recipient received.
Recurring Schedules with Cron
A gb.merge.schedule binds a template to a domain and an interval; an hourly ir.cron runs _cron_run_due, building, rendering and optionally emailing a run for each due schedule, then advancing next_run. An optional max_records cap turns one-shot merges into an unattended document factory (e.g. weekly statements).
Wizard-Driven & Safe by Design
The gb.merge.run.wizard pre-fills from the current list selection, shows a live matched-record estimate and supports ID or domain mode. All token and domain evaluation goes through safe_eval, so templates cannot run arbitrary code and email always flows through your configured mail server.
Use Cases
Screenshots
Run Mailmerge
Why Choose This Module
Stop exporting data to Word to run a mail-merge. Build a reusable letter / document template with placeholder tokens, point it at any Odoo recordset — partners, invoices, sale orders, employees — and generate one rendered document per record in a single batch run, with optional email dispatch. Pure format-generation; it sends through Odoo's own mail layer (BYO SMTP).
Specifications
- Compatible: Odoo 18.0 / 19.0
- License: OPL-1
- Languages: English
- Author: Pokutsoft
- Dependencies: mail
- Support: support@pokutsoft.com
Update date: 2026-07-02