ERPNext Customization Masterclass: DocTypes, Server Scripts & Jinja Print Formats
Learn how to customize ERPNext without breaking core updates! Master Client Scripts (JS), Server Scripts (Python), Custom Fields, and Jinja PDF templates.

Header Ad Advertisement
One of the biggest advantages of ERPNext over proprietary ERP systems like SAP or NetSuite is its unbelievable flexibility.
However, many beginner developers make the fatal mistake of modifying core ERPNext source files directly inside apps/erpnext/. When the next ERPNext version update rolls out, all custom code gets overwritten and destroyed!
In this masterclass, we cover the 4 upgrade-safe ways to customize ERPNext for any enterprise workflow:
1. Upgrade-Safe Customization Options
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. Custom Fields & Property Setters (UI Config) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 2. Client Scripts (Browser JavaScript Form Automation) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 3. Server Scripts (Sandboxed Python Event Hooks & APIs) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 4. Jinja2 Print Formats (Custom PDF Quotations & Invoices) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
2. Client Scripts (JavaScript Form Events)
Client Scripts run in the user's browser whenever a document form (like Sales Order or Quotation) is opened, modified, or saved.
๐ป Example: Auto-Calculate Discount in Sales Invoice
Navigate to Desk โ Client Script โ New:
// Target DocType: Sales Invoice
frappe.ui.form.on('Sales Invoice', {
refresh(frm) {
// Add custom action button to form toolbar
frm.add_custom_button(__('Apply VIP Discount 10%'), function() {
let total = frm.doc.grand_total || 0;
let discount = total * 0.10;
frm.set_value('discount_amount', discount);
frappe.show_alert({ message: __('10% VIP Discount Applied!'), indicator: 'green' });
});
},
grand_total(frm) {
// Trigger validation if total exceeds limit
if (frm.doc.grand_total > 500000 && !frm.doc.approved_by_manager) {
frappe.msgprint(__('Sales Invoices above โน5 Lakhs require Manager approval before submitting.'));
}
}
});
3. Server Scripts (Sandboxed Python Hooks)
Server Scripts allow system administrators and developers to execute backend Python code directly from the Desk UI without touching the filesystem!
๐ Example: Send Slack/WhatsApp Notification on High-Value Sales Order
Navigate to Desk โ Server Script โ New:
# Script Type: Document Event | DocType: Sales Order | Event: Before Submit
if doc.grand_total > 1000000: # Exceeds โน10 Lakhs
# Enforce custom restriction
if not doc.po_no:
frappe.throw("Customer PO Number is required for Sales Orders over โน10 Lakhs!")
# Send webhook notification to team chat
import json
payload = {
"text": f"๐ High-Value Sales Order Submitted: {doc.name} for โน{doc.grand_total:,.2f} by {doc.owner}"
}
# Execute HTTP request
# frappe.make_get_request / post request
4. Custom Jinja PDF Print Formats
ERPNext uses Jinja2 templating to render PDF documents for Invoices, Purchase Orders, and Delivery Notes.
<!-- Print Format: Custom Sales Invoice PDF -->
<div class="invoice-box" style="font-family: Arial, sans-serif; padding: 20px;">
<div style="display: flex; justify-[#1fa3a3] space-between; border-bottom: 2px solid #0f1d30; padding-bottom: 10px;">
<h2>{{ doc.company }}</h2>
<h3 style="color: #1fa3a3;">TAX INVOICE</h3>
</div>
<table style="width: 100%; margin-top: 15px; text-align: left; font-size: 12px;">
<tr>
<td><strong>Invoice No:</strong> {{ doc.name }}</td>
<td><strong>Date:</strong> {{ doc.get_formatted("posting_date") }}</td>
</tr>
<tr>
<td><strong>Customer:</strong> {{ doc.customer_name }}</td>
<td><strong>GSTIN:</strong> {{ doc.company_gstin or 'N/A' }}</td>
</tr>
</table>
<!-- Items Table -->
<table style="width: 100%; border-collapse: collapse; margin-top: 20px; font-size: 11px;">
<thead>
<tr style="background-color: #0f1d30; color: #fff;">
<th style="padding: 8px;">#</th>
<th style="padding: 8px;">Item Description</th>
<th style="padding: 8px; text-align: center;">Qty</th>
<th style="padding: 8px; text-align: right;">Rate (โน)</th>
<th style="padding: 8px; text-align: right;">Amount (โน)</th>
</tr>
</thead>
<tbody>
{% for item in doc.items %}
<tr style="border-bottom: 1px solid #ddd;">
<td style="padding: 8px;">{{ loop.index }}</td>
<td style="padding: 8px;"><strong>{{ item.item_name }}</strong><br><small>{{ item.description }}</small></td>
<td style="padding: 8px; text-align: center;">{{ item.qty }}</td>
<td style="padding: 8px; text-align: right;">{{ "{:,.2f}".format(item.rate) }}</td>
<td style="padding: 8px; text-align: right;">{{ "{:,.2f}".format(item.amount) }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
Mid Content Ad Advertisement
Interactive Developer Tools & Calculators
View All Tools โJSON Formatter
Format, validate and beautify JSON with syntax highlighting and error detection.
Base64 Encoder
Encode and decode Base64 strings and files instantly in your browser.
JWT Decoder
Decode and inspect JSON Web Tokens โ header, payload, claims, and expiry.
Regex Tester
Test and debug regular expressions with live match highlighting and flag toggles.
Editorial Disclaimer
The information in this article is provided for educational and informational purposes only. While we strive for accuracy, content may become outdated as technologies, regulations, and best practices evolve. Learntrix and Vyuhantrix make no warranties regarding the completeness, accuracy, or applicability of the information to your specific situation. Always verify critical information from primary and authoritative sources before implementation.
Last content review: August 2026 ยท Learntrix by Vyuhantrix
Copyright 2026 Vyuhantrix Technologies. All content on Learntrix is the intellectual property of Vyuhantrix. Reproduction, distribution, or republishing of this article โ in whole or in part โ without written permission from Vyuhantrix is strictly prohibited.
Footer Article Ad Advertisement
Related Articles
View all in Programming & Development โ
Frappe Framework 101: Complete ERPNext & Python Web Development Guide
Master Frappe Framework & ERPNext! Learn DocTypes, Python ORM, MariaDB/Postgres setup, Desk UI, Hooks, and REST API development with real code examples.

How Does a Solar Eclipse Work: Umbra, Penumbra & Geometry Explained Simply
Why does the Moon cover the Sun so perfectly? Learn the orbital geometry, umbra, penumbra, and total vs partial solar eclipses with simple 8th-grade analogies.
