๐งฉ Custom PDF Automation System in NetSuite (Auto-Generate, Save & Email PDFs)
Introduction
In many organizations, accounting and operations teams still manually print or email PDFs for Invoices, Statements, or Purchase Orders.
With SuiteScript and Advanced PDF templates, you can automate this process โ generating and sending professional PDFs automatically whenever a transaction is created, approved, or updated.
This tutorial teaches you how to build a complete PDF automation framework that handles generation, saving, and emailing of transaction PDFs โ with logging and configuration flexibility.
๐ก Why Automate PDF Generation?
Challenge | Without Automation | With Automation |
---|---|---|
Manual effort | Users download and email PDFs manually | Automatic generation after save |
Inconsistency | Different users send different templates | Standardized design |
Delays | Customers wait for email confirmations | Instant email delivery |
Missing copies | PDFs not stored in File Cabinet | Automatically archived |
โ Automated PDFs improve consistency, speed, and auditability.
๐งฑ Step 1: Create or Customize Your Advanced PDF Template
- Go to Customization โ Forms โ Advanced PDF/HTML Templates.
- Choose a transaction type (e.g., Invoice).
- Click Customize โ Name: Invoice PDF (Custom).
- Use FreeMarker syntax for dynamic fields:
<p><b>Invoice #:</b> ${record.tranid}</p> <p><b>Date:</b> ${record.trandate}</p> <p><b>Total Amount:</b> ${record.total}</p>
- Save your template.
- Note the Template ID for use in the script.
โ๏ธ Step 2: Build a PDF Generation Script (SuiteScript 2.1)
Hereโs a sample User Event Script to auto-generate and email a PDF when an invoice is created or approved.
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
*/
define(['N/render', 'N/record', 'N/file', 'N/email', 'N/runtime', 'N/log'],
(render, record, file, email, runtime, log) => {
const afterSubmit = (ctx) => {
if (ctx.type === ctx.UserEventType.DELETE) return;
try {
const rec = ctx.newRecord;
const recId = rec.id;
const recType = rec.type;
// Render PDF
const pdfFile = render.transaction({
entityId: recId,
printMode: render.PrintMode.PDF
});
const folderId = runtime.getCurrentScript().getParameter('custscript_pdf_folder');
pdfFile.folder = folderId;
pdfFile.name = `${recType}_${recId}.pdf`;
const fileId = pdfFile.save();
log.audit('PDF Generated', `File ID: ${fileId}`);
// Email PDF to customer
const customerId = rec.getValue('entity');
const emailRecipient = record.lookupFields({
type: 'customer',
id: customerId,
columns: ['email']
}).email;
if (emailRecipient) {
email.send({
author: runtime.getCurrentUser().id,
recipients: emailRecipient,
subject: `Your ${recType} #${recId}`,
body: 'Please find your attached PDF document.',
attachments: [file.load({ id: fileId })]
});
log.audit('Email Sent', `To: ${emailRecipient}`);
}
} catch (e) {
log.error('PDF Automation Error', e);
}
};
return { afterSubmit };
});
โ This script automatically:
- Generates a PDF
- Saves it to a File Cabinet folder
- Emails it to the customer
๐ง Step 3: Add Script Parameters
Parameter | ID | Type | Description |
---|---|---|---|
PDF Folder | custscript_pdf_folder | Select | File Cabinet folder ID |
Template ID | custscript_pdf_template | Text | Advanced PDF Template ID |
Send Email? | custscript_send_email | Checkbox | Toggle email sending |
โ Enables flexible control without editing code.
๐งฉ Step 4: Schedule or Trigger via Workflow
- Use Workflow Action Script to trigger PDF generation when
Approval Status = Approved
. - Or use a Scheduled Script for batch PDF generation:
- Example: Send all approved Invoices at 6 PM daily.
- Retrieve records via Saved Search and loop through the render/email process.
๐ Step 5: Store PDFs in Organized Folders
Structure your File Cabinet by type and date:
/PDF_Automation/
โโโ Invoices/
โโโ PurchaseOrders/
โโโ Statements/
โโโ CustomReports/
Add folder structure dynamically:
const yearFolder = file.createFolder({ name: new Date().getFullYear(), parent: parentFolderId });
โ Keeps historical copies organized and audit-friendly.
๐ Step 6: Build PDF Automation Dashboard
Create a Custom Record: customrecord_pdf_log
Field | Description |
---|---|
Record Type | Invoice / PO / etc. |
Record ID | Internal ID of transaction |
PDF File ID | File Cabinet ID |
Email Sent To | Recipient address |
Timestamp | Date sent |
Status | Success / Failed |
Then, use:
- Saved Search: โPDFs Sent This Weekโ
- Workbook: PDF success rate by record type
- Portlet: Total PDFs Sent Today
โ Great for audit and performance visibility.
๐งฎ Step 7: Handle Bulk PDF Generation (Map/Reduce)
For large batches (e.g., 5,000+ invoices):
- Use Map/Reduce to process in parallel
- Load records from saved search
- Render & email each one in the map stage
- Log results in the summarize stage
This ensures high performance without exceeding governance limits.
๐งฉ Step 8: Add Custom Branding & Conditional Content
In FreeMarker template:
<#if record.total gt 5000>
<p><b>Preferred Customer Discount Applied!</b></p>
</#if>
<#if record.custbody_po_number?has_content>
<p><b>Customer PO:</b> ${record.custbody_po_number}</p>
</#if>
โ Adds dynamic content based on transaction data.
โก Step 9: Integrate with External Storage or CRM
You can enhance your automation further:
- Upload generated PDFs to Google Drive, OneDrive, or SFTP via RESTlet.
- Attach PDFs to CRM systems like Salesforce using middleware (Boomi / Celigo).
- Include public URL links in email body for cloud access.
๐งฐ Step 10: Common Issues & Fixes
Issue | Cause | Solution |
---|---|---|
Blank PDF | Missing template association | Assign correct Advanced PDF template |
Email not sent | Customer missing email | Add validation check |
SSS_USAGE_LIMIT_EXCEEDED | Batch too large | Use Map/Reduce + rescheduling |
PDF not saved | Folder ID invalid | Set correct File Cabinet path |
Missing attachments | file.load() failure | Wait for file.save() completion |
๐ Related Tutorials
- ๐ Advanced PDF Customization Guide
- ๐ SuiteScript Error Handling Framework
- ๐ Integration Logging & Monitoring Dashboard
โ FAQ
Q1. Can I send different templates for different subsidiaries?
Yes โ add logic to select the template ID dynamically based on subsidiary.
Q2. Can PDFs be generated on-demand by users?
Yes โ create a Suitelet with a โGenerate PDFโ button to trigger manual generation.
Q3. Can I send multiple PDFs in one email?
Yes โ attach multiple files in the attachments
array.
Q4. Does this work for custom records?
Yes โ use render.xmlToPdf()
and a custom FreeMarker XML template.
๐งญ Summary
The Custom PDF Automation System eliminates manual effort and brings full consistency to your document workflow.
From invoices to statements, it ensures every transaction generates a professional, branded PDF โ automatically saved, emailed, and logged.
This framework can be easily extended for bulk reporting, EDI documentation, or multi-brand templates, turning NetSuite into a fully automated document delivery engine.
Leave a Reply