Building a Custom App in Frappe: A Step-by-Step Guide
Frappe is a powerful framework for building web applications, most notably used as the foundation for ERPNext. This blog post will guide you through the process of creating a new app, adding a custom Doctype, defining fields, and implementing buttons to enhance functionality. Whether you're an experienced developer or just getting started, these steps will help you extend the capabilities of your Frappe applications.
Creating a New App in Frappe
To begin, we need to create a new app within our Frappe environment. Follow these steps:
- Open Your Terminal: Navigate to the Frappe Bench directory.
Create a New App: Use the command:
bench new-app your_app_name
For example:
bench new-app starinfinity_integration
Install the App: Install it on your specific ERPNext site:
bench --site your-site-name install-app your_app_name
For example:
bench --site your-site-name install-app Test
- Verify Installation: Log into your ERPNext instance to confirm that your new app appears in the list of installed applications.
Creating a New Doctype
Once your app is created, the next step is to add a custom Doctype. Here's how to do it:
- Log Into Your ERPNext Instance: Go to your ERPNext URL and log in with your credentials.
- Access the Developer Module: Navigate to the Developer module. Ensure that developer mode is enabled in your
common_site_config.json
file by adding: - Create a New Doctype: Click on "Doctype" in the Developer module and then click "New".
- Fill in Doctype Details: Enter the Doctype name (e.g., Starinfinity Data), select the module, and add necessary fields.
Adding Fields to Your Doctype
You can define fields for your Doctype using JSON. Here's an example JSON structure for adding fields:
{
"name": "Your DocType Name",
"fields": [
{
"fieldname": "task_name",
"label": "Task Name",
"fieldtype": "Data",
"mandatory": 1,
"in_list_view": 1
},
{
"fieldname": "due_date",
"label": "Due Date",
"fieldtype": "Date",
"in_list_view": 1
},
{
"fieldname": "assigned_to",
"label": "Assigned To",
"fieldtype": "Link",
"options": "User"
},
{
"fieldname": "description",
"label": "Description",
"fieldtype": "Text Editor"
},
{
"fieldname": "status",
"label": "Status",
"fieldtype": "Select",
"options": "\nOpen\nIn Progress\nClosed",
"in_list_view": 1
}
],
"permissions": [
{
"role": "All",
"read": 1,
"write": 1,
"create": 1,
"delete": 1
}
]
}
Explanation of the JSON Fields
- name: The name of the Doctype.
- fields: An array of field objects, each defining a new field.
- fieldname: The name of the field in the database.
- label: The label displayed in the form.
- fieldtype: The type of field (e.g.,
Data
,Date
,Link
,Text Editor
,Select
, etc.). - mandatory: Whether the field is required (1 for Yes, 0 for No).
- reqd: This can also be used to indicate if the field is mandatory (1 for Yes, 0 for No).
- in_list_view: Whether to display the field in the list view (1 for Yes, 0 for No).
- options: Used for fields like
Select
to define the available options, separated by new lines.
- permissions: An array that defines permissions for different user roles. Here, it grants all permissions to the role "All".
Creating Buttons in Form and List Views
Adding buttons enhances user interaction with your Doctype. To create buttons in both the form and list views, follow these steps:
Step 1: Define the Button in the Doctype's JavaScript File
Navigate to your Doctype's JavaScript file, usually located at:
your_app_name/your_app_name/public/js/doctype_name.js
Add the following code for the form view:
frappe.ui.form.on('Your Doctype Name', { onload: function(frm) { frm.add_custom_button(__('Your Button Label'), function() { frappe.call({ method: 'your_app_name.your_module_name.doctype_name.your_function_name', args: { docname: frm.doc.name }, callback: function(response) { if (response.message) { frappe.show_alert({message: __('Success Message'), indicator: 'green'}); } } }); }); } });
Step 2: Add the Button to the List View
Add the following code outside the onload function:
frappe.listview_settings['Your Doctype Name'] = {
on_page_load: function(listview) {
listview.page.add_inner_button(__('Your Button Label'), function() {
var selected = listview.get_selected();
if (selected.length > 0) {
frappe.call({
method: 'your_app_name.your_module_name.doctype_name.your_function_name',
args: {
docnames: selected
},
callback: function(response) {
if (response.message) {
frappe.show_alert({message: __('Success Message'), indicator: 'green'});
}
}
});
} else {
frappe.msgprint(__('Please select at least one document.'));
}
});
}
};
Step 3: Define the Python Function
In the associated Python file for your Doctype (usually found at your_app_name/your_app_name/doctype/your_doctype_name/your_doctype_name.py
), define the function:
import frappe
@frappe.whitelist()
def your_function_name(docname):
doc = frappe.get_doc('Your Doctype Name', docname)
doc.fieldname = 'New Value'
doc.save()
return "Success"
The @frappe.whitelist()
decorator in Frappe allows a function to be accessed and called via client-side code (typically from JavaScript or other external sources) securely. In Frappe, functions that interact with the database or perform backend tasks are typically not accessible from the frontend unless explicitly made so, to avoid unauthorized access or security vulnerabilities.
By marking a function with @frappe.whitelist()
, you are:
- Making the Function Publicly Accessible: It can be called from JavaScript using
frappe.call
or through HTTP requests (like API calls), allowing interaction between the front-end (e.g., a button click) and back-end logic. - Ensuring Security: Only the functions that are decorated with
@frappe.whitelist()
can be accessed externally, keeping the rest of the backend methods private by default. This reduces the attack surface and ensures that only intended functions are exposed.
Final Thoughts
Building a custom app in Frappe empowers you to tailor your ERPNext environment to meet your unique business requirements. By understanding the fundamentals of Doctype creation, field definitions, and client-server interactions, you can create robust and efficient applications that enhance your organization's productivity and operational efficiency.
Remember, the Frappe and ERPNext communities are vibrant and supportive. Don't hesitate to seek help, share your projects, and collaborate with other developers to continuously improve your skills and applications. Regularly updating your knowledge and staying engaged with the community will ensure that your custom apps remain relevant, secure, and feature-rich.
Thank you for following this step-by-step guide. We hope it has been instrumental in your journey to building custom applications with Frappe. Should you have any questions or need further assistance, feel free to reach out through the community forums or consult the official documentation for more in-depth information.
Happy Developing!