Share
๐Ÿ’ฌ WhatsApp๐• Post
๐Ÿ’ป Programming & DevelopmentAdvancedโฑ 4 min read

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.

ERPNext Customization Masterclass: DocTypes, Server Scripts & Jinja Print Formats
๐Ÿ’ปProgramming & Development
LEARNTRIX VISUAL
100% Free Knowledgeโ€ขโฑ 4 min deep read
โœฆ Shareable Infographic Guide
๐Ÿ“… Published: 3 August 2026|VVyuhantrix Editorial Team
โœ“ ELIF8 Verifiedยฉ Learntrix

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

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.

Tags:#erpnext customization#frappe server scripts#erpnext jinja print#custom doctypes#erpnext developer

Footer Article Ad Advertisement