Professional Documents
Culture Documents
Contents
2 contact@solufy.in
ERPNext 2nd Edition Ebook
References: 44
3 contact@solufy.in
ERPNext 2nd Edition Ebook
4 contact@solufy.in
ERPNext 2nd Edition Ebook
$ python -V
Python 2.7.15rc1
wget https://bootstrap.pypa.io/get-pip.py
5 contact@solufy.in
ERPNext 2nd Edition Ebook
Execute the following command to verify that you have the latest version of pip and
setuptools.
Install the ansible module using pip. Ansible pip module automates manage Python
libraries and configuration.
6 contact@solufy.in
ERPNext 2nd Edition Ebook
When creating ERPNext database, you need to enable barracuda storage engine. So
you first need to configure MariaDB configuration my.cnf file.
[mysqld]
innodb-file-format=barracuda
innodb-file-per-table=1
innodb-large-prefix=1
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
[mysql]
default-character-set = utf8mb4
Next, you have to restart MariaDB and enable it to auto start MariaDB at boot time.
7 contact@solufy.in
ERPNext 2nd Edition Ebook
sudo mysql_secure_installation
This tool will ask if you want to set a new password for the MySQL root user and few
security related questions.
To install Nginx, Node.js and Redis on Ubuntu, run the commands below.
8 contact@solufy.in
ERPNext 2nd Edition Ebook
After installing, start and enable Nginx service to always start up with the boots.
Start and enable Redis service to always start up with the boots.
wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/
sudo tar -xf wkhtmltox-0.12.4_linux-generic-amd64.tar.xz -C /opt
Next, you have to create a soft link to access and execute wkhtmltopdf and
wkhtmltoimage globally as a command.
9 contact@solufy.in
ERPNext 2nd Edition Ebook
$ wkhtmltopdf -V
wkhtmltopdf 0.12.4 (with patched qt)
mkdir erpnext
cd erpnext/
Furthermore, you need to create virtual environment on “erpnext” directory using the
following command.
virtualenv .
Even more, you have to activate virtual environment using below command.
source ./bin/activate
10 contact@solufy.in
ERPNext 2nd Edition Ebook
cd frappe-bench/
11 contact@solufy.in
ERPNext 2nd Edition Ebook
bench start
Finally, go to your web browser open your server IP address with 8000 port number
http://0.0.0.0:8000 and you will see the ERPNext login screen. Here you have to log in with
username “administrator” and password as per you set when you created the new site.
12 contact@solufy.in
ERPNext 2nd Edition Ebook
2) Install site:
frappe-bench$ bench --site <<site name>> install-app <<apps name>>
3) Start bench:
frappe-bench$ bench start
13 contact@solufy.in
ERPNext 2nd Edition Ebook
1. Controller Module
A controller template is created when the DocType is created. which looks like
import frappe
from frappe.model.document import Document
class EbookExample(Document):
pass
2. Document Properties
All the fields and child tables are available to the class as attributes. For example the name
property is self.name
3. Adding Methods
In this module, you can add standard methods to the class that are called when a document of
that type is created. Standard Handlers are:
validate
on_submit
on_cancel
before_insert
on_update
on_trash
autoname
before_save
after_insert
before_submit
before_cancel
before_update_after_submit
on_update_after_submit
14 contact@solufy.in
ERPNext 2nd Edition Ebook
on_change
after_delete
# Document Events
# ---------------
doc_events = {
"Item" :{
"validate" :
"sample_demo.sample_demo.doctype.ebook_example.ebook_example.call_validate",
},
"Sales Order" :{
"validate" :
"sample_demo.sample_demo.doctype.ebook_example.ebook_example.validate",
"on_submit" :
"sample_demo.sample_demo.doctype.ebook_example.ebook_example.on_submit",
"on_cancel" :
"sample_demo.sample_demo.doctype.ebook_example.ebook_example.on_cancel",
"before_insert" :
"sample_demo.sample_demo.doctype.ebook_example.ebook_example.before_insert",
"on_update" :
"sample_demo.sample_demo.doctype.ebook_example.ebook_example.on_update",
"on_trash" :
"sample_demo.sample_demo.doctype.ebook_example.ebook_example.on_trash"
},
"Ebook Example" :{
"autoname" :
"sample_demo.sample_demo.doctype.ebook_example.ebook_example.autoname",
},
# ebook_example.py
# -----------------------
15 contact@solufy.in
ERPNext 2nd Edition Ebook
class EbookExample(Document):
pass
def call_validate(self,cdt):
frappe.msgprint(_("Validating"))
print ("\n CALL DOC ID:::::::::::::::",self.name)
doc = frappe.get_doc('Item',self.name)
print ("\n CALL DOC OBJECT::::::::::::::::::",doc)
print ("\n item_name::::::::::::::::::",doc.item_name)
def validate(self,cdt):
frappe.msgprint(_("Validating"))
def on_submit(self,cdt):
frappe.msgprint(_("Submiting"))
print ("\n CALL DOC ID:::::::::::::::",self.name)
def on_cancel(self,cdt):
frappe.msgprint(_("Canceling"))
def before_insert(self,cdt):
frappe.msgprint(_("Inserting"))
def on_update(self,cdt):
frappe.msgprint(_("Updating"))
def on_trash(self,cdt):
frappe.msgprint(_("Trashing"))
def autoname(self,cdt):
frappe.msgprint(_("autoname"))
16 contact@solufy.in
ERPNext 2nd Edition Ebook
Concept: Multi tenant feature is maintain separate database for single server, so that record
created in one site(site1.local) should not be visible in other site(site2.local).
17 contact@solufy.in
ERPNext 2nd Edition Ebook
just go in /etc/hosts
and define the domain
for ex:
127.0.0.1 site1.local
127.0.0.1 site2.local
127.0.0.1 site3.local
http://site1.local:8000/desk
http://site2.local:8000/desk
http://site3.local:8000/desk
Backup:
Take a backup of you ERPNext site by executing following command: bench --site site1.local
backup
backup created by default : /workspace/erpnext/frappe-bench/sites/site1.local/private
Restore database:
bench --site site2.local --force restore bench --site site2.local --force restore
/home/serpentcs/workspace/erpnext/frappe-bench/sites/site1.local/private/backups/20200108_1
60525-site1_local-database.sql.gz
Delete database:
bench drop-site site2.local
18 contact@solufy.in
ERPNext 2nd Edition Ebook
Create custom doc type "Parent Child Category" with below fields and settings:
View setting :
Title: category_name
frappe.ui.form.on('Item',{
onload: function(frm) {
console.log("par::::::::",frm.doc);
cur_frm.set_query("parent_category", function() {
console.log("dddddddddddddddddddddd",frm.doc);
return {
"filters": {
"parent_id": ("=", "")
}
};
});
}
});
19 contact@solufy.in
ERPNext 2nd Edition Ebook
frappe.ui.form.on('Item',{
"parent_category": function(frm) {
console.log("frm::::::::",frm.doc);
cur_frm.set_query("child_category", function() {
return {
"filters": {
"parent_id": frm.doc.parent_category
}
};
});
}
});
Hook.py:
doctype_js = {
"Item": "public/js/custom.js",
}
20 contact@solufy.in
ERPNext 2nd Edition Ebook
Screen Shot:
21 contact@solufy.in
ERPNext 2nd Edition Ebook
custom.js:
frappe.listview_settings['Customer'] = {
get_indicator:function(doc){
if (doc.status === "Open") {
return [__("Open"), "green", "status,=,Opened"];
}
if (doc.status === "Close") {
return [__("Close"), "red", "status,=,Closed"];
}
}
}
hook.py:
22 contact@solufy.in
ERPNext 2nd Edition Ebook
Screen Shot:
23 contact@solufy.in
ERPNext 2nd Edition Ebook
frappe.get_doc(doctype, name)
e.g. frappe.get_doc('Customer', 'self.name')
Load a document from the database with give doctype (table) and name Returns a Document
object. All columns are properties. e.g. doc.name
custom.py method:
def call_customer_doc_object(self,cdt):
print ("\n CALL DOC ID:::::::::::::::",self.name)
doc = frappe.get_doc('Customer',self.name)
print ("\n CALL DOC OBJECT::::::::::::::::::",doc)
print ("\n customer_name::::::::::::::::::",doc.customer_name)
print ("\n customer_type::::::::::::::::::",doc.customer_type)
print ("\n customer_group::::::::::::::::::",doc.customer_group)
hooks.py file:
doc_events = {
"Customer" :{
"validate" :
"sample_demo.sample_demo.doctype.parent_child_category.parent_child_category.call_custo
mer_doc_object",
}
}
24 contact@solufy.in
ERPNext 2nd Edition Ebook
In Frappe Framework, you can manage ajax calls via frappe.call. The frappe.call works in
asynchronous manner ie. send requests and handle response via callback mechanism.
frappe.call Structure:
frappe.call({
args: args,
success: callback,
error: opts.error,
always: opts.always,
btn: opts.btn,
freeze: opts.freeze,
freeze_message: opts.freeze_message,
async: opts.async,
})
25 contact@solufy.in
ERPNext 2nd Edition Ebook
Parameter description :
type: String parameter, http request type "GET", "POST", "PUT", "DELETE". Default set to
"POST".
success: Function parameter, code snippet, will after successful execution of request
error: Function parameter, code snippet, will execute after request failure
freeze: Boolean parameter, if set freeze the instance util it receives response
freeze_message: String parameter, message will populate to screen while screen is in freeze
state.
async: Boolean parameter, default set to true. So each frappe.call is asynchronous. To make
call synchronous set parameter value as false
26 contact@solufy.in
ERPNext 2nd Edition Ebook
@frappe.whitelist()
def custom_print_date(date=None):
print ("\n custom_print_date method:::::::::::::::::")
date = date or today()
return date
Hook.py:
# Define custom js
#-----------------------
doctype_js = {
"Ebook Example": "public/js/custom.js",
}
27 contact@solufy.in
ERPNext 2nd Edition Ebook
Screen Shot:
28 contact@solufy.in
ERPNext 2nd Edition Ebook
You will now see an icon for the Sample Demo module. If you do not see an icon you will have
to configure the desk. So go to the config folder (of the newly made app) and create a new file
sample_demo.py.
Directory Structure
apps/
├── frappe
└── sample_demo
├── MANIFEST.in
├── README.md
├── sample_demo
│ ├── __init__.py
│ ├── config
│ │ ├── __init__.py
│ │ ├── desktop.py
│ │ ├── docs.py
│ │ └── sample_demo.py <--Here
│ ├── hooks.py
│ ├── sample_demo
│ │ ├── __init__.py
│ │ └── doctype
│ ├── modules.txt
│ ├── patches.txt
│ ├── public
│ ├── templates
│ └── www
Paste the following code to configure the desk in order to view the Module.
29 contact@solufy.in
ERPNext 2nd Edition Ebook
def get_data():
return[
{
"label": ("ERPNext Example"),
"items": [
{
"type": "doctype",
"name": "Ebook Example",
"onboard": 1,
"label": _("ERNext EBook Example"),
"description": _("ERPNext Tutorials Technical Guide-2020"),
}
]
}
]
Now save the script and reload the page. You should see the icon for the sample demo module.
Click on that icon and you will see the Module page:
30 contact@solufy.in
ERPNext 2nd Edition Ebook
You can create tabulated reports using server side scripts by creating a new Report.
31 contact@solufy.in
ERPNext 2nd Edition Ebook
2 In the .py file you can add the script for generating the report.
1) In the execute method, two lists columns and data are returned
2) Columns must be a list of dictionaries containing fields like fieldname, label, fieldtype,
options,width. For example:
custom_script_report.py file :
def execute(filters=None):
columns = get_report_columns()
data = get_report_data(filters)
return columns, data
def get_report_columns():
columns = [{
"fieldname": "name1",
"label": _("Name"),
"fieldtype": "Data",
"options": "",
"width": 200
},
{
"fieldname": "address",
"label": _("Address"),
"fieldtype": "Data",
"width": 200
},
]
return columns
def get_report_data(filters=None):
data = get_orders(filters)
32 contact@solufy.in
ERPNext 2nd Edition Ebook
return data
def get_orders(filters):
#additional_conditions = get_additional_report_conditions(filters)
test_q = """select name1, address from `tabEbook Example`"""
return frappe.db.sql(test_q, as_dict=True)
In the module folder (for example if it is sample_demo in ERPNext the folder will be
erpnext/sample_demo/config/sample_demo.py) you will see labels and items for various
sections. The new report can be added in the item list as show in the example:
def get_data():
return[
{
"label": ("ERPNext Example"),
"items": [
{
"type": "doctype",
"name": "Ebook Example",
"onboard": 1,
"label": _("ERNext EBook Example"),
"description": _("ERPNext Tutorials Technical Guide-2020"),
}
]
},
{
"label": ("Reports"),
"items": [
{
"type": "report",
"name": "Custom Script Report",
"doctype": "Ebook Example",
"is_query_report": True
}
33 contact@solufy.in
ERPNext 2nd Edition Ebook
]
},
]
34 contact@solufy.in
ERPNext 2nd Edition Ebook
<small>
{{ add_header(0,1,doc,letter_head, no_letterhead) }}
35 contact@solufy.in
ERPNext 2nd Edition Ebook
font-size: 14px;
font-weight: normal;
} */
.table{
border: 1px solid black;
color:#000000;
font-size:16px;
}
.tr{
border: 1px solid black;
}
<div>
<table style="height: 36px;" width="100%">
<tbody>
36 contact@solufy.in
ERPNext 2nd Edition Ebook
<tr>
{% if doc.company_address %}
{% set cc = frappe.get_doc("Address", doc.company_address) %}
<td style="width: 292.5px;"><b> {{ doc.company_address }}</b> <br></br><b>GSTIN :</b> {{
cc.gst_state_number }} <br /><b>Address :</b> {{ cc.address_line1 }} <br /><b>Phone :</b>{{
cc.phone }} <br>
<b>Emails :</b> {{ cc.email_id }}</td>
{% endif %}
<td style="width: 292.5px;"> </td>
<td style="width: 292.5px;">
<p><strong>GST INVOICE</strong></p><br>
<p><strong>Invoice ID :</strong> {{ doc.name }} </p>
<p><strong>Invoice Date :</strong> {{ doc.po_date }}</p>
<p><strong>Eligible for Reverse GST : </strong> Yes</p>
</td>
</tr>
</tbody>
</table>
</div>
<div><hr /></div>
<div>
<table style="height: 36px;" width="100%" printdata>
<tbody>
<tr>
<td style="width: 292.5px;"> <strong>PO ID :</strong> {{ doc.po_no }}</td>
<td style="width: 292.5px;"> <strong>PO Date : </strong> {{ doc.po_date }}</td>
<td style="width: 292.5px;"> <strong>Payment : </strong>{{ doc.outstanding_amount
}}</td>
</tr>
</tbody>
</table>
</div>
<div><hr /></div>
<div>
<table style="height: 36px;" width="100%">
<tbody>
<tr>
<td style="width: 292.5px;">
37 contact@solufy.in
ERPNext 2nd Edition Ebook
</td>
<td style="width: 292.5px;"> </td>
<td style="width: 292.5px;">
<p><strong>Shipped to: </strong>{{ doc.shipping_address_name }}</p>
<p><strong>Shipping Mode:</strong></p>
<p><strong>Vehicle No.: </strong></p>
<p><strong> Place of Supply:</strong>{{ doc.place_of_supply }}</p>
</td>
</tr>
</tbody>
</table>
</div>
<div>
38 contact@solufy.in
ERPNext 2nd Edition Ebook
</tr>
{%- endfor -%}
</tbody>
</table>
</div>
<div>
<table width="100%">
<tbody>
<tr>
<td style="width: 292.5px;" colspan="3"><strong>Tax Breakup:</strong>
<table class="table table-condensed table-hover table-bordered" width="100%">
<tbody>
39 contact@solufy.in
ERPNext 2nd Edition Ebook
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<td>
</td>
</div>
<div>
<table style="height: 36px;" width="100%">
<tbody>
<tr>
<td> {{ doc.terms }}</td>
</tr>
</tbody>
</table>
</div>
<div>
<p> </p><p> </p><p> </p>
40 contact@solufy.in
ERPNext 2nd Edition Ebook
<p> </p><p> </p><p> </p>
<div>
<table style="height: 36px;" width="100%">
<tbody>
<tr>
<td style="width: 292.5px;" align="left"> <strong>GST Invoice: </strong>{{ doc.name
}} </td>
<td style="width: 292.5px;" align="center"> NB : Company Stamp or Signature not
required, if this document has received by email. <br />Dated: {{ doc.get_formatted }}</td>
<td style="width: 292.5px;" align="right"> <strong> Page No: 1 to 1 </strong></td>
</tr>
</tbody>
</table>
</div>
{% endif %}
override_whitelisted_methods = {
"Frappe.templates.print_formats.standard":
"tax_invoice.tax_invoice.templates.print_formats.standard",
41 contact@solufy.in
ERPNext 2nd Edition Ebook
4) Screen shot
42 contact@solufy.in
ERPNext 2nd Edition Ebook
References:
1) https://frappe.io/docs/user/en/tutorial
43 contact@solufy.in