An introduction to ERPNext module development
In our previous article about ERPNext, we had briefly presented the tools with a promise, come back with another one to describe how to develop modules with Frappé, the framework behind the scene. Here it is !
Because this subject is incredibly huge, we do not cover all problematics about module development. Today we'll focus on basics to produce a minimum viable application.
Like we saw in the post about MeteorJs, we are going to build an application to manage interventions with these prerequisites:
- The application provides a way to create a user account and to log in
- The application is available for connected users only
- It should be possible to add, edit, and delete customers
- it should be possible to add, edit and delete interventions linked to these customers
Before starting the application development let's review some core concepts :
- Frappé is a framework which allows creating applications
- ERPNext is an application built with Frappé
- Bench is a collection of command line tools to help the developer in his tasks
Starting a new project
First of all, install the bench tools. You'll find all explanations about it in the official documentation.
Once installed, we can start a new project with these commands:
bench init frappe-demo
cd frappe-demo
bench get-app erpnext https://github.com/frappe/erpnext
bench new-site demo
bench install-app erpnext
Some explanations:
- We initiate the "frappe-demo" project and go into its directory
- We download the "erpnext" application
- We start a new website called "demo"
- Then, we push the downloaded erpnext app onto the website
Now, execute the bench start
command and go to localhost:8000
you should see something like this screen
Great ! We have a working ERPNext instance, we can play with it and start developing our module.
The intervention management application
Let's use again "bench" to start our application. As we saw, the bench is a nice tool which will help in your applications management. Really powerfull you'll find all the documentation you need in the official page.
To create our application (assuming you're still in the frappe-demo folder) execute the command bench new-app {app_name}
and follow instructions. The command creates a boilerplate application for you:
$ bench new-app interventions_management
App Title (defaut: Lib Mgt): Interventions Management
App Description: App for interventions
App Publisher: Anybox
App Email: smorele@anybox.fr
App Icon (default 'octicon octicon-file-directory'):
App Color (default 'grey'):
App License (default 'MIT'):
If you go back to your ERPNext desk screen, there are no changes, it's just because we did not add our application to the website. Then, as we did before with the ERPNext application, add the new application with the command bench install-app interventions_management
. Our application is still invisible on the desk but you can search it in the top search bar and you'll find it but at this moment it's a blank page.
Let's add roles and models.
Roles and permissions
Roles are a feature to manage user permissions on models. In our example, we can define two differents roles:
- Administrator who can create, update, and delete interventions and customers. We'll use the provided Administrator role
- Technician who can only read interventions and cannot access customers
To create the technician role, go to Setup > Users > Role > New
Application models
Models in Frappé are called DocTypes and you can create them directly from the web interface. All Doctypes are made of fields called DocFields.
When you create a DocType a new folder is created in the module and a model JSON file and a controller template in Python are automatically created. When you update the DocType, the JSON model file is updated and whenever bench migrate
is executed, it is synced with the database. This makes it easy to propagate schema changes and migrate the database.
To create a new doctype, go to Developer > Documents > Doctype > New
from your Desk interface.
This interface allows us to create and manage DocTypes, let's start with the first DocType called intervention.
First of all, the interface asks which module is concerned. In our case it's interventions_management. Then we add fields:
Field nameTypeDetailtitleData detailText authorLinkAdd "user" into options fieldprioritySelectAdd values "Low", "Medium", "high" into options fieldcustomerLinkAdd customer into options field
Our intervention is linked to two other models, User which is a core model and Customer, a new one we need to define. In this tutorial context, we juste define a customer with a name even if in the reality we should need more fields to fill adress, phone, and other details.
Field nameTypeDetailcustomer_nameData
By defining these two models, our application is almost done. Seriously ! Save and go to the desk UI.
Because everything is magic, you should see your app beside others.
Change the application behavior with Controllers
Our application is plainly fonctionnal but we can make some improvements. For example, in our intervention model we have defined an author. It would be great if this field was filled automatically with the current user. To do so , we'll use a controller. A controller is a Python class which manages actions on models through differents events:
before_insert
validate
(before inserting or updating)on_update
(after saving)on_submit
(when document is set as submitted)on_cancel
on_trash
(before it is about to be deleted)
In the case of the intervention DocType, the controller is apps/interventions_management/interventions_management/interventions_management/doctype/intervention/intervention.py
Take a minute to read this piece of code and understand what it does:
Some explanations. Our class inherits the Document class, then we can access our record via self
. Frappé comes with builtin methods to get session data or for example raise an exception and we use them to set the author or inform user if there are no sessions. Simple isn't it ?
And finally let the magic operate
Until now, we only focus on models and controllers. We never wrote a line for the presentation layer but you can currently enter some records from the desk interface. It's possible thanks to the framework which builds the interface with models and permission definitions. Then because our DocField have properties and our user too, Frappé knows exactly what data to present and how.
This introduction to module development is now finished. We have discovered how to create applications fastly and easily. There is so much to say about Frappé and ERPNext, we cannot concat all subjects in an unique blog post. Feel free to contact us to talk about or if you need us to get into a specific point, otherwise see you in a future post !