ERPNext Server and Client Scripts: Making things work better and making the user experience better

ERPNext is a strong open-source enterprise resource planning (ERP) system that gives companies a full set of tools to run their businesses. One of the best things about ERPNext is that you can use server and client scripts to change and add to its features. These scripts let users customise the system to fit their needs, automate boring tasks, and make the experience better for everyone. This article will talk about the basics of server and client scripts in ERPNext, give examples of scripts for both types, and explain how Zikpro, a certified Frappe partner, helps clients write scripts for ERPNext.

How to Understand Server and Client Scripts

Server Scripts:

Python is used to write server scripts, which take advantage of the Frappe Framework.

Client Scripts:

Most of the time, client scripts are written in JavaScript and change the UI dynamically by working with the DOM (Document Object Model).

Advantages of Using Server and Client Scripts in ERPNext

Server Scripts in Action

  1. Create Serial Numbers Automatically
    @frappe.whitelist()
    def generate_serial_number(doc):
        if not doc.serial_number:
            doc.serial_number = "SN-" + str(frappe.db.count('Item') + 1)
  2. Check Payment Terms
    @frappe.whitelist()
    def validate_payment_terms(doc):
        if doc.payment_terms not in ["Net 30", "Net 60"]:
            frappe.throw("Invalid payment terms. Pick either Net 30 or Net 60.")
  3. Set the Default Warehouse
    @frappe.whitelist()
    def set_default_warehouse(doc):
        if doc.supplier:
            supplier = frappe.get_doc("Supplier", doc.supplier)
            doc.default_warehouse = supplier.default_warehouse
  4. Change the levels of stock
    @frappe.whitelist()
    def update_stock_levels(doc):
        for item in doc.items:
            item_doc = frappe.get_doc("Item", item.item_code)
            item_doc.stock_qty += item.qty
            item_doc.save()
  5. Send an email alert
    @frappe.whitelist()
    def send_lead_notification(doc):
        frappe.sendmail(
            recipients=["sales@example.com"],
            subject="New Lead Created",
            message=f"New lead created: {doc.lead_name}"
        )
  6. Figure Out How Much Tax
    @frappe.whitelist()
    def calculate_tax_amount(doc):
        tax_rate = 0.05  # 5% tax
        doc.tax_amount = doc.total_amount * tax_rate
  7. Check to make sure that the stock is available
    @frappe.whitelist()
    def check_stock_availability(doc):
        for item in doc.items:
            stock_qty = frappe.db.get_value("Item", item.item_code, "stock_qty")
            if stock_qty < item.qty:
                frappe.throw(f"Insufficient stock for {item.item_code}. Available: {stock_qty}")
  8. Automatically Assign Tasks
    @frappe.whitelist()
    def auto_assign_tasks(doc):
        users = frappe.get_all("User", filters={"role": "Project Manager"})
        if users:
            doc.assigned_to = users[0].name
  9. Make entries in the accounting system
    @frappe.whitelist()
    def create_accounting_entries(doc):
        frappe.get_doc({
            "doctype": "Journal Entry",
            "voucher_type": "Sales",
            "posting_date": doc.posting_date,
            "items": [{"account": "Sales Income", "debit": doc.total_amount}]
        }).insert().submit()
  10. Tell Customers
    @frappe.whitelist()
    def notify_customer(doc):
        customer_email = frappe.get_value("Customer", doc.customer, "email_id")
        frappe.sendmail(
            to=[customer_email],
            subject="Order Shipped",
            message=f"Your order {doc.name} has been sent."
        )

Client Scripts in Action

Here are ten client scripts that can make using ERPNext better for users:

  1. Hide Field Based on What You Choose
    frappe.ui.form.on('Sales Order', {
      on_load: function(frm) {
        if (frm.doc.order_type === 'Retail') {
          frm.set_df_property('wholesale_discount', 'hidden', true);
        }
      }
    });
  2. Show Alert on Form Submission
    frappe.ui.form.on('Lead', {
      before_submit: function(frm) {
        frappe.msgprint('You are about to submit the lead form.');
      }
    });
  3. Auto-Fill Fields
    frappe.ui.form.on('Purchase Order', {
      supplier: function(frm) {
        frappe.db.get_value('Supplier', frm.doc.supplier, 'contact_person', function(r) {
          frm.set_value('contact_person', r.contact_person);
        });
      }
    });
  4. Change Colour of a Field
    frappe.ui.form.on('Sales Invoice', {
      refresh: function(frm) {
        if (frm.doc.status === 'Paid') {
          frm.set_df_property('status', 'options', '
    Paid
    ');
        }
      }
    });
  5. Show Messages That Change
    frappe.ui.form.on('Employee', {
      employment_type: function(frm) {
        if (frm.doc.employment_type === 'Contract') {
          frm.add_custom_button(__('Send Contract'), function() {
            frappe.msgprint('Contract will be sent to the employee.');
          });
        }
      }
    });
  6. Calculate Total Amount
    frappe.ui.form.on('Sales Order', {
      qty: function(frm) {
        frm.set_value('total_amount', frm.doc.qty * frm.doc.unit_price);
      }
    });
  7. Validate Email Format
    frappe.ui.form.on('Customer', {
      email_id: function(frm) {
        var email_regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        if (!email_regex.test(frm.doc.email_id))
          frappe.throw('Please enter a valid email address.');
      }
    });
  8. Complete Task Button
    frappe.ui.form.on('Task', {
      refresh: function(frm) {
        frm.add_custom_button(__('Complete Task'), function() {
          frm.set_value('status', 'Completed');
          frm.save();
        });
      }
    });
  9. Enable/Disable Fields
    frappe.ui.form.on('Sales Order', {
      enable_discount: function(frm) {
        frm.toggle_enable('discount', frm.doc.enable_discount);
      }
    });
  10. Change Field Properties Dynamically
    frappe.ui.form.on('Purchase Invoice', {
      field_name: function(frm) {
        // Your logic here
      }
    });

How Zikpro Helps Clients with ERPNext Scripting

In short, Zikpro’s knowledge of ERPNext scripting not only makes the system work better, but it also makes the whole business run more smoothly, which makes it a good partner for companies that use ERPNext.