Merge branch 'develop' into social-media-integration-feat
diff --git a/erpnext/accounts/doctype/account_subtype/account_subtype.json b/erpnext/accounts/doctype/account_subtype/account_subtype.json
deleted file mode 100644
index 6b1f2a2..0000000
--- a/erpnext/accounts/doctype/account_subtype/account_subtype.json
+++ /dev/null
@@ -1,134 +0,0 @@
-{
- "allow_copy": 0, 
- "allow_events_in_timeline": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 1, 
- "autoname": "field:account_subtype", 
- "beta": 0, 
- "creation": "2018-10-25 15:46:08.054586", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
- "fields": [
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "account_subtype", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Account Subtype", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 1
-  }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2018-10-25 15:47:03.841390", 
- "modified_by": "Administrator", 
- "module": "Accounts", 
- "name": "Account Subtype", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [
-  {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "System Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }, 
-  {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Accounts Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }, 
-  {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Accounts User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 0, 
- "track_seen": 0, 
- "track_views": 0
-}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/account_type/account_type.js b/erpnext/accounts/doctype/account_type/account_type.js
deleted file mode 100644
index 858b56c..0000000
--- a/erpnext/accounts/doctype/account_type/account_type.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Account Type', {
-	refresh: function() {
-
-	}
-});
diff --git a/erpnext/accounts/doctype/account_type/account_type.json b/erpnext/accounts/doctype/account_type/account_type.json
deleted file mode 100644
index 6b8f724..0000000
--- a/erpnext/accounts/doctype/account_type/account_type.json
+++ /dev/null
@@ -1,134 +0,0 @@
-{
- "allow_copy": 0, 
- "allow_events_in_timeline": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 1, 
- "autoname": "field:account_type", 
- "beta": 0, 
- "creation": "2018-10-25 15:45:45.789963", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
- "fields": [
-  {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "account_type", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Account Type", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 1
-  }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2018-10-25 15:46:51.042604", 
- "modified_by": "Administrator", 
- "module": "Accounts", 
- "name": "Account Type", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [
-  {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "System Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }, 
-  {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Accounts Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }, 
-  {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Accounts User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
-   "write": 1
-  }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 0, 
- "track_seen": 0, 
- "track_views": 0
-}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/account_type/test_account_type.js b/erpnext/accounts/doctype/account_type/test_account_type.js
deleted file mode 100644
index 76e434f..0000000
--- a/erpnext/accounts/doctype/account_type/test_account_type.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/* eslint-disable */
-// rename this file from _test_[name] to test_[name] to activate
-// and remove above this line
-
-QUnit.test("test: Account Type", function (assert) {
-	let done = assert.async();
-
-	// number of asserts
-	assert.expect(1);
-
-	frappe.run_serially([
-		// insert a new Account Type
-		() => frappe.tests.make('Account Type', [
-			// values to be set
-			{key: 'value'}
-		]),
-		() => {
-			assert.equal(cur_frm.doc.key, 'value');
-		},
-		() => done()
-	]);
-
-});
diff --git a/erpnext/accounts/doctype/account_type/test_account_type.py b/erpnext/accounts/doctype/account_type/test_account_type.py
deleted file mode 100644
index 824c2f6..0000000
--- a/erpnext/accounts/doctype/account_type/test_account_type.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-import unittest
-
-class TestAccountType(unittest.TestCase):
-	pass
diff --git a/erpnext/accounts/doctype/bank_account/bank_account.json b/erpnext/accounts/doctype/bank_account/bank_account.json
index aa9c434..65a0a51 100644
--- a/erpnext/accounts/doctype/bank_account/bank_account.json
+++ b/erpnext/accounts/doctype/bank_account/bank_account.json
@@ -64,13 +64,13 @@
    "fieldname": "account_type",
    "fieldtype": "Link",
    "label": "Account Type",
-   "options": "Account Type"
+   "options": "Bank Account Type"
   },
   {
    "fieldname": "account_subtype",
    "fieldtype": "Link",
    "label": "Account Subtype",
-   "options": "Account Subtype"
+   "options": "Bank Account Subtype"
   },
   {
    "fieldname": "column_break_7",
@@ -200,7 +200,7 @@
   }
  ],
  "links": [],
- "modified": "2020-01-30 20:42:26.458316",
+ "modified": "2020-04-06 21:00:45.379804",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Bank Account",
diff --git a/erpnext/accounts/doctype/account_subtype/__init__.py b/erpnext/accounts/doctype/bank_account_subtype/__init__.py
similarity index 100%
rename from erpnext/accounts/doctype/account_subtype/__init__.py
rename to erpnext/accounts/doctype/bank_account_subtype/__init__.py
diff --git a/erpnext/accounts/doctype/account_subtype/account_subtype.js b/erpnext/accounts/doctype/bank_account_subtype/bank_account_subtype.js
similarity index 77%
rename from erpnext/accounts/doctype/account_subtype/account_subtype.js
rename to erpnext/accounts/doctype/bank_account_subtype/bank_account_subtype.js
index 30144ad..f045665 100644
--- a/erpnext/accounts/doctype/account_subtype/account_subtype.js
+++ b/erpnext/accounts/doctype/bank_account_subtype/bank_account_subtype.js
@@ -1,7 +1,7 @@
 // Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
 // For license information, please see license.txt
 
-frappe.ui.form.on('Account Subtype', {
+frappe.ui.form.on('Bank Account Subtype', {
 	refresh: function() {
 
 	}
diff --git a/erpnext/accounts/doctype/bank_account_subtype/bank_account_subtype.json b/erpnext/accounts/doctype/bank_account_subtype/bank_account_subtype.json
new file mode 100644
index 0000000..f875db8
--- /dev/null
+++ b/erpnext/accounts/doctype/bank_account_subtype/bank_account_subtype.json
@@ -0,0 +1,134 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:account_subtype",
+ "beta": 0,
+ "creation": "2018-10-25 15:46:08.054586",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+  {
+   "allow_bulk_edit": 0,
+   "allow_in_quick_entry": 0,
+   "allow_on_submit": 0,
+   "bold": 0,
+   "collapsible": 0,
+   "columns": 0,
+   "fieldname": "account_subtype",
+   "fieldtype": "Data",
+   "hidden": 0,
+   "ignore_user_permissions": 0,
+   "ignore_xss_filter": 0,
+   "in_filter": 0,
+   "in_global_search": 0,
+   "in_list_view": 0,
+   "in_standard_filter": 0,
+   "label": "Account Subtype",
+   "length": 0,
+   "no_copy": 0,
+   "permlevel": 0,
+   "precision": "",
+   "print_hide": 0,
+   "print_hide_if_no_value": 0,
+   "read_only": 0,
+   "remember_last_selected_value": 0,
+   "report_hide": 0,
+   "reqd": 0,
+   "search_index": 0,
+   "set_only_once": 0,
+   "translatable": 0,
+   "unique": 1
+  }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2018-10-25 15:47:03.841390",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Bank Account Subtype",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "amend": 0,
+   "cancel": 0,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "if_owner": 0,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 1
+  },
+  {
+   "amend": 0,
+   "cancel": 0,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "if_owner": 0,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Accounts Manager",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 1
+  },
+  {
+   "amend": 0,
+   "cancel": 0,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "if_owner": 0,
+   "import": 0,
+   "permlevel": 0,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Accounts User",
+   "set_user_permissions": 0,
+   "share": 1,
+   "submit": 0,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 0,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/account_subtype/account_subtype.py b/erpnext/accounts/doctype/bank_account_subtype/bank_account_subtype.py
similarity index 86%
rename from erpnext/accounts/doctype/account_subtype/account_subtype.py
rename to erpnext/accounts/doctype/bank_account_subtype/bank_account_subtype.py
index 46c45cc..ab52c4a 100644
--- a/erpnext/accounts/doctype/account_subtype/account_subtype.py
+++ b/erpnext/accounts/doctype/bank_account_subtype/bank_account_subtype.py
@@ -5,5 +5,5 @@
 from __future__ import unicode_literals
 from frappe.model.document import Document
 
-class AccountSubtype(Document):
+class BankAccountSubtype(Document):
 	pass
diff --git a/erpnext/accounts/doctype/account_subtype/test_account_subtype.js b/erpnext/accounts/doctype/bank_account_subtype/test_bank_account_subtype.js
similarity index 69%
rename from erpnext/accounts/doctype/account_subtype/test_account_subtype.js
rename to erpnext/accounts/doctype/bank_account_subtype/test_bank_account_subtype.js
index 5646763..f599998 100644
--- a/erpnext/accounts/doctype/account_subtype/test_account_subtype.js
+++ b/erpnext/accounts/doctype/bank_account_subtype/test_bank_account_subtype.js
@@ -2,15 +2,15 @@
 // rename this file from _test_[name] to test_[name] to activate
 // and remove above this line
 
-QUnit.test("test: Account Subtype", function (assert) {
+QUnit.test("test: Bank Account Subtype", function (assert) {
 	let done = assert.async();
 
 	// number of asserts
 	assert.expect(1);
 
 	frappe.run_serially([
-		// insert a new Account Subtype
-		() => frappe.tests.make('Account Subtype', [
+		// insert a new Bank Account Subtype
+		() => frappe.tests.make('Bank Account Subtype', [
 			// values to be set
 			{key: 'value'}
 		]),
diff --git a/erpnext/accounts/doctype/account_subtype/test_account_subtype.py b/erpnext/accounts/doctype/bank_account_subtype/test_bank_account_subtype.py
similarity index 77%
rename from erpnext/accounts/doctype/account_subtype/test_account_subtype.py
rename to erpnext/accounts/doctype/bank_account_subtype/test_bank_account_subtype.py
index c37b5b9..ca3addc 100644
--- a/erpnext/accounts/doctype/account_subtype/test_account_subtype.py
+++ b/erpnext/accounts/doctype/bank_account_subtype/test_bank_account_subtype.py
@@ -5,5 +5,5 @@
 
 import unittest
 
-class TestAccountSubtype(unittest.TestCase):
+class TestBankAccountSubtype(unittest.TestCase):
 	pass
diff --git a/erpnext/accounts/doctype/account_type/__init__.py b/erpnext/accounts/doctype/bank_account_type/__init__.py
similarity index 100%
rename from erpnext/accounts/doctype/account_type/__init__.py
rename to erpnext/accounts/doctype/bank_account_type/__init__.py
diff --git a/erpnext/accounts/doctype/bank_account_type/bank_account_type.js b/erpnext/accounts/doctype/bank_account_type/bank_account_type.js
new file mode 100644
index 0000000..4cfabe3
--- /dev/null
+++ b/erpnext/accounts/doctype/bank_account_type/bank_account_type.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Bank Account Type', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/accounts/doctype/bank_account_type/bank_account_type.json b/erpnext/accounts/doctype/bank_account_type/bank_account_type.json
new file mode 100644
index 0000000..5a297cc
--- /dev/null
+++ b/erpnext/accounts/doctype/bank_account_type/bank_account_type.json
@@ -0,0 +1,68 @@
+{
+ "actions": [],
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:account_type",
+ "creation": "2018-10-25 15:45:45.789963",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "account_type"
+ ],
+ "fields": [
+  {
+   "fieldname": "account_type",
+   "fieldtype": "Data",
+   "label": "Account Type",
+   "unique": 1
+  }
+ ],
+ "links": [],
+ "modified": "2020-04-10 21:13:09.137898",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Bank Account Type",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Accounts Manager",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Accounts User",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC"
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/account_type/account_type.py b/erpnext/accounts/doctype/bank_account_type/bank_account_type.py
similarity index 60%
rename from erpnext/accounts/doctype/account_type/account_type.py
rename to erpnext/accounts/doctype/bank_account_type/bank_account_type.py
index 3e64293..b7dc0e0 100644
--- a/erpnext/accounts/doctype/account_type/account_type.py
+++ b/erpnext/accounts/doctype/bank_account_type/bank_account_type.py
@@ -1,9 +1,10 @@
 # -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
+# import frappe
 from frappe.model.document import Document
 
-class AccountType(Document):
+class BankAccountType(Document):
 	pass
diff --git a/erpnext/accounts/doctype/bank_account_type/test_bank_account_type.py b/erpnext/accounts/doctype/bank_account_type/test_bank_account_type.py
new file mode 100644
index 0000000..f04725a
--- /dev/null
+++ b/erpnext/accounts/doctype/bank_account_type/test_bank_account_type.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestBankAccountType(unittest.TestCase):
+	pass
diff --git a/erpnext/accounts/doctype/budget/budget.py b/erpnext/accounts/doctype/budget/budget.py
index 084514c..d93b6ff 100644
--- a/erpnext/accounts/doctype/budget/budget.py
+++ b/erpnext/accounts/doctype/budget/budget.py
@@ -9,6 +9,7 @@
 from frappe.model.naming import make_autoname
 from erpnext.accounts.utils import get_fiscal_year
 from frappe.model.document import Document
+from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
 
 class BudgetError(frappe.ValidationError): pass
 class DuplicateBudgetError(frappe.ValidationError): pass
@@ -98,30 +99,32 @@
 	if not (args.get('account') and args.get('cost_center')) and args.item_code:
 		args.cost_center, args.account = get_item_details(args)
 
-	if not (args.cost_center or args.project) and not args.account:
+	if not args.account:
 		return
 
-	for budget_against in ['project', 'cost_center']:
+	for budget_against in ['project', 'cost_center'] + get_accounting_dimensions():
 		if (args.get(budget_against) and args.account
 				and frappe.db.get_value("Account", {"name": args.account, "root_type": "Expense"})):
 
-			if args.project and budget_against == 'project':
-				condition = "and b.project=%s" % frappe.db.escape(args.project)
-				args.budget_against_field = "Project"
+			doctype = frappe.unscrub(budget_against)
 
-			elif args.cost_center and budget_against == 'cost_center':
-				cc_lft, cc_rgt = frappe.db.get_value("Cost Center", args.cost_center, ["lft", "rgt"])
-				condition = """and exists(select name from `tabCost Center`
-					where lft<=%s and rgt>=%s and name=b.cost_center)""" % (cc_lft, cc_rgt)
-				args.budget_against_field = "Cost Center"
+			if frappe.get_cached_value('DocType', doctype, 'is_tree'):
+				lft, rgt = frappe.db.get_value(doctype, args.get(budget_against), ["lft", "rgt"])
+				condition = """and exists(select name from `tab%s`
+					where lft<=%s and rgt>=%s and name=b.%s)""" % (doctype, lft, rgt, budget_against) #nosec
+				args.is_tree = True
+			else:
+				condition = "and b.%s=%s" % (budget_against, frappe.db.escape(args.get(budget_against)))
+				args.is_tree = False
 
-			args.budget_against = args.get(budget_against)
+			args.budget_against_field = budget_against
+			args.budget_against_doctype = doctype
 
 			budget_records = frappe.db.sql("""
 				select
 					b.{budget_against_field} as budget_against, ba.budget_amount, b.monthly_distribution,
 					ifnull(b.applicable_on_material_request, 0) as for_material_request,
-					ifnull(applicable_on_purchase_order,0) as for_purchase_order,
+					ifnull(applicable_on_purchase_order, 0) as for_purchase_order,
 					ifnull(applicable_on_booking_actual_expenses,0) as for_actual_expenses,
 					b.action_if_annual_budget_exceeded, b.action_if_accumulated_monthly_budget_exceeded,
 					b.action_if_annual_budget_exceeded_on_mr, b.action_if_accumulated_monthly_budget_exceeded_on_mr,
@@ -132,9 +135,7 @@
 					b.name=ba.parent and b.fiscal_year=%s
 					and ba.account=%s and b.docstatus=1
 					{condition}
-			""".format(condition=condition,
-				budget_against_field=frappe.scrub(args.get("budget_against_field"))),
-				(args.fiscal_year, args.account), as_dict=True)
+			""".format(condition=condition, budget_against_field=budget_against), (args.fiscal_year, args.account), as_dict=True) #nosec
 
 			if budget_records:
 				validate_budget_records(args, budget_records)
@@ -230,10 +231,10 @@
 
 def get_other_condition(args, budget, for_doc):
 	condition = "expense_account = '%s'" % (args.expense_account)
-	budget_against_field = frappe.scrub(args.get("budget_against_field"))
+	budget_against_field = args.get("budget_against_field")
 
 	if budget_against_field and args.get(budget_against_field):
-		condition += " and child.%s = '%s'" %(budget_against_field, args.get(budget_against_field))
+		condition += " and child.%s = '%s'" % (budget_against_field, args.get(budget_against_field))
 
 	if args.get('fiscal_year'):
 		date_field = 'schedule_date' if for_doc == 'Material Request' else 'transaction_date'
@@ -246,19 +247,30 @@
 	return condition
 
 def get_actual_expense(args):
+	if not args.budget_against_doctype:
+		args.budget_against_doctype = frappe.unscrub(args.budget_against_field)
+
+	budget_against_field = args.get('budget_against_field')
 	condition1 = " and gle.posting_date <= %(month_end_date)s" \
 		if args.get("month_end_date") else ""
-	if args.budget_against_field == "Cost Center":
-		lft_rgt = frappe.db.get_value(args.budget_against_field,
-			args.budget_against, ["lft", "rgt"], as_dict=1)
+
+	if args.is_tree:
+		lft_rgt = frappe.db.get_value(args.budget_against_doctype,
+			args.get(budget_against_field), ["lft", "rgt"], as_dict=1)
+
 		args.update(lft_rgt)
-		condition2 = """and exists(select name from `tabCost Center`
-			where lft>=%(lft)s and rgt<=%(rgt)s and name=gle.cost_center)"""
 
-	elif args.budget_against_field == "Project":
-		condition2 = "and exists(select name from `tabProject` where name=gle.project and gle.project = %(budget_against)s)"
+		condition2 = """and exists(select name from `tab{doctype}`
+			where lft>=%(lft)s and rgt<=%(rgt)s
+			and name=gle.{budget_against_field})""".format(doctype=args.budget_against_doctype, #nosec
+			budget_against_field=budget_against_field)
+	else:
+		condition2 = """and exists(select name from `tab{doctype}`
+		where name=gle.{budget_against} and
+		gle.{budget_against} = %({budget_against})s)""".format(doctype=args.budget_against_doctype,
+		budget_against = budget_against_field)
 
-	return flt(frappe.db.sql("""
+	amount  = flt(frappe.db.sql("""
 		select sum(gle.debit) - sum(gle.credit)
 		from `tabGL Entry` gle
 		where gle.account=%(account)s
@@ -267,7 +279,9 @@
 			and gle.company=%(company)s
 			and gle.docstatus=1
 			{condition2}
-	""".format(condition1=condition1, condition2=condition2), (args))[0][0])
+	""".format(condition1=condition1, condition2=condition2), (args))[0][0]) #nosec
+
+	return amount
 
 def get_accumulated_monthly_budget(monthly_distribution, posting_date, fiscal_year, annual_budget):
 	distribution = {}
diff --git a/erpnext/accounts/doctype/budget/test_budget.py b/erpnext/accounts/doctype/budget/test_budget.py
index 33aefd6..9c19791 100644
--- a/erpnext/accounts/doctype/budget/test_budget.py
+++ b/erpnext/accounts/doctype/budget/test_budget.py
@@ -13,7 +13,7 @@
 
 class TestBudget(unittest.TestCase):
 	def test_monthly_budget_crossed_ignore(self):
-		set_total_expense_zero("2013-02-28", "Cost Center")
+		set_total_expense_zero("2013-02-28", "cost_center")
 
 		budget = make_budget(budget_against="Cost Center")
 
@@ -26,7 +26,7 @@
 		budget.cancel()
 
 	def test_monthly_budget_crossed_stop1(self):
-		set_total_expense_zero("2013-02-28", "Cost Center")
+		set_total_expense_zero("2013-02-28", "cost_center")
 
 		budget = make_budget(budget_against="Cost Center")
 
@@ -41,7 +41,7 @@
 		budget.cancel()
 
 	def test_exception_approver_role(self):
-		set_total_expense_zero("2013-02-28", "Cost Center")
+		set_total_expense_zero("2013-02-28", "cost_center")
 
 		budget = make_budget(budget_against="Cost Center")
 
@@ -114,7 +114,7 @@
 		budget.cancel()
 
 	def test_monthly_budget_crossed_stop2(self):
-		set_total_expense_zero("2013-02-28", "Project")
+		set_total_expense_zero("2013-02-28", "project")
 
 		budget = make_budget(budget_against="Project")
 
@@ -129,7 +129,7 @@
 		budget.cancel()
 
 	def test_yearly_budget_crossed_stop1(self):
-		set_total_expense_zero("2013-02-28", "Cost Center")
+		set_total_expense_zero("2013-02-28", "cost_center")
 
 		budget = make_budget(budget_against="Cost Center")
 
@@ -141,7 +141,7 @@
 		budget.cancel()
 
 	def test_yearly_budget_crossed_stop2(self):
-		set_total_expense_zero("2013-02-28", "Project")
+		set_total_expense_zero("2013-02-28", "project")
 
 		budget = make_budget(budget_against="Project")
 
@@ -153,7 +153,7 @@
 		budget.cancel()
 
 	def test_monthly_budget_on_cancellation1(self):
-		set_total_expense_zero("2013-02-28", "Cost Center")
+		set_total_expense_zero("2013-02-28", "cost_center")
 
 		budget = make_budget(budget_against="Cost Center")
 
@@ -177,7 +177,7 @@
 		budget.cancel()
 
 	def test_monthly_budget_on_cancellation2(self):
-		set_total_expense_zero("2013-02-28", "Project")
+		set_total_expense_zero("2013-02-28", "project")
 
 		budget = make_budget(budget_against="Project")
 
@@ -201,8 +201,8 @@
 		budget.cancel()
 
 	def test_monthly_budget_against_group_cost_center(self):
-		set_total_expense_zero("2013-02-28", "Cost Center")
-		set_total_expense_zero("2013-02-28", "Cost Center", "_Test Cost Center 2 - _TC")
+		set_total_expense_zero("2013-02-28", "cost_center")
+		set_total_expense_zero("2013-02-28", "cost_center", "_Test Cost Center 2 - _TC")
 
 		budget = make_budget(budget_against="Cost Center", cost_center="_Test Company - _TC")
 		frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
@@ -241,25 +241,30 @@
 
 
 def set_total_expense_zero(posting_date, budget_against_field=None, budget_against_CC=None):
-	if budget_against_field == "Project":
+	if budget_against_field == "project":
 		budget_against = "_Test Project"
 	else:
 		budget_against = budget_against_CC or "_Test Cost Center - _TC"
-	existing_expense = get_actual_expense(frappe._dict({
+
+	args = frappe._dict({
 		"account": "_Test Account Cost for Goods Sold - _TC",
 		"cost_center": "_Test Cost Center - _TC",
 		"monthly_end_date": posting_date,
 		"company": "_Test Company",
 		"fiscal_year": "_Test Fiscal Year 2013",
 		"budget_against_field": budget_against_field,
-		"budget_against": budget_against
-	}))
+	})
+
+	if not args.get(budget_against_field):
+		args[budget_against_field] = budget_against
+
+	existing_expense = get_actual_expense(args)
 
 	if existing_expense:
-		if budget_against_field == "Cost Center":
+		if budget_against_field == "cost_center":
 			make_journal_entry("_Test Account Cost for Goods Sold - _TC",
 			"_Test Bank - _TC", -existing_expense, "_Test Cost Center - _TC", posting_date="2013-02-28", submit=True)
-		elif budget_against_field == "Project":
+		elif budget_against_field == "project":
 			make_journal_entry("_Test Account Cost for Goods Sold - _TC",
 			"_Test Bank - _TC", -existing_expense, "_Test Cost Center - _TC", submit=True, project="_Test Project", posting_date="2013-02-28")
 
diff --git a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
index fa4d40e..e1b331b 100644
--- a/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
+++ b/erpnext/accounts/doctype/chart_of_accounts_importer/chart_of_accounts_importer.py
@@ -152,10 +152,9 @@
 				return [parent_account]
 			elif account_name == child:
 				parent_account_list = return_parent(data, parent_account)
-				if not parent_account_list:
+				if not parent_account_list and parent_account:
 					frappe.throw(_("The parent account {0} does not exists in the uploaded template").format(
 						frappe.bold(parent_account)))
-
 				return [child] + parent_account_list
 
 	charts_map, paths = {}, []
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index b7c97a7..a378a51 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -106,6 +106,21 @@
 			};
 		});
 
+		frm.set_query('payment_term', 'references', function(frm, cdt, cdn) {
+			const child = locals[cdt][cdn];
+			if (in_list(['Purchase Invoice', 'Sales Invoice'], child.reference_doctype) && child.reference_name) {
+				let payment_term_list = frappe.get_list('Payment Schedule', {'parent': child.reference_name});
+
+				payment_term_list = payment_term_list.map(pt => pt.payment_term);
+
+				return {
+					filters: {
+						'name': ['in', payment_term_list]
+					}
+				}
+			}
+		});
+
 		frm.set_query("reference_name", "references", function(doc, cdt, cdn) {
 			const child = locals[cdt][cdn];
 			const filters = {"docstatus": 1, "company": doc.company};
@@ -287,7 +302,7 @@
 			frm.set_value("contact_email", "");
 			frm.set_value("contact_person", "");
 		}
-		if(frm.doc.payment_type && frm.doc.party_type && frm.doc.party) {
+		if(frm.doc.payment_type && frm.doc.party_type && frm.doc.party && frm.doc.company) {
 			if(!frm.doc.posting_date) {
 				frappe.msgprint(__("Please select Posting Date before selecting Party"))
 				frm.set_value("party", "");
@@ -1033,4 +1048,4 @@
 			});
 		}
 	},
-})
+})
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py
index a453e95..b53e68f 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py
@@ -71,9 +71,9 @@
 		self.update_outstanding_amounts()
 		self.update_advance_paid()
 		self.update_expense_claim()
+		self.update_payment_schedule()
 		self.set_status()
 
-
 	def on_cancel(self):
 		self.setup_party_account_field()
 		self.make_gl_entries(cancel=1)
@@ -81,6 +81,7 @@
 		self.update_advance_paid()
 		self.update_expense_claim()
 		self.delink_advance_entry_references()
+		self.update_payment_schedule(cancel=1)
 		self.set_payment_req_status()
 		self.set_status()
 	
@@ -94,10 +95,10 @@
 	def validate_duplicate_entry(self):
 		reference_names = []
 		for d in self.get("references"):
-			if (d.reference_doctype, d.reference_name) in reference_names:
+			if (d.reference_doctype, d.reference_name, d.payment_term) in reference_names:
 				frappe.throw(_("Row #{0}: Duplicate entry in References {1} {2}")
 					.format(d.idx, d.reference_doctype, d.reference_name))
-			reference_names.append((d.reference_doctype, d.reference_name))
+			reference_names.append((d.reference_doctype, d.reference_name, d.payment_term))
 
 	def set_bank_account_data(self):
 		if self.bank_account:
@@ -285,6 +286,36 @@
 						frappe.throw(_("Against Journal Entry {0} does not have any unmatched {1} entry")
 							.format(d.reference_name, dr_or_cr))
 
+	def update_payment_schedule(self, cancel=0):
+		invoice_payment_amount_map = {}
+		invoice_paid_amount_map = {}
+
+		for reference in self.get('references'):
+			if reference.payment_term and reference.reference_name:
+				key = (reference.payment_term, reference.reference_name)
+				invoice_payment_amount_map.setdefault(key, 0.0)
+				invoice_payment_amount_map[key] += reference.allocated_amount
+
+				if not invoice_paid_amount_map.get(reference.reference_name):
+					payment_schedule = frappe.get_all('Payment Schedule', filters={'parent': reference.reference_name},
+						fields=['paid_amount', 'payment_amount', 'payment_term'])
+					for term in payment_schedule:
+						invoice_key = (term.payment_term, reference.reference_name)
+						invoice_paid_amount_map.setdefault(invoice_key, {})
+						invoice_paid_amount_map[invoice_key]['outstanding'] = term.payment_amount - term.paid_amount
+
+		for key, amount in iteritems(invoice_payment_amount_map):
+			if cancel:
+				frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` - %s
+					WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
+			else:
+				outstanding = invoice_paid_amount_map.get(key)['outstanding']
+				if amount > outstanding:
+					frappe.throw(_('Cannot allocate more than {0} against payment term {1}').format(outstanding, key[0]))
+
+				frappe.db.sql(""" UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` + %s
+						WHERE parent = %s and payment_term = %s""", (amount, key[1], key[0]))
+
 	def set_status(self):
 		if self.docstatus == 2:
 			self.status = 'Cancelled'
@@ -1012,15 +1043,22 @@
 	if doc.doctype == "Purchase Invoice" and doc.invoice_is_blocked():
 		frappe.msgprint(_('{0} is on hold till {1}').format(doc.name, doc.release_date))
 	else:
-		pe.append("references", {
-			'reference_doctype': dt,
-			'reference_name': dn,
-			"bill_no": doc.get("bill_no"),
-			"due_date": doc.get("due_date"),
-			'total_amount': grand_total,
-			'outstanding_amount': outstanding_amount,
-			'allocated_amount': outstanding_amount
-		})
+		if (doc.doctype in ('Sales Invoice', 'Purchase Invoice')
+			and frappe.get_value('Payment Terms Template',
+			{'name': doc.payment_terms_template}, 'allocate_payment_based_on_payment_terms')):
+
+			for reference in get_reference_as_per_payment_terms(doc.payment_schedule, dt, dn, doc, grand_total, outstanding_amount):
+				pe.append('references', reference)
+		else:
+			pe.append("references", {
+				'reference_doctype': dt,
+				'reference_name': dn,
+				"bill_no": doc.get("bill_no"),
+				"due_date": doc.get("due_date"),
+				'total_amount': grand_total,
+				'outstanding_amount': outstanding_amount,
+				'allocated_amount': outstanding_amount
+			})
 
 	pe.setup_party_account_field()
 	pe.set_missing_values()
@@ -1029,6 +1067,22 @@
 		pe.set_amounts()
 	return pe
 
+def get_reference_as_per_payment_terms(payment_schedule, dt, dn, doc, grand_total, outstanding_amount):
+	references = []
+	for payment_term in payment_schedule:
+		references.append({
+			'reference_doctype': dt,
+			'reference_name': dn,
+			'bill_no': doc.get('bill_no'),
+			'due_date': doc.get('due_date'),
+			'total_amount': grand_total,
+			'outstanding_amount': outstanding_amount,
+			'payment_term': payment_term.payment_term,
+			'allocated_amount': flt(payment_term.payment_amount - payment_term.paid_amount,
+				payment_term.precision('payment_amount'))
+		})
+
+	return references
 
 def get_paid_amount(dt, dn, party_type, party, account, due_date):
 	if party_type=="Customer":
diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
index a25e0e3..4c7d933 100644
--- a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
@@ -171,6 +171,32 @@
 		self.assertEqual(flt(outstanding_amount), 100)
 		self.assertEqual(status, 'Unpaid')
 
+	def test_payment_entry_against_payment_terms(self):
+		si = create_sales_invoice(do_not_save=1, qty=1, rate=200)
+		create_payment_terms_template()
+		si.payment_terms_template = 'Test Receivable Template'
+
+		si.append('taxes', {
+			"charge_type": "On Net Total",
+			"account_head": "_Test Account Service Tax - _TC",
+			"cost_center": "_Test Cost Center - _TC",
+			"description": "Service Tax",
+			"rate": 18
+		})
+		si.save()
+
+		si.submit()
+
+		pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC")
+		pe.submit()
+		si.load_from_db()
+
+		self.assertEqual(pe.references[0].payment_term, 'Basic Amount Receivable')
+		self.assertEqual(pe.references[1].payment_term, 'Tax Receivable')
+		self.assertEqual(si.payment_schedule[0].paid_amount, 200.0)
+		self.assertEqual(si.payment_schedule[1].paid_amount, 36.0)
+
+
 	def test_payment_against_purchase_invoice_to_check_status(self):
 		pi = make_purchase_invoice(supplier="_Test Supplier USD", debit_to="_Test Payable USD - _TC",
 			currency="USD", conversion_rate=50)
@@ -609,4 +635,38 @@
 		self.assertEqual(expected_party_account_balance, party_account_balance)
 
 		accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
-		accounts_settings.save()
\ No newline at end of file
+		accounts_settings.save()
+
+def create_payment_terms_template():
+
+	create_payment_term('Basic Amount Receivable')
+	create_payment_term('Tax Receivable')
+
+	if not frappe.db.exists('Payment Terms Template', 'Test Receivable Template'):
+		payment_term_template = frappe.get_doc({
+			'doctype': 'Payment Terms Template',
+			'template_name': 'Test Receivable Template',
+			'allocate_payment_based_on_payment_terms': 1,
+			'terms': [{
+				'doctype': 'Payment Terms Template Detail',
+				'payment_term': 'Basic Amount Receivable',
+				'invoice_portion': 84.746,
+				'credit_days_based_on': 'Day(s) after invoice date',
+				'credit_days': 1
+			},
+			{
+				'doctype': 'Payment Terms Template Detail',
+				'payment_term': 'Tax Receivable',
+				'invoice_portion': 15.254,
+				'credit_days_based_on': 'Day(s) after invoice date',
+				'credit_days': 2
+			}]
+		}).insert()
+
+
+def create_payment_term(name):
+	if not frappe.db.exists('Payment Term', name):
+		frappe.get_doc({
+			'doctype': 'Payment Term',
+			'payment_term_name': name
+		}).insert()
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json
index b6a6643..8f5e9fb 100644
--- a/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json
+++ b/erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json
@@ -1,343 +1,107 @@
 {
- "allow_copy": 0,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 0,
+ "actions": [],
  "creation": "2016-06-01 16:55:32.196722",
- "custom": 0,
- "docstatus": 0,
  "doctype": "DocType",
- "document_type": "",
  "editable_grid": 1,
  "engine": "InnoDB",
+ "field_order": [
+  "reference_doctype",
+  "reference_name",
+  "due_date",
+  "bill_no",
+  "payment_term",
+  "column_break_4",
+  "total_amount",
+  "outstanding_amount",
+  "allocated_amount",
+  "exchange_rate"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
    "columns": 2,
-   "fetch_if_empty": 0,
    "fieldname": "reference_doctype",
    "fieldtype": "Link",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
    "in_list_view": 1,
-   "in_standard_filter": 0,
    "label": "Type",
-   "length": 0,
-   "no_copy": 0,
    "options": "DocType",
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 1,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
+   "reqd": 1
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
    "columns": 2,
-   "fetch_if_empty": 0,
    "fieldname": "reference_name",
    "fieldtype": "Dynamic Link",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
    "in_global_search": 1,
    "in_list_view": 1,
-   "in_standard_filter": 0,
    "label": "Name",
-   "length": 0,
-   "no_copy": 0,
    "options": "reference_doctype",
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 1,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
+   "reqd": 1
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fetch_if_empty": 0,
    "fieldname": "due_date",
    "fieldtype": "Date",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 0,
-   "in_standard_filter": 0,
    "label": "Due Date",
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 1,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
+   "read_only": 1
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "depends_on": "",
-   "fetch_if_empty": 0,
    "fieldname": "bill_no",
    "fieldtype": "Data",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 0,
-   "in_standard_filter": 0,
    "label": "Supplier Invoice No",
-   "length": 0,
    "no_copy": 1,
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 1,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
+   "read_only": 1
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
-   "fetch_if_empty": 0,
    "fieldname": "column_break_4",
-   "fieldtype": "Column Break",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 0,
-   "in_standard_filter": 0,
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
+   "fieldtype": "Column Break"
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
    "columns": 2,
-   "fetch_if_empty": 0,
    "fieldname": "total_amount",
    "fieldtype": "Float",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
    "in_list_view": 1,
-   "in_standard_filter": 0,
    "label": "Total Amount",
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "precision": "",
    "print_hide": 1,
-   "print_hide_if_no_value": 0,
-   "read_only": 1,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
+   "read_only": 1
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
    "columns": 2,
-   "fetch_if_empty": 0,
    "fieldname": "outstanding_amount",
    "fieldtype": "Float",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
    "in_list_view": 1,
-   "in_standard_filter": 0,
    "label": "Outstanding",
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 1,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
+   "read_only": 1
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
    "columns": 2,
-   "fetch_if_empty": 0,
    "fieldname": "allocated_amount",
    "fieldtype": "Float",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
    "in_list_view": 1,
-   "in_standard_filter": 0,
-   "label": "Allocated",
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
+   "label": "Allocated"
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "depends_on": "eval:(doc.reference_doctype=='Purchase Invoice')",
-   "fetch_if_empty": 0,
    "fieldname": "exchange_rate",
    "fieldtype": "Float",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 0,
-   "in_standard_filter": 0,
    "label": "Exchange Rate",
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "precision": "",
    "print_hide": 1,
-   "print_hide_if_no_value": 0,
-   "read_only": 1,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
+   "read_only": 1
+  },
+  {
+   "fieldname": "payment_term",
+   "fieldtype": "Link",
+   "label": "Payment Term",
+   "options": "Payment Term"
   }
  ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
  "istable": 1,
- "max_attachments": 0,
- "modified": "2019-05-01 13:24:56.586677",
+ "links": [],
+ "modified": "2020-03-13 12:07:19.362539",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Payment Entry Reference",
- "name_case": "",
  "owner": "Administrator",
  "permissions": [],
  "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
  "sort_field": "modified",
  "sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0,
- "track_views": 0
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_schedule/payment_schedule.json b/erpnext/accounts/doctype/payment_schedule/payment_schedule.json
index 1b38904..d363cf1 100644
--- a/erpnext/accounts/doctype/payment_schedule/payment_schedule.json
+++ b/erpnext/accounts/doctype/payment_schedule/payment_schedule.json
@@ -1,243 +1,82 @@
 {
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "autoname": "", 
- "beta": 0, 
- "creation": "2017-08-10 15:38:00.080575", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "creation": "2017-08-10 15:38:00.080575",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "payment_term",
+  "description",
+  "due_date",
+  "invoice_portion",
+  "payment_amount",
+  "mode_of_payment",
+  "paid_amount"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 2, 
-   "fieldname": "payment_term", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Payment Term", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Payment Term", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 1, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "columns": 2,
+   "fieldname": "payment_term",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Payment Term",
+   "options": "Payment Term",
+   "print_hide": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 2, 
-   "fetch_from": "", 
-   "fieldname": "description", 
-   "fieldtype": "Small Text", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Description", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "columns": 2,
+   "fieldname": "description",
+   "fieldtype": "Small Text",
+   "in_list_view": 1,
+   "label": "Description"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 2, 
-   "fieldname": "due_date", 
-   "fieldtype": "Date", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Due Date", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "columns": 2,
+   "fieldname": "due_date",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "label": "Due Date",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 2, 
-   "fetch_from": "", 
-   "fieldname": "invoice_portion", 
-   "fieldtype": "Percent", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Invoice Portion", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 1, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "columns": 2,
+   "fieldname": "invoice_portion",
+   "fieldtype": "Percent",
+   "in_list_view": 1,
+   "label": "Invoice Portion",
+   "print_hide": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 2, 
-   "fieldname": "payment_amount", 
-   "fieldtype": "Currency", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Payment Amount", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "currency", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "columns": 2,
+   "fieldname": "payment_amount",
+   "fieldtype": "Currency",
+   "in_list_view": 1,
+   "label": "Payment Amount",
+   "options": "currency",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "mode_of_payment", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Mode of Payment", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Mode of Payment", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
+   "fieldname": "mode_of_payment",
+   "fieldtype": "Link",
+   "label": "Mode of Payment",
+   "options": "Mode of Payment"
+  },
+  {
+   "fieldname": "paid_amount",
+   "fieldtype": "Currency",
+   "label": "Paid Amount"
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 1, 
- "max_attachments": 0, 
- "modified": "2018-09-06 17:35:44.580209", 
- "modified_by": "Administrator", 
- "module": "Accounts", 
- "name": "Payment Schedule", 
- "name_case": "", 
- "owner": "Administrator", 
- "permissions": [], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 1, 
- "track_seen": 0, 
- "track_views": 0
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-03-13 17:58:24.729526",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Payment Schedule",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.json b/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.json
index 7a3483d..c4a2a88 100644
--- a/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.json
+++ b/erpnext/accounts/doctype/payment_terms_template/payment_terms_template.json
@@ -1,164 +1,84 @@
 {
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 1, 
- "allow_rename": 1, 
- "autoname": "field:template_name", 
- "beta": 0, 
- "creation": "2017-08-10 15:34:28.058054", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "allow_import": 1,
+ "allow_rename": 1,
+ "autoname": "field:template_name",
+ "creation": "2017-08-10 15:34:28.058054",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "template_name",
+  "allocate_payment_based_on_payment_terms",
+  "terms"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "template_name", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Template Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "template_name",
+   "fieldtype": "Data",
+   "label": "Template Name",
+   "unique": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "terms", 
-   "fieldtype": "Table", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Payment Terms", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Payment Terms Template Detail", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
+   "fieldname": "terms",
+   "fieldtype": "Table",
+   "label": "Payment Terms",
+   "options": "Payment Terms Template Detail",
+   "reqd": 1
+  },
+  {
+   "default": "0",
+   "description": "If this checkbox is checked, paid amount will be splitted and allocated as per the amounts in payment schedule against each payment term",
+   "fieldname": "allocate_payment_based_on_payment_terms",
+   "fieldtype": "Check",
+   "label": "Allocate Payment Based On Payment Terms"
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2018-01-24 11:13:31.158613", 
- "modified_by": "Administrator", 
- "module": "Accounts", 
- "name": "Payment Terms Template", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "links": [],
+ "modified": "2020-04-01 15:35:18.112619",
+ "modified_by": "Administrator",
+ "module": "Accounts",
+ "name": "Payment Terms Template",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "System Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
    "write": 1
-  }, 
+  },
   {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Accounts User", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Accounts User",
+   "share": 1,
    "write": 1
-  }, 
+  },
   {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Accounts Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Accounts Manager",
+   "share": 1,
    "write": 1
   }
- ], 
- "quick_entry": 0, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 1, 
- "track_seen": 0
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index e13fcb9..19f571f 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -237,6 +237,7 @@
 			if pricing_rule.mixed_conditions or pricing_rule.apply_rule_on_other:
 				item_details.update({
 					'apply_rule_on_other_items': json.dumps(pricing_rule.apply_rule_on_other_items),
+					'price_or_product_discount': pricing_rule.price_or_product_discount,
 					'apply_rule_on': (frappe.scrub(pricing_rule.apply_rule_on_other)
 						if pricing_rule.apply_rule_on_other else frappe.scrub(pricing_rule.get('apply_on')))
 				})
diff --git a/erpnext/accounts/doctype/pricing_rule/utils.py b/erpnext/accounts/doctype/pricing_rule/utils.py
index 100bb1d..b358f56 100644
--- a/erpnext/accounts/doctype/pricing_rule/utils.py
+++ b/erpnext/accounts/doctype/pricing_rule/utils.py
@@ -330,9 +330,9 @@
 			if pr_doc.mixed_conditions:
 				amt = args.get('qty') * args.get("price_list_rate")
 				if args.get("item_code") != row.get("item_code"):
-					amt = row.get('qty') * (row.get("price_list_rate") or args.get("rate"))
+					amt = flt(row.get('qty')) * flt(row.get("price_list_rate") or args.get("rate"))
 
-				sum_qty += row.get("stock_qty") or args.get("stock_qty") or args.get("qty")
+				sum_qty += flt(row.get("stock_qty")) or flt(args.get("stock_qty")) or flt(args.get("qty"))
 				sum_amt += amt
 
 		if pr_doc.is_cumulative:
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index 3cd988c..0e09454 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -13,23 +13,18 @@
   "supplier_name",
   "tax_id",
   "due_date",
-  "is_paid",
-  "is_return",
-  "apply_tds",
   "column_break1",
   "company",
   "posting_date",
   "posting_time",
   "set_posting_time",
+  "is_paid",
+  "is_return",
+  "apply_tds",
   "amended_from",
   "accounting_dimensions_section",
   "cost_center",
   "dimension_col_break",
-  "sb_14",
-  "on_hold",
-  "release_date",
-  "cb_17",
-  "hold_comment",
   "supplier_invoice_details",
   "bill_no",
   "column_break_15",
@@ -73,9 +68,9 @@
   "base_total",
   "base_net_total",
   "column_break_28",
+  "total_net_weight",
   "total",
   "net_total",
-  "total_net_weight",
   "taxes_section",
   "tax_category",
   "column_break_49",
@@ -137,10 +132,15 @@
   "terms",
   "printing_settings",
   "letter_head",
-  "group_same_items",
-  "column_break_112",
   "select_print_heading",
+  "column_break_112",
+  "group_same_items",
   "language",
+  "sb_14",
+  "on_hold",
+  "release_date",
+  "cb_17",
+  "hold_comment",
   "more_info",
   "credit_to",
   "party_account_currency",
@@ -190,6 +190,7 @@
    "oldfieldtype": "Link",
    "options": "Supplier",
    "print_hide": 1,
+   "reqd": 1,
    "search_index": 1
   },
   {
@@ -1232,6 +1233,7 @@
    "print_hide": 1
   },
   {
+   "collapsible": 1,
    "fieldname": "subscription_section",
    "fieldtype": "Section Break",
    "label": "Subscription Section",
@@ -1298,7 +1300,7 @@
  "idx": 204,
  "is_submittable": 1,
  "links": [],
- "modified": "2019-12-30 19:13:49.610538",
+ "modified": "2020-04-17 13:05:25.199832",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice",
diff --git a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
index db3f72a..52a5be0 100644
--- a/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
+++ b/erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
@@ -12,15 +12,11 @@
   "item_name",
   "description_section",
   "description",
-  "item_group",
   "brand",
-  "image_section",
+  "col_break7",
+  "item_group",
   "image",
   "image_view",
-  "manufacture_details",
-  "manufacturer",
-  "column_break_13",
-  "manufacturer_part_no",
   "quantity_and_rate",
   "received_qty",
   "qty",
@@ -55,20 +51,19 @@
   "item_tax_amount",
   "landed_cost_voucher_amount",
   "rm_supp_cost",
-  "item_weight_details",
-  "weight_per_unit",
-  "total_weight",
-  "column_break_38",
-  "weight_uom",
   "warehouse_section",
   "warehouse",
-  "rejected_warehouse",
   "from_warehouse",
   "quality_inspection",
-  "batch_no",
-  "col_br_wh",
   "serial_no",
+  "col_br_wh",
+  "rejected_warehouse",
+  "batch_no",
   "rejected_serial_no",
+  "manufacture_details",
+  "manufacturer",
+  "column_break_13",
+  "manufacturer_part_no",
   "accounting",
   "expense_account",
   "col_break5",
@@ -92,6 +87,11 @@
   "po_detail",
   "purchase_receipt",
   "pr_detail",
+  "item_weight_details",
+  "weight_per_unit",
+  "total_weight",
+  "column_break_38",
+  "weight_uom",
   "accounting_dimensions_section",
   "project",
   "dimension_col_break",
@@ -550,23 +550,21 @@
   },
   {
    "fieldname": "brand",
-   "fieldtype": "Data",
-   "hidden": 1,
-   "label": "Brand",
-   "oldfieldname": "brand",
-   "oldfieldtype": "Data",
-   "print_hide": 1
-  },
-  {
-   "fieldname": "item_group",
    "fieldtype": "Link",
    "hidden": 1,
-   "label": "Item Group",
-   "oldfieldname": "item_group",
-   "oldfieldtype": "Link",
-   "options": "Item Group",
+   "label": "Brand",
    "print_hide": 1,
-   "read_only": 1
+   "options": "Brand"
+  },
+  {
+   "fetch_from": "item_code.item_group",
+   "fetch_if_empty": 1,
+   "fieldname": "item_group",
+   "fieldtype": "Link",
+   "label": "Item Group",
+   "print_hide": 1,
+   "read_only": 1,
+   "options": "Item Group"
   },
   {
    "description": "Tax detail table fetched from item master as a string and stored in this field.\nUsed for Taxes and Charges",
@@ -722,12 +720,6 @@
   },
   {
    "collapsible": 1,
-   "fieldname": "image_section",
-   "fieldtype": "Section Break",
-   "label": "Image"
-  },
-  {
-   "collapsible": 1,
    "fieldname": "accounting_dimensions_section",
    "fieldtype": "Section Break",
    "label": "Accounting Dimensions"
@@ -737,6 +729,7 @@
    "fieldtype": "Column Break"
   },
   {
+   "collapsible": 1,
    "fieldname": "manufacture_details",
    "fieldtype": "Section Break",
    "label": "Manufacture"
@@ -771,12 +764,17 @@
    "ignore_user_permissions": 1,
    "label": "Supplier Warehouse",
    "options": "Warehouse"
+  },
+  {
+   "collapsible": 1,
+   "fieldname": "col_break7",
+   "fieldtype": "Column Break"
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-04-07 18:34:35.104178",
+ "modified": "2020-04-22 10:37:35.103176",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Purchase Invoice Item",
@@ -784,4 +782,4 @@
  "permissions": [],
  "sort_field": "modified",
  "sort_order": "DESC"
-}
\ No newline at end of file
+}
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index 6f78db2..a6113cd 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -32,6 +32,7 @@
 			me.frm.script_manager.trigger("is_pos");
 			me.frm.refresh_fields();
 		}
+		erpnext.queries.setup_warehouse_query(this.frm);
 	},
 
 	refresh: function(doc, dt, dn) {
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
index e239f91..918fa14 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "allow_import": 1,
  "autoname": "naming_series:",
  "creation": "2013-05-24 19:29:05",
@@ -74,9 +75,9 @@
   "base_total",
   "base_net_total",
   "column_break_32",
+  "total_net_weight",
   "total",
   "net_total",
-  "total_net_weight",
   "taxes_section",
   "taxes_and_charges",
   "column_break_38",
@@ -1577,7 +1578,8 @@
  "icon": "fa fa-file-text",
  "idx": 181,
  "is_submittable": 1,
- "modified": "2020-02-10 04:57:11.221180",
+ "links": [],
+ "modified": "2020-04-17 12:38:41.435728",
  "modified_by": "Administrator",
  "module": "Accounts",
  "name": "Sales Invoice",
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index 240b0d8..e9c286f 100755
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -344,26 +344,28 @@
 	def allocate_outstanding_based_on_payment_terms(self, row):
 		self.get_payment_terms(row)
 		for term in row.payment_terms:
-			term.outstanding = term.invoiced
 
 			# update "paid" and "oustanding" for this term
-			self.allocate_closing_to_term(row, term, 'paid')
+			if not term.paid:
+				self.allocate_closing_to_term(row, term, 'paid')
 
 			# update "credit_note" and "oustanding" for this term
 			if term.outstanding:
 				self.allocate_closing_to_term(row, term, 'credit_note')
 
+		row.payment_terms = sorted(row.payment_terms, key=lambda x: x['due_date'])
+
 	def get_payment_terms(self, row):
 		# build payment_terms for row
 		payment_terms_details = frappe.db.sql("""
 			select
 				si.name, si.party_account_currency, si.currency, si.conversion_rate,
-				ps.due_date, ps.payment_amount, ps.description
+				ps.due_date, ps.payment_amount, ps.description, ps.paid_amount
 			from `tab{0}` si, `tabPayment Schedule` ps
 			where
 				si.name = ps.parent and
 				si.name = %s
-			order by ps.due_date
+			order by ps.paid_amount desc, due_date
 		""".format(row.voucher_type), row.voucher_no, as_dict = 1)
 
 
@@ -389,11 +391,14 @@
 			"invoiced": invoiced,
 			"invoice_grand_total": row.invoiced,
 			"payment_term": d.description,
-			"paid": 0.0,
+			"paid": d.paid_amount,
 			"credit_note": 0.0,
-			"outstanding": 0.0
+			"outstanding": invoiced - d.paid_amount
 		}))
 
+		if d.paid_amount:
+			row['paid'] -= d.paid_amount
+
 	def allocate_closing_to_term(self, row, term, key):
 		if row[key]:
 			if row[key] > term.outstanding:
diff --git a/erpnext/accounts/report/general_ledger/general_ledger.html b/erpnext/accounts/report/general_ledger/general_ledger.html
index 9a2205a..378fa37 100644
--- a/erpnext/accounts/report/general_ledger/general_ledger.html
+++ b/erpnext/accounts/report/general_ledger/general_ledger.html
@@ -2,7 +2,7 @@
 <h4 class="text-center">
 	{% if (filters.party_name) { %}
 		{%= filters.party_name %}
-	{% } else if (filters.party) { %}
+	{% } else if (filters.party && filters.party.length) { %}
 		{%= filters.party %}
 	{% } else if (filters.account) { %}
 		{%= filters.account %}
diff --git a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py
index 6550981..260f35f 100644
--- a/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py
+++ b/erpnext/accounts/report/gross_and_net_profit_report/gross_and_net_profit_report.py
@@ -8,7 +8,6 @@
 from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
 import copy
 
-
 def execute(filters=None):
 	period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
 		filters.periodicity, filters.accumulated_values, filters.company)
@@ -27,17 +26,19 @@
 
 
 	gross_income = get_revenue(income, period_list)
-
 	gross_expense = get_revenue(expense, period_list)
 
 	if(len(gross_income)==0 and len(gross_expense)== 0):
-		data.append({"account_name": "'" + _("Nothing is included in gross") + "'",
-		"account": "'" + _("Nothing is included in gross") + "'"})
-
+		data.append({
+			"account_name": "'" + _("Nothing is included in gross") + "'",
+			"account": "'" + _("Nothing is included in gross") + "'"
+		})
 		return columns, data
 
-	data.append({"account_name": "'" + _("Included in Gross Profit") + "'",
-		"account": "'" + _("Included in Gross Profit") + "'"})
+	data.append({
+		"account_name": "'" + _("Included in Gross Profit") + "'",
+		"account": "'" + _("Included in Gross Profit") + "'"
+	})
 
 	data.append({})
 	data.extend(gross_income or [])
@@ -111,7 +112,6 @@
 
 
 def get_profit(gross_income, gross_expense, period_list, company, profit_type, currency=None, consolidated=False):
-
 	profit_loss = {
 		"account_name": "'" + _(profit_type) + "'",
 		"account": "'" + _(profit_type) + "'",
@@ -123,7 +123,9 @@
 
 	for period in period_list:
 		key = period if consolidated else period.key
-		profit_loss[key] = flt(gross_income[0].get(key, 0)) - flt(gross_expense[0].get(key, 0))
+		gross_income_for_period = flt(gross_income[0].get(key, 0)) if gross_income else 0
+		gross_expense_for_period = flt(gross_expense[0].get(key, 0)) if gross_expense else 0
+		profit_loss[key] = gross_income_for_period - gross_expense_for_period
 
 		if profit_loss[key]:
 			has_value=True
@@ -143,12 +145,18 @@
 
 	for period in period_list:
 		key = period if consolidated else period.key
-		total_income = flt(gross_income[0].get(key, 0)) + flt(non_gross_income[0].get(key, 0))
-		total_expense = flt(gross_expense[0].get(key, 0)) + flt(non_gross_expense[0].get(key, 0))
+		gross_income_for_period = flt(gross_income[0].get(key, 0)) if gross_income else 0
+		non_gross_income_for_period = flt(non_gross_income[0].get(key, 0)) if non_gross_income else 0
+
+		gross_expense_for_period = flt(gross_expense[0].get(key, 0)) if gross_expense else 0
+		non_gross_expense_for_period = flt(non_gross_expense[0].get(key, 0)) if non_gross_expense else 0
+
+		total_income = gross_income_for_period + non_gross_income_for_period
+		total_expense = gross_expense_for_period + non_gross_expense_for_period
 		profit_loss[key] = flt(total_income) - flt(total_expense)
 
 		if profit_loss[key]:
 			has_value=True
 
 	if has_value:
-		return profit_loss
+		return profit_loss
\ No newline at end of file
diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js
index 3c135d4..001fc26 100644
--- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js
+++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.js
@@ -24,26 +24,6 @@
 				return indicator;
 			}
 		);
-
-		frm.set_query('select_serial_no', function(doc){
-			return {
-				asset: frm.doc.asset_name
-			}
-		})
-	},
-
-	select_serial_no: (frm) => {
-		let serial_nos = frm.doc.serial_no || frm.doc.select_serial_no;
-		if (serial_nos) {
-			serial_nos = serial_nos.split('\n');
-			serial_nos.push(frm.doc.select_serial_no);
-
-			const unique_sn = serial_nos.filter(function(elem, index, self) {
-			    return index === self.indexOf(elem);
-			});
-
-			frm.set_value("serial_no", unique_sn.join('\n'));
-		}
 	},
 
 	refresh: (frm) => {
@@ -93,25 +73,6 @@
 	},
 	end_date: (frm, cdt, cdn)  => {
 		get_next_due_date(frm, cdt, cdn);
-	},
-	assign_to: (frm, cdt, cdn)  => {
-		var d = locals[cdt][cdn];
-		if (frm.doc.__islocal) {
-			frappe.model.set_value(cdt, cdn, "assign_to", "");
-			frappe.model.set_value(cdt, cdn, "assign_to_name", "");
-			frappe.throw(__("Please save before assigning task."));
-		}
-		if (d.assign_to) {
-			return frappe.call({
-				method: 'erpnext.assets.doctype.asset_maintenance.asset_maintenance.assign_tasks',
-				args: {
-					asset_maintenance_name: frm.doc.name,
-					assign_to_member: d.assign_to,
-					maintenance_task: d.maintenance_task,
-					next_due_date: d.next_due_date
-				}
-			});
-		}
 	}
 });
 
diff --git a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
index ecb55dd..3f04611 100644
--- a/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
+++ b/erpnext/assets/doctype/asset_maintenance/asset_maintenance.py
@@ -16,12 +16,11 @@
 				throw(_("Start date should be less than end date for task {0}").format(task.maintenance_task))
 			if getdate(task.next_due_date) < getdate(nowdate()):
 				task.maintenance_status = "Overdue"
+			if not task.assign_to and self.docstatus == 0:
+				throw(_("Row #{}: Please asign task to a member.").format(task.idx))
 
 	def on_update(self):
 		for task in self.get('asset_maintenance_tasks'):
-			if not task.assign_to:
-				task.db_set("assign_to", self.maintenance_manager)
-				task.db_set("assign_to_name", self.maintenance_manager_name)
 			assign_tasks(self.name, task.assign_to, task.maintenance_task, task.next_due_date)
 		self.sync_maintenance_tasks()
 
@@ -108,7 +107,7 @@
 
 @frappe.whitelist()
 def get_team_members(doctype, txt, searchfield, start, page_len, filters):
-	return frappe.db.get_values('Maintenance Team Member', {'parent':filters.get("maintenance_team")})
+	return frappe.db.get_values('Maintenance Team Member', { 'parent': filters.get("maintenance_team") })
 
 @frappe.whitelist()
 def get_maintenance_log(asset_name):
diff --git a/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.py b/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.py
index 6c2fd67..392fbdd 100644
--- a/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.py
+++ b/erpnext/assets/doctype/asset_maintenance/test_asset_maintenance.py
@@ -125,13 +125,15 @@
 			"start_date": nowdate(),
 			"periodicity": "Monthly",
 			"maintenance_type": "Preventive Maintenance",
-			"maintenance_status": "Planned"
+			"maintenance_status": "Planned",
+			"assign_to": "marcus@abc.com"
 			},
 			{"maintenance_task": "Check Gears",
 			"start_date": nowdate(),
 			"periodicity": "Yearly",
 			"maintenance_type": "Calibration",
-			"maintenance_status": "Planned"
+			"maintenance_status": "Planned",
+			"assign_to": "thalia@abc.com"
 			}
 		]
 
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index 4d83690..578858c 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -1,4 +1,5 @@
 {
+ "actions": [],
  "allow_import": 1,
  "autoname": "naming_series:",
  "creation": "2013-05-21 16:16:39",
@@ -63,9 +64,9 @@
   "base_total",
   "base_net_total",
   "column_break_26",
+  "total_net_weight",
   "total",
   "net_total",
-  "total_net_weight",
   "taxes_section",
   "tax_category",
   "column_break_50",
@@ -170,8 +171,8 @@
    "search_index": 1
   },
   {
-   "description": "Fetch items based on Default Supplier.",
    "depends_on": "eval:doc.supplier && doc.docstatus===0 && (!(doc.items && doc.items.length) || (doc.items.length==1 && !doc.items[0].item_code))",
+   "description": "Fetch items based on Default Supplier.",
    "fieldname": "get_items_from_open_material_requests",
    "fieldtype": "Button",
    "label": "Get Items from Open Material Requests"
@@ -1054,7 +1055,8 @@
  "icon": "fa fa-file-text",
  "idx": 105,
  "is_submittable": 1,
- "modified": "2020-01-14 18:54:39.694448",
+ "links": [],
+ "modified": "2020-04-17 13:04:28.185197",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Order",
diff --git a/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json b/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json
index 6f2fbe5..ea58630 100644
--- a/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json
+++ b/erpnext/buying/doctype/purchase_receipt_item_supplied/purchase_receipt_item_supplied.json
@@ -1,24 +1,31 @@
 {
+ "actions": [],
  "creation": "2013-02-22 01:27:42",
  "doctype": "DocType",
  "editable_grid": 1,
  "engine": "InnoDB",
  "field_order": [
   "main_item_code",
-  "rm_item_code",
   "description",
-  "batch_no",
-  "serial_no",
+  "bom_detail_no",
   "col_break1",
-  "required_qty",
-  "consumed_qty",
+  "rm_item_code",
   "stock_uom",
-  "rate",
-  "amount",
   "conversion_factor",
-  "current_stock",
   "reference_name",
-  "bom_detail_no"
+  "secbreak_1",
+  "rate",
+  "col_break2",
+  "amount",
+  "secbreak_2",
+  "required_qty",
+  "col_break3",
+  "consumed_qty",
+  "current_stock",
+  "secbreak_3",
+  "batch_no",
+  "col_break4",
+  "serial_no"
  ],
  "fields": [
   {
@@ -152,11 +159,36 @@
    "oldfieldname": "bom_detail_no",
    "oldfieldtype": "Data",
    "read_only": 1
+  },
+  {
+   "fieldname": "secbreak_1",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "col_break2",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "secbreak_2",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "col_break3",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "secbreak_3",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "col_break4",
+   "fieldtype": "Column Break"
   }
  ],
  "idx": 1,
  "istable": 1,
- "modified": "2019-11-21 16:25:29.909112",
+ "links": [],
+ "modified": "2020-04-10 18:09:33.997618",
  "modified_by": "Administrator",
  "module": "Buying",
  "name": "Purchase Receipt Item Supplied",
diff --git a/erpnext/config/healthcare.py b/erpnext/config/healthcare.py
index 2b46127..da24d11 100644
--- a/erpnext/config/healthcare.py
+++ b/erpnext/config/healthcare.py
@@ -214,5 +214,41 @@
 					"label": _("Lab Test Report")
 				}
 			]
+		},
+		{
+			"label": _("Rehabilitation"),
+			"icon": "icon-cog",
+			"items": [
+				{
+					"type": "doctype",
+					"name": "Exercise Type",
+					"label": _("Exercise Type")
+				},
+				{
+					"type": "doctype",
+					"name": "Exercise Difficulty Level",
+					"label": _("Exercise Difficulty Level")
+				},
+				{
+					"type": "doctype",
+					"name": "Therapy Type",
+					"label": _("Therapy Type")
+				},
+				{
+					"type": "doctype",
+					"name": "Therapy Plan",
+					"label": _("Therapy Plan")
+				},
+				{
+					"type": "doctype",
+					"name": "Therapy Session",
+					"label": _("Therapy Session")
+				},
+				{
+					"type": "doctype",
+					"name": "Motor Assessment Scale",
+					"label": _("Motor Assessment Scale")
+				}
+			]
 		}
 	]
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 4045250..3e97f76 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -819,7 +819,7 @@
 		else:
 			for d in self.get("payment_schedule"):
 				if d.invoice_portion:
-					d.payment_amount = grand_total * flt(d.invoice_portion) / 100
+					d.payment_amount = flt(grand_total * flt(d.invoice_portion) / 100, d.precision('payment_amount'))
 
 	def set_due_date(self):
 		due_dates = [d.due_date for d in self.get("payment_schedule") if d.due_date]
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index 2b21ee8..90ba8b3 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -46,6 +46,7 @@
 		set_default_income_account_for_item(self)
 		self.set_customer_address()
 		self.validate_for_duplicate_items()
+		self.validate_target_warehouse()
 
 	def set_missing_values(self, for_validate=False):
 
@@ -403,6 +404,14 @@
 				else:
 					chk_dupl_itm.append(f)
 
+	def validate_target_warehouse(self):
+		items = self.get("items") + (self.get("packed_items") or [])
+
+		for d in items:
+			if d.get("target_warehouse") and d.get("warehouse") == d.get("target_warehouse"):
+				warehouse = frappe.bold(d.get("target_warehouse"))
+				frappe.throw(_("Row {0}: Delivery Warehouse ({1}) and Customer Warehouse ({2}) can not be same")
+					.format(d.idx, warehouse, warehouse))
 
 	def validate_items(self):
 		# validate items to see if they have is_sales_item enabled
diff --git a/erpnext/controllers/tests/test_mapper.py b/erpnext/controllers/tests/test_mapper.py
index d02308d..8839e00 100644
--- a/erpnext/controllers/tests/test_mapper.py
+++ b/erpnext/controllers/tests/test_mapper.py
@@ -13,7 +13,7 @@
 		'''Test mapping of multiple source docs on a single target doc'''
 
 		make_test_records("Item")
-		items = frappe.get_all("Item", fields = ["name", "item_code"], filters = {'is_sales_item': 1, 'has_variants': 0})
+		items = frappe.get_all("Item", fields = ["name", "item_code"], filters = {'is_sales_item': 1, 'has_variants': 0, 'disabled': 0})
 		customers = frappe.get_all("Customer")
 		if items and customers:
 			# Make source docs (quotations) and a target doc (sales order)
diff --git a/erpnext/crm/doctype/email_campaign/email_campaign.py b/erpnext/crm/doctype/email_campaign/email_campaign.py
index 00a4bd1..8f60ecf 100644
--- a/erpnext/crm/doctype/email_campaign/email_campaign.py
+++ b/erpnext/crm/doctype/email_campaign/email_campaign.py
@@ -27,7 +27,7 @@
 		for entry in campaign.get("campaign_schedules"):
 			send_after_days.append(entry.send_after_days)
 		try:
-			end_date = add_days(getdate(self.start_date), max(send_after_days))
+			self.end_date = add_days(getdate(self.start_date), max(send_after_days))
 		except ValueError:
 			frappe.throw(_("Please set up the Campaign Schedule in the Campaign {0}").format(self.campaign_name))
 
diff --git a/erpnext/erpnext_integrations/connectors/woocommerce_connection.py b/erpnext/erpnext_integrations/connectors/woocommerce_connection.py
index 4422d23..6188652 100644
--- a/erpnext/erpnext_integrations/connectors/woocommerce_connection.py
+++ b/erpnext/erpnext_integrations/connectors/woocommerce_connection.py
@@ -144,6 +144,10 @@
 def set_items_in_sales_order(new_sales_order, woocommerce_settings, order, sys_lang):
 	company_abbr = frappe.db.get_value('Company', woocommerce_settings.company, 'abbr')
 
+	default_warehouse = _("Stores - {0}", sys_lang).format(company_abbr)
+	if not frappe.db.exists("Warehouse", default_warehouse):
+		frappe.throw(_("Please set Warehouse in Woocommerce Settings"))
+
 	for item in order.get("line_items"):
 		woocomm_item_id = item.get("product_id")
 		found_item = frappe.get_doc("Item", {"woocommerce_id": woocomm_item_id})
@@ -158,7 +162,7 @@
 			"uom": woocommerce_settings.uom or _("Nos", sys_lang),
 			"qty": item.get("quantity"),
 			"rate": item.get("price"),
-			"warehouse": woocommerce_settings.warehouse or _("Stores - {0}", sys_lang).format(company_abbr)
+			"warehouse": woocommerce_settings.warehouse or default_warehouse
 			})
 
 		add_tax_details(new_sales_order, ordered_items_tax, "Ordered Item tax", woocommerce_settings.tax_account)
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
index 7083950..b4a5bd1 100644
--- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
@@ -67,11 +67,11 @@
 		frappe.throw(_("Please setup a default bank account for company {0}").format(company))
 
 	for account in response["accounts"]:
-		acc_type = frappe.db.get_value("Account Type", account["type"])
+		acc_type = frappe.db.get_value("Bank Account Type", account["type"])
 		if not acc_type:
 			add_account_type(account["type"])
 
-		acc_subtype = frappe.db.get_value("Account Subtype", account["subtype"])
+		acc_subtype = frappe.db.get_value("Bank Account Subtype", account["subtype"])
 		if not acc_subtype:
 			add_account_subtype(account["subtype"])
 
@@ -106,7 +106,7 @@
 def add_account_type(account_type):
 	try:
 		frappe.get_doc({
-			"doctype": "Account Type",
+			"doctype": "Bank Account Type",
 			"account_type": account_type
 		}).insert()
 	except Exception:
@@ -116,7 +116,7 @@
 def add_account_subtype(account_subtype):
 	try:
 		frappe.get_doc({
-			"doctype": "Account Subtype",
+			"doctype": "Bank Account Subtype",
 			"account_subtype": account_subtype
 		}).insert()
 	except Exception:
diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.py b/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.py
index 29e8fa4..1a063d6 100644
--- a/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.py
+++ b/erpnext/erpnext_integrations/doctype/plaid_settings/test_plaid_settings.py
@@ -23,11 +23,11 @@
 		for ba in frappe.get_all("Bank Account"):
 			frappe.get_doc("Bank Account", ba.name).delete()
 
-		for at in frappe.get_all("Account Type"):
-			frappe.get_doc("Account Type", at.name).delete()
+		for at in frappe.get_all("Bank Account Type"):
+			frappe.get_doc("Bank Account Type", at.name).delete()
 
-		for ast in frappe.get_all("Account Subtype"):
-			frappe.get_doc("Account Subtype", ast.name).delete()
+		for ast in frappe.get_all("Bank Account Subtype"):
+			frappe.get_doc("Bank Account Subtype", ast.name).delete()
 
 	def test_plaid_disabled(self):
 		frappe.db.set_value("Plaid Settings", None, "enabled", 0)
@@ -35,11 +35,11 @@
 
 	def test_add_account_type(self):
 		add_account_type("brokerage")
-		self.assertEqual(frappe.get_doc("Account Type", "brokerage").name, "brokerage")
+		self.assertEqual(frappe.get_doc("Bank Account Type", "brokerage").name, "brokerage")
 
 	def test_add_account_subtype(self):
 		add_account_subtype("loan")
-		self.assertEqual(frappe.get_doc("Account Subtype", "loan").name, "loan")
+		self.assertEqual(frappe.get_doc("Bank Account Subtype", "loan").name, "loan")
 
 	def test_default_bank_account(self):
 		if not frappe.db.exists("Bank", "Citi"):
diff --git a/erpnext/healthcare/desk_page/healthcare/healthcare.json b/erpnext/healthcare/desk_page/healthcare/healthcare.json
index 54798ba..24c6d6f 100644
--- a/erpnext/healthcare/desk_page/healthcare/healthcare.json
+++ b/erpnext/healthcare/desk_page/healthcare/healthcare.json
@@ -1,48 +1,53 @@
 {
  "cards": [
   {
-   "icon": "",
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient\",\n\t\t\"label\": \"Patient\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Practitioner\",\n\t\t\"label\":\"Healthcare Practitioner\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Practitioner Schedule\",\n\t\t\"label\": \"Practitioner Schedule\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Department\",\n\t\t\"label\": \"Medical Department\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Service Unit Type\",\n\t\t\"label\": \"Healthcare Service Unit Type\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Service Unit\",\n\t\t\"label\": \"Healthcare Service Unit\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Code Standard\",\n\t\t\"label\": \"Medical Code Standard\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Code\",\n\t\t\"label\": \"Medical Code\"\n\t}\n]",
-   "title": "Masters"
+   "hidden": 0,
+   "label": "Masters",
+   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient\",\n\t\t\"label\": \"Patient\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Practitioner\",\n\t\t\"label\":\"Healthcare Practitioner\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Practitioner Schedule\",\n\t\t\"label\": \"Practitioner Schedule\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Department\",\n\t\t\"label\": \"Medical Department\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Service Unit Type\",\n\t\t\"label\": \"Healthcare Service Unit Type\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Service Unit\",\n\t\t\"label\": \"Healthcare Service Unit\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Code Standard\",\n\t\t\"label\": \"Medical Code Standard\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Medical Code\",\n\t\t\"label\": \"Medical Code\"\n\t}\n]"
   },
   {
-   "icon": "",
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Appointment Type\",\n\t\t\"label\": \"Appointment Type\"\n    },\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Clinical Procedure Template\",\n\t\t\"label\": \"Clinical Procedure Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Prescription Dosage\",\n\t\t\"label\": \"Prescription Dosage\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Prescription Duration\",\n\t\t\"label\": \"Prescription Duration\"\n\t},\n\t{\n\t    \"type\": \"doctype\",\n\t\t\"name\": \"Antibiotic\",\n\t\t\"label\": \"Antibiotic\"\n\t}\n]",
-   "title": "Consultation Setup"
+   "hidden": 0,
+   "label": "Consultation Setup",
+   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Appointment Type\",\n\t\t\"label\": \"Appointment Type\"\n    },\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Clinical Procedure Template\",\n\t\t\"label\": \"Clinical Procedure Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Prescription Dosage\",\n\t\t\"label\": \"Prescription Dosage\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Prescription Duration\",\n\t\t\"label\": \"Prescription Duration\"\n\t},\n\t{\n\t    \"type\": \"doctype\",\n\t\t\"name\": \"Antibiotic\",\n\t\t\"label\": \"Antibiotic\"\n\t}\n]"
   },
   {
-   "icon": "icon-star",
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Appointment\",\n\t\t\"label\": \"Patient Appointment\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Clinical Procedure\",\n\t\t\"label\": \"Clinical Procedure\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Encounter\",\n\t\t\"label\": \"Patient Encounter\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Vital Signs\",\n\t\t\"label\": \"Vital Signs\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Complaint\",\n\t\t\"label\": \"Complaint\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Diagnosis\",\n\t\t\"label\": \"Diagnosis\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Fee Validity\",\n\t\t\"label\": \"Fee Validity\"\n\t}\n]",
-   "title": "Consultation"
+   "hidden": 0,
+   "label": "Consultation",
+   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Appointment\",\n\t\t\"label\": \"Patient Appointment\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Clinical Procedure\",\n\t\t\"label\": \"Clinical Procedure\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Encounter\",\n\t\t\"label\": \"Patient Encounter\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Vital Signs\",\n\t\t\"label\": \"Vital Signs\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Complaint\",\n\t\t\"label\": \"Complaint\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Diagnosis\",\n\t\t\"label\": \"Diagnosis\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Fee Validity\",\n\t\t\"label\": \"Fee Validity\"\n\t}\n]"
   },
   {
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Settings\",\n\t\t\"label\": \"Healthcare Settings\",\n\t\t\"onboard\": 1\n\t}\n]",
-   "title": "Settings"
+   "hidden": 0,
+   "label": "Settings",
+   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Healthcare Settings\",\n\t\t\"label\": \"Healthcare Settings\",\n\t\t\"onboard\": 1\n\t}\n]"
   },
   {
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test Template\",\n\t\t\"label\": \"Lab Test Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test Sample\",\n\t\t\"label\": \"Lab Test Sample\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test UOM\",\n\t\t\"label\": \"Lab Test UOM\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Sensitivity\",\n\t\t\"label\": \"Sensitivity\"\n\t}\n]",
-   "title": "Laboratory Setup"
+   "hidden": 0,
+   "label": "Laboratory Setup",
+   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test Template\",\n\t\t\"label\": \"Lab Test Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test Sample\",\n\t\t\"label\": \"Lab Test Sample\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test UOM\",\n\t\t\"label\": \"Lab Test UOM\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Sensitivity\",\n\t\t\"label\": \"Sensitivity\"\n\t}\n]"
   },
   {
-   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test\",\n\t\t\"label\": \"Lab Test\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Sample Collection\",\n\t\t\"label\": \"Sample Collection\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Dosage Form\",\n\t\t\"label\": \"Dosage Form\"\n\t}\n]",
-   "title": "Laboratory"
+   "hidden": 0,
+   "label": "Laboratory",
+   "links": "[\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Lab Test\",\n\t\t\"label\": \"Lab Test\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Sample Collection\",\n\t\t\"label\": \"Sample Collection\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Dosage Form\",\n\t\t\"label\": \"Dosage Form\"\n\t}\n]"
   },
   {
-   "links": "[\n\t{\n\t\t\"type\": \"page\",\n\t\t\"name\": \"patient_history\",\n\t\t\"label\": \"Patient History\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Medical Record\",\n\t\t\"label\": \"Patient Medical Record\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Inpatient Record\",\n\t\t\"label\": \"Inpatient Record\"\n\t}\n]",
-   "title": "Records and History"
+   "hidden": 0,
+   "label": "Rehabilitation and Physiotherapy",
+   "links": "[\n    {\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Exercise Type\",\n\t\t\"label\": \"Exercise Type\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Therapy Type\",\n\t\t\"label\": \"Therapy Type\",\n\t\t\"onboard\": 1\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Therapy Plan\",\n\t\t\"label\": \"Therapy Plan\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Therapy Session\",\n\t\t\"label\": \"Therapy Session\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Assessment Template\",\n\t\t\"label\": \"Patient Assessment Template\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Assessment\",\n\t\t\"label\": \"Patient Assessment\"\n\t}\n]"
   },
   {
-   "links": "[\n\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Patient Appointment Analytics\",\n\t\t\"doctype\": \"Patient Appointment\"\n\t},\n\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Lab Test Report\",\n\t\t\"doctype\": \"Lab Test\",\n\t\t\"label\": \"Lab Test Report\"\n\t}\n]",
-   "title": "Reports"
+   "hidden": 0,
+   "label": "Records and History",
+   "links": "[\n\t{\n\t\t\"type\": \"page\",\n\t\t\"name\": \"patient_history\",\n\t\t\"label\": \"Patient History\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Patient Medical Record\",\n\t\t\"label\": \"Patient Medical Record\"\n\t},\n\t{\n\t\t\"type\": \"doctype\",\n\t\t\"name\": \"Inpatient Record\",\n\t\t\"label\": \"Inpatient Record\"\n\t}\n]"
+  },
+  {
+   "hidden": 0,
+   "label": "Reports",
+   "links": "[\n\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Patient Appointment Analytics\",\n\t\t\"doctype\": \"Patient Appointment\"\n\t},\n\t{\n\t\t\"type\": \"report\",\n\t\t\"is_query_report\": true,\n\t\t\"name\": \"Lab Test Report\",\n\t\t\"doctype\": \"Lab Test\",\n\t\t\"label\": \"Lab Test Report\"\n\t}\n]"
   }
  ],
  "category": "Domains",
- "charts": [
-  {
-   "chart_name": "Patient Appointments",
-   "label": "Patient Appointments"
-  }
- ],
+ "charts": [],
  "charts_label": "",
  "creation": "2020-03-02 17:23:17.919682",
  "developer_mode_only": 0,
@@ -53,7 +58,7 @@
  "idx": 0,
  "is_standard": 1,
  "label": "Healthcare",
- "modified": "2020-03-26 16:10:44.629795",
+ "modified": "2020-04-20 11:42:43.889576",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Healthcare",
@@ -64,32 +69,32 @@
  "shortcuts": [
   {
    "format": "{} Open",
-   "is_query_report": 0,
+   "label": "Patient Appointment",
    "link_to": "Patient Appointment",
    "stats_filter": "{\n    \"status\": \"Open\"\n}",
    "type": "DocType"
   },
   {
    "format": "{} Active",
-   "is_query_report": 0,
+   "label": "Patient",
    "link_to": "Patient",
    "stats_filter": "{\n    \"status\": \"Active\"\n}",
    "type": "DocType"
   },
   {
    "format": "{} Vacant",
-   "is_query_report": 0,
+   "label": "Healthcare Service Unit",
    "link_to": "Healthcare Service Unit",
    "stats_filter": "{\n    \"occupancy_status\": \"Vacant\",\n    \"is_group\": 0\n}",
    "type": "DocType"
   },
   {
-   "is_query_report": 0,
+   "label": "Healthcare Practitioner",
    "link_to": "Healthcare Practitioner",
    "type": "DocType"
   },
   {
-   "is_query_report": 0,
+   "label": "Patient History",
    "link_to": "patient_history",
    "type": "Page"
   }
diff --git a/erpnext/accounts/doctype/account_subtype/__init__.py b/erpnext/healthcare/doctype/body_part/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/account_subtype/__init__.py
copy to erpnext/healthcare/doctype/body_part/__init__.py
diff --git a/erpnext/healthcare/doctype/body_part/body_part.js b/erpnext/healthcare/doctype/body_part/body_part.js
new file mode 100644
index 0000000..d2f9d09
--- /dev/null
+++ b/erpnext/healthcare/doctype/body_part/body_part.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Body Part', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/healthcare/doctype/body_part/body_part.json b/erpnext/healthcare/doctype/body_part/body_part.json
new file mode 100644
index 0000000..6e3d1d4
--- /dev/null
+++ b/erpnext/healthcare/doctype/body_part/body_part.json
@@ -0,0 +1,45 @@
+{
+ "actions": [],
+ "autoname": "field:body_part",
+ "creation": "2020-04-10 12:21:55.036402",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "body_part"
+ ],
+ "fields": [
+  {
+   "fieldname": "body_part",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Body Part",
+   "reqd": 1,
+   "unique": 1
+  }
+ ],
+ "links": [],
+ "modified": "2020-04-10 12:26:44.087985",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Body Part",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/account_subtype/account_subtype.py b/erpnext/healthcare/doctype/body_part/body_part.py
similarity index 61%
copy from erpnext/accounts/doctype/account_subtype/account_subtype.py
copy to erpnext/healthcare/doctype/body_part/body_part.py
index 46c45cc..300493a 100644
--- a/erpnext/accounts/doctype/account_subtype/account_subtype.py
+++ b/erpnext/healthcare/doctype/body_part/body_part.py
@@ -1,9 +1,10 @@
 # -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
+# import frappe
 from frappe.model.document import Document
 
-class AccountSubtype(Document):
+class BodyPart(Document):
 	pass
diff --git a/erpnext/healthcare/doctype/body_part/test_body_part.py b/erpnext/healthcare/doctype/body_part/test_body_part.py
new file mode 100644
index 0000000..cb3a611
--- /dev/null
+++ b/erpnext/healthcare/doctype/body_part/test_body_part.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestBodyPart(unittest.TestCase):
+	pass
diff --git a/erpnext/accounts/doctype/account_subtype/__init__.py b/erpnext/healthcare/doctype/body_part_link/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/account_subtype/__init__.py
copy to erpnext/healthcare/doctype/body_part_link/__init__.py
diff --git a/erpnext/healthcare/doctype/body_part_link/body_part_link.json b/erpnext/healthcare/doctype/body_part_link/body_part_link.json
new file mode 100644
index 0000000..400b7c6
--- /dev/null
+++ b/erpnext/healthcare/doctype/body_part_link/body_part_link.json
@@ -0,0 +1,32 @@
+{
+ "actions": [],
+ "creation": "2020-04-10 12:23:15.259816",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "body_part"
+ ],
+ "fields": [
+  {
+   "fieldname": "body_part",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Body Part",
+   "options": "Body Part",
+   "reqd": 1
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-04-10 12:25:23.101749",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Body Part Link",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/account_subtype/account_subtype.py b/erpnext/healthcare/doctype/body_part_link/body_part_link.py
similarity index 60%
copy from erpnext/accounts/doctype/account_subtype/account_subtype.py
copy to erpnext/healthcare/doctype/body_part_link/body_part_link.py
index 46c45cc..0371529 100644
--- a/erpnext/accounts/doctype/account_subtype/account_subtype.py
+++ b/erpnext/healthcare/doctype/body_part_link/body_part_link.py
@@ -1,9 +1,10 @@
 # -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
+# import frappe
 from frappe.model.document import Document
 
-class AccountSubtype(Document):
+class BodyPartLink(Document):
 	pass
diff --git a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py
index 3f295af..f32b7cf 100644
--- a/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py
+++ b/erpnext/healthcare/doctype/clinical_procedure_template/clinical_procedure_template.py
@@ -79,6 +79,7 @@
 	if doc.is_billable and not doc.disabled:
 		disabled = 0
 
+	uom = frappe.db.exists('UOM', 'Unit') or frappe.db.get_single_value('Stock Settings', 'stock_uom')
 	item = frappe.get_doc({
 		'doctype': 'Item',
 		'item_code': doc.template,
@@ -92,7 +93,7 @@
 		'show_in_website': 0,
 		'is_pro_applicable': 0,
 		'disabled': disabled,
-		'stock_uom': 'Unit'
+		'stock_uom': uom
 	}).insert(ignore_permissions=True, ignore_mandatory=True)
 
 	make_item_price(item.name, doc.rate)
diff --git a/erpnext/accounts/doctype/account_type/__init__.py b/erpnext/healthcare/doctype/exercise/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/account_type/__init__.py
copy to erpnext/healthcare/doctype/exercise/__init__.py
diff --git a/erpnext/healthcare/doctype/exercise/exercise.json b/erpnext/healthcare/doctype/exercise/exercise.json
new file mode 100644
index 0000000..2486a5d
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise/exercise.json
@@ -0,0 +1,61 @@
+{
+ "actions": [],
+ "creation": "2020-03-11 09:25:00.968572",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "exercise_type",
+  "difficulty_level",
+  "counts_target",
+  "counts_completed",
+  "assistance_level"
+ ],
+ "fields": [
+  {
+   "fieldname": "exercise_type",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Exercise Type",
+   "options": "Exercise Type",
+   "reqd": 1
+  },
+  {
+   "fetch_from": "exercise_type.difficulty_level",
+   "fieldname": "difficulty_level",
+   "fieldtype": "Link",
+   "label": "Difficulty Level",
+   "options": "Exercise Difficulty Level"
+  },
+  {
+   "fieldname": "counts_target",
+   "fieldtype": "Int",
+   "in_list_view": 1,
+   "label": "Counts Target"
+  },
+  {
+   "depends_on": "eval:doc.parenttype==\"Therapy\";",
+   "fieldname": "counts_completed",
+   "fieldtype": "Int",
+   "label": "Counts Completed"
+  },
+  {
+   "fieldname": "assistance_level",
+   "fieldtype": "Select",
+   "label": "Assistance Level",
+   "options": "\nPassive\nActive Assist\nActive"
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-04-10 13:41:06.662351",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Exercise",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/account_subtype/account_subtype.py b/erpnext/healthcare/doctype/exercise/exercise.py
similarity index 61%
copy from erpnext/accounts/doctype/account_subtype/account_subtype.py
copy to erpnext/healthcare/doctype/exercise/exercise.py
index 46c45cc..efd8999 100644
--- a/erpnext/accounts/doctype/account_subtype/account_subtype.py
+++ b/erpnext/healthcare/doctype/exercise/exercise.py
@@ -1,9 +1,10 @@
 # -*- coding: utf-8 -*-
-# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
+# import frappe
 from frappe.model.document import Document
 
-class AccountSubtype(Document):
+class Exercise(Document):
 	pass
diff --git a/erpnext/accounts/doctype/account_subtype/__init__.py b/erpnext/healthcare/doctype/exercise_difficulty_level/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/account_subtype/__init__.py
copy to erpnext/healthcare/doctype/exercise_difficulty_level/__init__.py
diff --git a/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.js b/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.js
new file mode 100644
index 0000000..ff51c34
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Exercise Difficulty Level', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.json b/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.json
new file mode 100644
index 0000000..a6aed75
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.json
@@ -0,0 +1,45 @@
+{
+ "actions": [],
+ "autoname": "field:difficulty_level",
+ "creation": "2020-03-29 21:12:55.835941",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "difficulty_level"
+ ],
+ "fields": [
+  {
+   "fieldname": "difficulty_level",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Difficulty Level",
+   "reqd": 1,
+   "unique": 1
+  }
+ ],
+ "links": [],
+ "modified": "2020-03-31 23:14:33.554066",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Exercise Difficulty Level",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.py b/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.py
new file mode 100644
index 0000000..17e97b8
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_difficulty_level/exercise_difficulty_level.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class ExerciseDifficultyLevel(Document):
+	pass
diff --git a/erpnext/healthcare/doctype/exercise_difficulty_level/test_exercise_difficulty_level.py b/erpnext/healthcare/doctype/exercise_difficulty_level/test_exercise_difficulty_level.py
new file mode 100644
index 0000000..80ef3a7
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_difficulty_level/test_exercise_difficulty_level.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestExerciseDifficultyLevel(unittest.TestCase):
+	pass
diff --git a/erpnext/accounts/doctype/account_type/__init__.py b/erpnext/healthcare/doctype/exercise_type/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/account_type/__init__.py
copy to erpnext/healthcare/doctype/exercise_type/__init__.py
diff --git a/erpnext/healthcare/doctype/exercise_type/exercise_type.js b/erpnext/healthcare/doctype/exercise_type/exercise_type.js
new file mode 100644
index 0000000..f450c9b
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_type/exercise_type.js
@@ -0,0 +1,180 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Exercise Type', {
+	refresh: function(frm) {
+		let wrapper = frm.fields_dict.steps_html.wrapper;
+
+		frm.ExerciseEditor = new erpnext.ExerciseEditor(frm, wrapper);
+	}
+});
+
+erpnext.ExerciseEditor = Class.extend({
+	init: function(frm, wrapper) {
+		this.wrapper = wrapper;
+		this.frm = frm;
+		this.make(frm, wrapper);
+	},
+
+	make: function(frm, wrapper) {
+		$(this.wrapper).empty();
+
+		this.exercise_toolbar = $('<p>\
+		<button class="btn btn-default btn-add btn-xs" style="margin-left: 10px;"></button>').appendTo(this.wrapper);
+
+		this.exercise_cards = $('<div class="exercise-cards"></div>').appendTo(this.wrapper);
+
+		let me = this;
+
+		this.exercise_toolbar.find(".btn-add")
+			.html(__('Add'))
+			.on("click", function() {
+				me.show_add_card_dialog(frm);
+			});
+
+		if (frm.doc.steps_table.length > 0) {
+			this.make_cards(frm);
+			this.make_buttons(frm);
+		}
+	},
+
+	make_cards: function(frm) {
+		var me = this;
+		$(me.exercise_cards).empty();
+		this.row = $('<div class="exercise-row"></div>').appendTo(me.exercise_cards);
+
+		$.each(frm.doc.steps_table, function(i, step) {
+			$(repl(`
+				<div class="exercise-col col-sm-4" id="%(col_id)s">
+					<div class="card h-100 exercise-card" id="%(card_id)s">
+						<div class="card-body exercise-card-body">
+							<img src=%(image_src)s class="card-img-top" alt="...">
+							<h4 class="card-title">%(title)s</h4>
+							<p class="card-text text-truncate">%(description)s</p>
+						</div>
+						<div class="card-footer">
+							<button class="btn btn-default btn-xs btn-edit" data-id="%(id)s"><i class="fa fa-pencil" aria-hidden="true"></i></button>
+							<button class="btn btn-default btn-xs btn-del" data-id="%(id)s"><i class="fa fa-trash" aria-hidden="true"></i></button>
+						</div>
+					</div>
+			</div>`, {image_src: step.image, title: step.title, description: step.description, col_id: "col-"+i, card_id: "card-"+i, id: i})).appendTo(me.row);
+		});
+	},
+
+	make_buttons: function(frm) {
+		let me = this;
+		$('.btn-edit').on('click', function() {
+			let id = $(this).attr('data-id');
+			me.show_edit_card_dialog(frm, id);
+		});
+
+		$('.btn-del').on('click', function() {
+			let id = $(this).attr('data-id');
+			$('#card-'+id).addClass("zoomOutDelete");
+
+			setTimeout(() => {
+				// not using grid_rows[id].remove because
+				// grid_rows is not defined when the table is hidden
+				frm.doc.steps_table.pop(id);
+				frm.refresh_field('steps_table');
+				$('#col-'+id).remove();
+			}, 300);
+		});
+	},
+
+	show_add_card_dialog: function(frm) {
+		let me = this;
+		let d = new frappe.ui.Dialog({
+			title: __('Add Exercise Step'),
+			fields: [
+				{
+					"label": "Title",
+					"fieldname": "title",
+					"fieldtype": "Data",
+					"reqd": 1
+				},
+				{
+					"label": "Attach Image",
+					"fieldname": "image",
+					"fieldtype": "Attach Image"
+				},
+				{
+					"label": "Step Description",
+					"fieldname": "step_description",
+					"fieldtype": "Long Text"
+				}
+			],
+			primary_action: function() {
+				let data = d.get_values();
+				let i = frm.doc.steps_table.length;
+				$(repl(`
+					<div class="exercise-col col-sm-4" id="%(col_id)s">
+						<div class="card h-100 exercise-card" id="%(card_id)s">
+							<div class="card-body exercise-card-body">
+								<img src=%(image_src)s class="card-img-top" alt="...">
+								<h4 class="card-title">%(title)s</h4>
+								<p class="card-text text-truncate">%(description)s</p>
+							</div>
+							<div class="card-footer">
+								<button class="btn btn-default btn-xs btn-edit" data-id="%(id)s"><i class="fa fa-pencil" aria-hidden="true"></i></button>
+								<button class="btn btn-default btn-xs btn-del" data-id="%(id)s"><i class="fa fa-trash" aria-hidden="true"></i></button>
+							</div>
+						</div>
+					</div>`, {image_src: data.image, title: data.title, description: data.step_description, col_id: "col-"+i, card_id: "card-"+i, id: i})).appendTo(me.row);
+				let step = frappe.model.add_child(frm.doc, 'Exercise Type Step', 'steps_table');
+				step.title = data.title;
+				step.image = data.image;
+				step.description = data.step_description;
+				me.make_buttons(frm);
+				frm.refresh_field('steps_table');
+				d.hide();
+			},
+			primary_action_label: __('Add')
+		});
+		d.show();
+	},
+
+	show_edit_card_dialog: function(frm, id) {
+		let new_dialog = new frappe.ui.Dialog({
+			title: __("Edit Exercise Step"),
+			fields: [
+				{
+					"label": "Title",
+					"fieldname": "title",
+					"fieldtype": "Data",
+					"reqd": 1
+				},
+				{
+					"label": "Attach Image",
+					"fieldname": "image",
+					"fieldtype": "Attach Image"
+				},
+				{
+					"label": "Step Description",
+					"fieldname": "step_description",
+					"fieldtype": "Long Text"
+				}
+			],
+			primary_action: () => {
+				let data = new_dialog.get_values();
+				$('#card-'+id).find('.card-title').html(data.title);
+				$('#card-'+id).find('img').attr('src', data.image);
+				$('#card-'+id).find('.card-text').html(data.step_description);
+
+				frm.doc.steps_table[id].title = data.title;
+				frm.doc.steps_table[id].image = data.image;
+				frm.doc.steps_table[id].description = data.step_description;
+				refresh_field('steps_table');
+				new_dialog.hide();
+			},
+			primary_action_label: __("Save"),
+		});
+
+		new_dialog.set_values({
+			title: frm.doc.steps_table[id].title,
+			image: frm.doc.steps_table[id].image,
+			step_description: frm.doc.steps_table[id].description
+		});
+		new_dialog.show();
+	}
+});
diff --git a/erpnext/healthcare/doctype/exercise_type/exercise_type.json b/erpnext/healthcare/doctype/exercise_type/exercise_type.json
new file mode 100644
index 0000000..0db9c6e
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_type/exercise_type.json
@@ -0,0 +1,144 @@
+{
+ "actions": [],
+ "creation": "2020-03-29 21:37:03.366344",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "exercise_name",
+  "body_parts",
+  "column_break_3",
+  "difficulty_level",
+  "section_break_5",
+  "description",
+  "section_break_7",
+  "exercise_steps",
+  "column_break_9",
+  "exercise_video",
+  "section_break_11",
+  "steps_html",
+  "section_break_13",
+  "steps_table"
+ ],
+ "fields": [
+  {
+   "fieldname": "exercise_name",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Exercise Name",
+   "reqd": 1
+  },
+  {
+   "fieldname": "difficulty_level",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Difficulty Level",
+   "options": "Exercise Difficulty Level"
+  },
+  {
+   "fieldname": "column_break_3",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "section_break_5",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "description",
+   "fieldtype": "Long Text",
+   "label": "Description"
+  },
+  {
+   "fieldname": "section_break_7",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "exercise_steps",
+   "fieldtype": "Attach",
+   "label": "Exercise Instructions"
+  },
+  {
+   "fieldname": "exercise_video",
+   "fieldtype": "Link",
+   "label": "Exercise Video",
+   "options": "Video"
+  },
+  {
+   "fieldname": "column_break_9",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "steps_html",
+   "fieldtype": "HTML",
+   "label": "Steps"
+  },
+  {
+   "fieldname": "steps_table",
+   "fieldtype": "Table",
+   "hidden": 1,
+   "label": "Steps Table",
+   "options": "Exercise Type Step"
+  },
+  {
+   "fieldname": "section_break_11",
+   "fieldtype": "Section Break",
+   "label": "Exercise Steps"
+  },
+  {
+   "fieldname": "section_break_13",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "body_parts",
+   "fieldtype": "Table MultiSelect",
+   "label": "Body Parts",
+   "options": "Body Part Link"
+  }
+ ],
+ "links": [],
+ "modified": "2020-04-21 13:05:36.555060",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Exercise Type",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Healthcare Administrator",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Physician",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/exercise_type/exercise_type.py b/erpnext/healthcare/doctype/exercise_type/exercise_type.py
new file mode 100644
index 0000000..fb635c8
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_type/exercise_type.py
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class ExerciseType(Document):
+	def autoname(self):
+		if self.difficulty_level:
+			self.name = ' - '.join(filter(None, [self.exercise_name, self.difficulty_level]))
+		else:
+			self.name = self.exercise_name
+
diff --git a/erpnext/healthcare/doctype/exercise_type/test_exercise_type.py b/erpnext/healthcare/doctype/exercise_type/test_exercise_type.py
new file mode 100644
index 0000000..bf217e8
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_type/test_exercise_type.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestExerciseType(unittest.TestCase):
+	pass
diff --git a/erpnext/accounts/doctype/account_subtype/__init__.py b/erpnext/healthcare/doctype/exercise_type_step/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/account_subtype/__init__.py
copy to erpnext/healthcare/doctype/exercise_type_step/__init__.py
diff --git a/erpnext/healthcare/doctype/exercise_type_step/exercise_type_step.json b/erpnext/healthcare/doctype/exercise_type_step/exercise_type_step.json
new file mode 100644
index 0000000..b37ff00
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_type_step/exercise_type_step.json
@@ -0,0 +1,44 @@
+{
+ "actions": [],
+ "creation": "2020-03-31 23:01:18.761967",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "title",
+  "image",
+  "description"
+ ],
+ "fields": [
+  {
+   "fieldname": "title",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Title",
+   "reqd": 1
+  },
+  {
+   "fieldname": "image",
+   "fieldtype": "Attach Image",
+   "label": "Image"
+  },
+  {
+   "fieldname": "description",
+   "fieldtype": "Long Text",
+   "in_list_view": 1,
+   "label": "Description"
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-04-02 20:39:34.258512",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Exercise Type Step",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/exercise_type_step/exercise_type_step.py b/erpnext/healthcare/doctype/exercise_type_step/exercise_type_step.py
new file mode 100644
index 0000000..13d7e57
--- /dev/null
+++ b/erpnext/healthcare/doctype/exercise_type_step/exercise_type_step.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class ExerciseTypeStep(Document):
+	pass
diff --git a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
index 6bbb4f1..e2b47b4 100644
--- a/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
+++ b/erpnext/healthcare/doctype/lab_test_template/lab_test_template.py
@@ -74,26 +74,27 @@
 
 
 def create_item_from_template(doc):
-	if doc.is_billable:
+	disabled = doc.disabled
+	if doc.is_billable and not doc.disabled:
 		disabled = 0
-	else:
-		disabled = 1
+
+	uom = frappe.db.exists('UOM', 'Unit') or frappe.db.get_single_value('Stock Settings', 'stock_uom')
 	# insert item
 	item =  frappe.get_doc({
-	"doctype": "Item",
-	"item_code": doc.lab_test_code,
-	"item_name":doc.lab_test_name,
-	"item_group": doc.lab_test_group,
-	"description":doc.lab_test_description,
-	"is_sales_item": 1,
-	"is_service_item": 1,
-	"is_purchase_item": 0,
-	"is_stock_item": 0,
-	"show_in_website": 0,
-	"is_pro_applicable": 0,
-	"disabled": disabled,
-	"stock_uom": "Unit"
-	}).insert(ignore_permissions=True)
+		"doctype": "Item",
+		"item_code": doc.lab_test_code,
+		"item_name":doc.lab_test_name,
+		"item_group": doc.lab_test_group,
+		"description":doc.lab_test_description,
+		"is_sales_item": 1,
+		"is_service_item": 1,
+		"is_purchase_item": 0,
+		"is_stock_item": 0,
+		"show_in_website": 0,
+		"is_pro_applicable": 0,
+		"disabled": disabled,
+		"stock_uom": uom
+	}).insert(ignore_permissions=True, ignore_mandatory=True)
 
 	# insert item price
 	# get item price list to insert item price
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
index efa6b24..fa58934 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js
@@ -102,6 +102,13 @@
 						frm: frm,
 					});
 				}, __('Create'));
+			} else if (frm.doc.therapy_type) {
+				frm.add_custom_button(__('Therapy Session'),function(){
+					frappe.model.open_mapped_doc({
+						method: 'erpnext.healthcare.doctype.therapy_session.therapy_session.create_therapy_session',
+						frm: frm,
+					})
+				}, 'Create');
 			} else {
 				frm.add_custom_button(__('Patient Encounter'), function() {
 					frappe.model.open_mapped_doc({
@@ -123,6 +130,16 @@
 		}
 	},
 
+	therapy_type: function(frm) {
+		if (frm.doc.therapy_type) {
+			frappe.db.get_value('Therapy Type', frm.doc.therapy_type, 'default_duration', (r) => {
+				if (r.default_duration) {
+					frm.set_value('duration', r.default_duration)
+				}
+			});
+		}
+	},
+
 	get_procedure_from_encounter: function(frm) {
 		get_prescribed_procedure(frm);
 	},
@@ -148,6 +165,26 @@
 				}
 			}
 		});
+	},
+
+	get_prescribed_therapies: function(frm) {
+		if (frm.doc.patient) {
+			frappe.call({
+				method: "erpnext.healthcare.doctype.patient_appointment.patient_appointment.get_prescribed_therapies",
+				args: {patient: frm.doc.patient},
+				callback: function(r) {
+					if (r.message) {
+						show_therapy_types(frm, r.message);
+					} else {
+						frappe.msgprint({
+							title: __('Not Therapies Prescribed'),
+							message: __('There are no Therapies prescribed for Patient {0}', [frm.doc.patient.bold()]),
+							indicator: 'blue'
+						});
+					}
+				}
+			});
+		}
 	}
 });
 
@@ -393,6 +430,50 @@
 	d.show();
 };
 
+let show_therapy_types = function(frm, result) {
+	var d = new frappe.ui.Dialog({
+		title: __('Prescribed Therapies'),
+		fields: [
+			{
+				fieldtype: 'HTML', fieldname: 'therapy_type'
+			}
+		]
+	});
+	var html_field = d.fields_dict.therapy_type.$wrapper;
+	$.each(result, function(x, y){
+		var row = $(repl('<div class="col-xs-12" style="padding-top:12px; text-align:center;" >\
+		<div class="col-xs-5"> %(encounter)s <br> %(practitioner)s <br> %(date)s </div>\
+		<div class="col-xs-5"> %(therapy)s </div>\
+		<div class="col-xs-2">\
+		<a data-therapy="%(therapy)s" data-therapy-plan="%(therapy_plan)s" data-name="%(name)s"\
+		data-encounter="%(encounter)s" data-practitioner="%(practitioner)s"\
+		data-date="%(date)s"  data-department="%(department)s">\
+		<button class="btn btn-default btn-xs">Add\
+		</button></a></div></div><div class="col-xs-12"><hr/><div/>', {therapy:y[0],
+		name: y[1], encounter:y[2], practitioner:y[3], date:y[4],
+		department:y[6]? y[6]:'', therapy_plan:y[5]})).appendTo(html_field);
+
+		row.find("a").click(function() {
+			frm.doc.therapy_type = $(this).attr("data-therapy");
+			frm.doc.practitioner = $(this).attr("data-practitioner");
+			frm.doc.department = $(this).attr("data-department");
+			frm.doc.therapy_plan = $(this).attr("data-therapy-plan");
+			frm.refresh_field("therapy_type");
+			frm.refresh_field("practitioner");
+			frm.refresh_field("department");
+			frm.refresh_field("therapy-plan");
+			frappe.db.get_value('Therapy Type', frm.doc.therapy_type, 'default_duration', (r) => {
+				if (r.default_duration) {
+					frm.set_value('duration', r.default_duration)
+				}
+			});
+			d.hide();
+			return false;
+		});
+	});
+	d.show();
+};
+
 let create_vital_signs = function(frm) {
 	if (!frm.doc.patient) {
 		frappe.throw(__('Please select patient'));
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
index 7f9a671..57e6c47 100644
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json
@@ -20,6 +20,9 @@
   "procedure_template",
   "get_procedure_from_encounter",
   "procedure_prescription",
+  "therapy_type",
+  "get_prescribed_therapies",
+  "therapy_plan",
   "service_unit",
   "section_break_12",
   "practitioner",
@@ -270,6 +273,28 @@
    "report_hide": 1
   },
   {
+   "depends_on": "eval:doc.patient;",
+   "fieldname": "therapy_type",
+   "fieldtype": "Link",
+   "label": "Therapy",
+   "options": "Therapy Type",
+   "set_only_once": 1
+  },
+  {
+   "depends_on": "eval:doc.patient && doc.__islocal;",
+   "fieldname": "get_prescribed_therapies",
+   "fieldtype": "Button",
+   "label": "Get Prescribed Therapies"
+  },
+  {
+   "depends_on": "eval: doc.patient && doc.therapy_type",
+   "fieldname": "therapy_plan",
+   "fieldtype": "Link",
+   "label": "Therapy Plan",
+   "mandatory_depends_on": "eval: doc.patient && doc.therapy_type",
+   "options": "Therapy Plan"
+  },
+  {
    "fieldname": "ref_sales_invoice",
    "fieldtype": "Link",
    "label": "Reference Sales Invoice",
@@ -285,7 +310,7 @@
   }
  ],
  "links": [],
- "modified": "2020-03-27 11:27:33.773195",
+ "modified": "2020-03-31 16:16:32.116865",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Patient Appointment",
diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
index a2d9d02..512d44e 100755
--- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
+++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
@@ -412,11 +412,36 @@
 
 @frappe.whitelist()
 def get_procedure_prescribed(patient):
-	return frappe.db.sql("""select pp.name, pp.procedure, pp.parent, ct.practitioner,
-	ct.encounter_date, pp.practitioner, pp.date, pp.department
-	from `tabPatient Encounter` ct, `tabProcedure Prescription` pp
-	where ct.patient=%(patient)s and pp.parent=ct.name and pp.appointment_booked=0
-	order by ct.creation desc""", {'patient': patient})
+	return frappe.db.sql(
+		"""
+			SELECT
+				pp.name, pp.procedure, pp.parent, ct.practitioner,
+				ct.encounter_date, pp.practitioner, pp.date, pp.department
+			FROM
+				`tabPatient Encounter` ct, `tabProcedure Prescription` pp
+			WHERE
+				ct.patient=%(patient)s and pp.parent=ct.name and pp.appointment_booked=0
+			ORDER BY
+				ct.creation desc
+		""", {'patient': patient}
+	)
+
+
+@frappe.whitelist()
+def get_prescribed_therapies(patient):
+	return frappe.db.sql(
+		"""
+			SELECT
+				t.therapy_type, t.name, t.parent, e.practitioner,
+				e.encounter_date, e.therapy_plan, e.visit_department
+			FROM
+				`tabPatient Encounter` e, `tabTherapy Plan Detail` t
+			WHERE
+				e.patient=%(patient)s and t.parent=e.name
+			ORDER BY
+				e.creation desc
+		""", {'patient': patient}
+	)
 
 
 def update_appointment_status():
diff --git a/erpnext/accounts/doctype/account_subtype/__init__.py b/erpnext/healthcare/doctype/patient_assessment/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/account_subtype/__init__.py
copy to erpnext/healthcare/doctype/patient_assessment/__init__.py
diff --git a/erpnext/healthcare/doctype/patient_assessment/patient_assessment.js b/erpnext/healthcare/doctype/patient_assessment/patient_assessment.js
new file mode 100644
index 0000000..c7074e8
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment/patient_assessment.js
@@ -0,0 +1,86 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Patient Assessment', {
+	refresh: function(frm) {
+		if (frm.doc.assessment_template) {
+			frm.trigger('set_score_range');
+		}
+
+		if (!frm.doc.__islocal) {
+			frm.trigger('show_patient_progress');
+		}
+	},
+
+	assessment_template: function(frm) {
+		if (frm.doc.assessment_template) {
+			frappe.call({
+				'method': 'frappe.client.get',
+				args: {
+					doctype: 'Patient Assessment Template',
+					name: frm.doc.assessment_template
+				},
+				callback: function(data) {
+					frm.doc.assessment_sheet = [];
+					$.each(data.message.parameters, function(_i, e) {
+						let entry = frm.add_child('assessment_sheet');
+						entry.parameter = e.assessment_parameter;
+					});
+
+					frm.set_value('scale_min', data.message.scale_min);
+					frm.set_value('scale_max', data.message.scale_max);
+					frm.set_value('assessment_description', data.message.assessment_description);
+					frm.set_value('total_score', data.message.scale_max * data.message.parameters.length);
+					frm.trigger('set_score_range');
+					refresh_field('assessment_sheet');
+				}
+			});
+		}
+	},
+
+	set_score_range: function(frm) {
+		let options = [];
+		for(let i = frm.doc.scale_min; i <= frm.doc.scale_max; i++) {
+			options.push(i);
+		}
+		frappe.meta.get_docfield('Patient Assessment Sheet', 'score', frm.doc.name).options = [''].concat(options);
+	},
+
+	calculate_total_score: function(frm, cdt, cdn) {
+		let row = locals[cdt][cdn];
+		let total_score = 0;
+		$.each(frm.doc.assessment_sheet || [], function(_i, item) {
+			if (item.score) {
+				total_score += parseInt(item.score);
+			}
+		});
+
+		frm.set_value('total_score_obtained', total_score);
+	},
+
+	show_patient_progress: function(frm) {
+		let bars = [];
+		let message = '';
+		let added_min = false;
+
+		let title = __('{0} out of {1}', [frm.doc.total_score_obtained, frm.doc.total_score]);
+
+		bars.push({
+			'title': title,
+			'width': (frm.doc.total_score_obtained / frm.doc.total_score * 100) + '%',
+			'progress_class': 'progress-bar-success'
+		});
+		if (bars[0].width == '0%') {
+			bars[0].width = '0.5%';
+			added_min = 0.5;
+		}
+		message = title;
+		frm.dashboard.add_progress(__('Status'), bars, message);
+	},
+});
+
+frappe.ui.form.on('Patient Assessment Sheet', {
+	score: function(frm, cdt, cdn) {
+		frm.events.calculate_total_score(frm, cdt, cdn);
+	}
+});
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_assessment/patient_assessment.json b/erpnext/healthcare/doctype/patient_assessment/patient_assessment.json
new file mode 100644
index 0000000..3952a81
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment/patient_assessment.json
@@ -0,0 +1,172 @@
+{
+ "actions": [],
+ "autoname": "naming_series:",
+ "creation": "2020-04-19 22:45:12.356209",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "naming_series",
+  "therapy_session",
+  "patient",
+  "assessment_template",
+  "column_break_4",
+  "healthcare_practitioner",
+  "assessment_datetime",
+  "assessment_description",
+  "section_break_7",
+  "assessment_sheet",
+  "section_break_9",
+  "total_score_obtained",
+  "column_break_11",
+  "total_score",
+  "scale_min",
+  "scale_max",
+  "amended_from"
+ ],
+ "fields": [
+  {
+   "fetch_from": "therapy_session.patient",
+   "fieldname": "patient",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Patient",
+   "options": "Patient",
+   "reqd": 1
+  },
+  {
+   "fieldname": "assessment_template",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Assessment Template",
+   "options": "Patient Assessment Template",
+   "reqd": 1
+  },
+  {
+   "fieldname": "therapy_session",
+   "fieldtype": "Link",
+   "label": "Therapy Session",
+   "options": "Therapy Session"
+  },
+  {
+   "fieldname": "column_break_4",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fetch_from": "therapy_session.practitioner",
+   "fieldname": "healthcare_practitioner",
+   "fieldtype": "Link",
+   "label": "Healthcare Practitioner",
+   "options": "Healthcare Practitioner"
+  },
+  {
+   "fieldname": "assessment_datetime",
+   "fieldtype": "Datetime",
+   "label": "Assessment Datetime"
+  },
+  {
+   "fieldname": "section_break_7",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "assessment_sheet",
+   "fieldtype": "Table",
+   "label": "Assessment Sheet",
+   "options": "Patient Assessment Sheet"
+  },
+  {
+   "fieldname": "section_break_9",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "total_score",
+   "fieldtype": "Int",
+   "label": "Total Score",
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_11",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "total_score_obtained",
+   "fieldtype": "Int",
+   "label": "Total Score Obtained",
+   "read_only": 1
+  },
+  {
+   "fieldname": "scale_min",
+   "fieldtype": "Int",
+   "hidden": 1,
+   "label": "Scale Min",
+   "read_only": 1
+  },
+  {
+   "fieldname": "scale_max",
+   "fieldtype": "Int",
+   "hidden": 1,
+   "label": "Scale Max",
+   "read_only": 1
+  },
+  {
+   "fieldname": "naming_series",
+   "fieldtype": "Select",
+   "label": "Naming Series",
+   "options": "HLC-PA-.YYYY.-"
+  },
+  {
+   "fieldname": "amended_from",
+   "fieldtype": "Link",
+   "label": "Amended From",
+   "no_copy": 1,
+   "options": "Patient Assessment",
+   "print_hide": 1,
+   "read_only": 1
+  },
+  {
+   "fieldname": "assessment_description",
+   "fieldtype": "Small Text",
+   "label": "Assessment Description"
+  }
+ ],
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2020-04-21 13:23:09.815007",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient Assessment",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "cancel": 1,
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "submit": 1,
+   "write": 1
+  },
+  {
+   "cancel": 1,
+   "create": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Physician",
+   "share": 1,
+   "submit": 1,
+   "write": 1
+  }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "patient",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_assessment/patient_assessment.py b/erpnext/healthcare/doctype/patient_assessment/patient_assessment.py
new file mode 100644
index 0000000..3033a3e
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment/patient_assessment.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+from frappe.model.mapper import get_mapped_doc
+
+class PatientAssessment(Document):
+	def validate(self):
+		self.set_total_score()
+
+	def set_total_score(self):
+		total_score = 0
+		for entry in self.assessment_sheet:
+			total_score += int(entry.score)
+		self.total_score_obtained = total_score
+
+@frappe.whitelist()
+def create_patient_assessment(source_name, target_doc=None):
+	doc = get_mapped_doc('Therapy Session', source_name, {
+			'Therapy Session': {
+				'doctype': 'Patient Assessment',
+				'field_map': [
+					['therapy_session', 'name'],
+					['patient', 'patient'],
+					['practitioner', 'practitioner']
+				]
+			}
+		}, target_doc)
+
+	return doc
+
+
+
diff --git a/erpnext/healthcare/doctype/patient_assessment/test_patient_assessment.py b/erpnext/healthcare/doctype/patient_assessment/test_patient_assessment.py
new file mode 100644
index 0000000..3fda855
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment/test_patient_assessment.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestPatientAssessment(unittest.TestCase):
+	pass
diff --git a/erpnext/accounts/doctype/account_subtype/__init__.py b/erpnext/healthcare/doctype/patient_assessment_detail/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/account_subtype/__init__.py
copy to erpnext/healthcare/doctype/patient_assessment_detail/__init__.py
diff --git a/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.json b/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.json
new file mode 100644
index 0000000..179f441
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.json
@@ -0,0 +1,32 @@
+{
+ "actions": [],
+ "creation": "2020-04-19 19:33:00.115395",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "assessment_parameter"
+ ],
+ "fields": [
+  {
+   "fieldname": "assessment_parameter",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Assessment Parameter",
+   "options": "Patient Assessment Parameter",
+   "reqd": 1
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-04-19 19:33:00.115395",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient Assessment Detail",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.py b/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.py
new file mode 100644
index 0000000..0519599
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_detail/patient_assessment_detail.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class PatientAssessmentDetail(Document):
+	pass
diff --git a/erpnext/accounts/doctype/account_subtype/__init__.py b/erpnext/healthcare/doctype/patient_assessment_parameter/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/account_subtype/__init__.py
copy to erpnext/healthcare/doctype/patient_assessment_parameter/__init__.py
diff --git a/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.js b/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.js
new file mode 100644
index 0000000..2c5d270
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Patient Assessment Parameter', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.json b/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.json
new file mode 100644
index 0000000..098bdef
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.json
@@ -0,0 +1,45 @@
+{
+ "actions": [],
+ "autoname": "field:assessment_parameter",
+ "creation": "2020-04-15 14:34:46.551042",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "assessment_parameter"
+ ],
+ "fields": [
+  {
+   "fieldname": "assessment_parameter",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Assessment Parameter",
+   "reqd": 1,
+   "unique": 1
+  }
+ ],
+ "links": [],
+ "modified": "2020-04-20 09:22:19.135196",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient Assessment Parameter",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.py b/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.py
new file mode 100644
index 0000000..b8e0074
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_parameter/patient_assessment_parameter.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class PatientAssessmentParameter(Document):
+	pass
diff --git a/erpnext/healthcare/doctype/patient_assessment_parameter/test_patient_assessment_parameter.py b/erpnext/healthcare/doctype/patient_assessment_parameter/test_patient_assessment_parameter.py
new file mode 100644
index 0000000..e722f99
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_parameter/test_patient_assessment_parameter.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestPatientAssessmentParameter(unittest.TestCase):
+	pass
diff --git a/erpnext/accounts/doctype/account_subtype/__init__.py b/erpnext/healthcare/doctype/patient_assessment_sheet/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/account_subtype/__init__.py
copy to erpnext/healthcare/doctype/patient_assessment_sheet/__init__.py
diff --git a/erpnext/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.json b/erpnext/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.json
new file mode 100644
index 0000000..64e4aef
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.json
@@ -0,0 +1,57 @@
+{
+ "actions": [],
+ "creation": "2020-04-19 23:07:02.220244",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "parameter",
+  "score",
+  "time",
+  "column_break_4",
+  "comments"
+ ],
+ "fields": [
+  {
+   "fieldname": "parameter",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Parameter",
+   "options": "Patient Assessment Parameter",
+   "reqd": 1
+  },
+  {
+   "fieldname": "score",
+   "fieldtype": "Select",
+   "in_list_view": 1,
+   "label": "Score",
+   "reqd": 1
+  },
+  {
+   "fieldname": "time",
+   "fieldtype": "Time",
+   "label": "Time"
+  },
+  {
+   "fieldname": "column_break_4",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "comments",
+   "fieldtype": "Small Text",
+   "label": "Comments"
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-04-20 09:56:28.746619",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient Assessment Sheet",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.py b/erpnext/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.py
new file mode 100644
index 0000000..40da763
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_sheet/patient_assessment_sheet.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class PatientAssessmentSheet(Document):
+	pass
diff --git a/erpnext/accounts/doctype/account_subtype/__init__.py b/erpnext/healthcare/doctype/patient_assessment_template/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/account_subtype/__init__.py
copy to erpnext/healthcare/doctype/patient_assessment_template/__init__.py
diff --git a/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.js b/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.js
new file mode 100644
index 0000000..4041936
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Patient Assessment Template', {
+	// refresh: function(frm) {
+
+	// }
+});
diff --git a/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.json b/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.json
new file mode 100644
index 0000000..de006b1
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.json
@@ -0,0 +1,109 @@
+{
+ "actions": [],
+ "autoname": "field:assessment_name",
+ "creation": "2020-04-19 19:33:13.204707",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "assessment_name",
+  "section_break_2",
+  "parameters",
+  "assessment_scale_details_section",
+  "scale_min",
+  "scale_max",
+  "column_break_8",
+  "assessment_description"
+ ],
+ "fields": [
+  {
+   "fieldname": "parameters",
+   "fieldtype": "Table",
+   "label": "Parameters",
+   "options": "Patient Assessment Detail"
+  },
+  {
+   "fieldname": "assessment_name",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Assessment Name",
+   "reqd": 1,
+   "unique": 1
+  },
+  {
+   "fieldname": "section_break_2",
+   "fieldtype": "Section Break",
+   "label": "Assessment Parameters"
+  },
+  {
+   "fieldname": "assessment_scale_details_section",
+   "fieldtype": "Section Break",
+   "label": "Assessment Scale"
+  },
+  {
+   "fieldname": "scale_min",
+   "fieldtype": "Int",
+   "label": "Scale Minimum"
+  },
+  {
+   "fieldname": "scale_max",
+   "fieldtype": "Int",
+   "label": "Scale Maximum"
+  },
+  {
+   "fieldname": "column_break_8",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "assessment_description",
+   "fieldtype": "Small Text",
+   "label": "Assessment Description"
+  }
+ ],
+ "links": [],
+ "modified": "2020-04-21 13:14:19.075167",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Patient Assessment Template",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Healthcare Administrator",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "create": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Physician",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.py b/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.py
new file mode 100644
index 0000000..083cab5
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_template/patient_assessment_template.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class PatientAssessmentTemplate(Document):
+	pass
diff --git a/erpnext/healthcare/doctype/patient_assessment_template/test_patient_assessment_template.py b/erpnext/healthcare/doctype/patient_assessment_template/test_patient_assessment_template.py
new file mode 100644
index 0000000..86dbd54
--- /dev/null
+++ b/erpnext/healthcare/doctype/patient_assessment_template/test_patient_assessment_template.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestPatientAssessmentTemplate(unittest.TestCase):
+	pass
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
index 83c5d2b..78e789d 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.js
@@ -3,6 +3,10 @@
 
 frappe.ui.form.on('Patient Encounter', {
 	setup: function(frm) {
+		frm.get_field('therapies').grid.editable_fields = [
+			{fieldname: 'therapy_type', columns: 8},
+			{fieldname: 'no_of_sessions', columns: 2}
+		];
 		frm.get_field('drug_prescription').grid.editable_fields = [
 			{fieldname: 'drug_code', columns: 2},
 			{fieldname: 'drug_name', columns: 2},
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
index d00e7bc..5f11039 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.json
@@ -42,6 +42,10 @@
   "lab_test_prescription",
   "sb_procedures",
   "procedure_prescription",
+  "rehabilitation_section",
+  "therapy_plan",
+  "therapies",
+  "section_break_33",
   "encounter_comment",
   "amended_from"
  ],
@@ -257,6 +261,29 @@
    "read_only": 1
   },
   {
+   "fieldname": "rehabilitation_section",
+   "fieldtype": "Section Break",
+   "label": "Rehabilitation"
+  },
+  {
+   "fieldname": "therapies",
+   "fieldtype": "Table",
+   "label": "Therapies",
+   "options": "Therapy Plan Detail"
+  },
+  {
+   "fieldname": "section_break_33",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "therapy_plan",
+   "fieldtype": "Link",
+   "hidden": 1,
+   "label": "Therapy Plan",
+   "options": "Therapy Plan",
+   "read_only": 1
+  },
+  {
    "fieldname": "appointment_type",
    "fieldtype": "Link",
    "ignore_user_permissions": 1,
@@ -291,7 +318,7 @@
  ],
  "is_submittable": 1,
  "links": [],
- "modified": "2020-02-27 12:42:21.751964",
+ "modified": "2020-04-14 16:18:08.180457",
  "modified_by": "Administrator",
  "module": "Healthcare",
  "name": "Patient Encounter",
diff --git a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
index ade4748..767643b 100644
--- a/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
+++ b/erpnext/healthcare/doctype/patient_encounter/patient_encounter.py
@@ -4,6 +4,7 @@
 
 from __future__ import unicode_literals
 import frappe
+from frappe import _
 from frappe.model.document import Document
 from frappe.utils import cstr
 from frappe import _
@@ -22,6 +23,24 @@
 			frappe.db.set_value('Patient Appointment', self.appointment, 'status', 'Open')
 		delete_medical_record(self)
 
+	def on_submit(self):
+		create_therapy_plan(self)
+
+def create_therapy_plan(encounter):
+	if len(encounter.therapies):
+		doc = frappe.new_doc('Therapy Plan')
+		doc.patient = encounter.patient
+		doc.start_date = encounter.encounter_date
+		for entry in encounter.therapies:
+			doc.append('therapy_plan_details', {
+				'therapy_type': entry.therapy_type,
+				'no_of_sessions': entry.no_of_sessions
+			})
+		doc.save(ignore_permissions=True)
+		if doc.get('name'):
+			encounter.db_set('therapy_plan', doc.name)
+			frappe.msgprint(_('Therapy Plan {0} created successfully.').format(frappe.bold(doc.name)), alert=True)
+
 def insert_encounter_to_medical_record(doc):
 	subject = set_subject_field(doc)
 	medical_record = frappe.new_doc('Patient Medical Record')
diff --git a/erpnext/accounts/doctype/account_subtype/__init__.py b/erpnext/healthcare/doctype/therapy_plan/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/account_subtype/__init__.py
copy to erpnext/healthcare/doctype/therapy_plan/__init__.py
diff --git a/erpnext/healthcare/doctype/therapy_plan/test_therapy_plan.py b/erpnext/healthcare/doctype/therapy_plan/test_therapy_plan.py
new file mode 100644
index 0000000..526bb95
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan/test_therapy_plan.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+from frappe.utils import getdate
+from erpnext.healthcare.doctype.therapy_type.test_therapy_type import create_therapy_type
+from erpnext.healthcare.doctype.therapy_plan.therapy_plan import make_therapy_session
+from erpnext.healthcare.doctype.patient_appointment.test_patient_appointment import create_healthcare_docs, create_patient
+
+class TestTherapyPlan(unittest.TestCase):
+	def test_creation_on_encounter_submission(self):
+		patient, medical_department, practitioner = create_healthcare_docs()
+		encounter = create_encounter(patient, medical_department, practitioner)
+		self.assertTrue(frappe.db.exists('Therapy Plan', encounter.therapy_plan))
+
+	def test_status(self):
+		plan = create_therapy_plan()
+		self.assertEquals(plan.status, 'Not Started')
+
+		session = make_therapy_session(plan.name, plan.patient, 'Basic Rehab')
+		frappe.get_doc(session).submit()
+		self.assertEquals(frappe.db.get_value('Therapy Plan', plan.name, 'status'), 'In Progress')
+
+		session = make_therapy_session(plan.name, plan.patient, 'Basic Rehab')
+		frappe.get_doc(session).submit()
+		self.assertEquals(frappe.db.get_value('Therapy Plan', plan.name, 'status'), 'Completed')
+
+
+def create_therapy_plan():
+	patient = create_patient()
+	therapy_type = create_therapy_type()
+	plan = frappe.new_doc('Therapy Plan')
+	plan.patient = patient
+	plan.start_date = getdate()
+	plan.append('therapy_plan_details', {
+		'therapy_type': therapy_type.name,
+		'no_of_sessions': 2
+	})
+	plan.save()
+	return plan
+
+def create_encounter(patient, medical_department, practitioner):
+	encounter = frappe.new_doc('Patient Encounter')
+	encounter.patient = patient
+	encounter.practitioner = practitioner
+	encounter.medical_department = medical_department
+	therapy_type = create_therapy_type()
+	encounter.append('therapies', {
+		'therapy_type': therapy_type.name,
+		'no_of_sessions': 2
+	})
+	encounter.save()
+	encounter.submit()
+	return encounter
diff --git a/erpnext/healthcare/doctype/therapy_plan/therapy_plan.js b/erpnext/healthcare/doctype/therapy_plan/therapy_plan.js
new file mode 100644
index 0000000..dea0cfe
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan/therapy_plan.js
@@ -0,0 +1,90 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Therapy Plan', {
+	setup: function(frm) {
+		frm.get_field('therapy_plan_details').grid.editable_fields = [
+			{fieldname: 'therapy_type', columns: 6},
+			{fieldname: 'no_of_sessions', columns: 2},
+			{fieldname: 'sessions_completed', columns: 2}
+		];
+	},
+
+	refresh: function(frm) {
+		if (!frm.doc.__islocal) {
+			frm.trigger('show_progress_for_therapies');
+		}
+
+		if (!frm.doc.__islocal && frm.doc.status != 'Completed') {
+			let therapy_types = (frm.doc.therapy_plan_details || []).map(function(d){ return d.therapy_type });
+			const fields = [{
+				fieldtype: 'Link',
+				label: __('Therapy Type'),
+				fieldname: 'therapy_type',
+				options: 'Therapy Type',
+				reqd: 1,
+				get_query: function() {
+					return {
+						filters: { 'therapy_type': ['in', therapy_types]}
+					}
+				}
+			}];
+
+			frm.add_custom_button(__('Therapy Session'), function() {
+				frappe.prompt(fields, data => {
+					frappe.call({
+						method: 'erpnext.healthcare.doctype.therapy_plan.therapy_plan.make_therapy_session',
+						args: {
+							therapy_plan: frm.doc.name,
+							patient: frm.doc.patient,
+							therapy_type: data.therapy_type
+						},
+						freeze: true,
+						callback: function(r) {
+							if (r.message) {
+								frappe.model.sync(r.message);
+								frappe.set_route('Form', r.message.doctype, r.message.name);
+							}
+						}
+					});
+				}, __('Select Therapy Type'), __('Create'));
+			}, __('Create'));
+		}
+	},
+
+	show_progress_for_therapies: function(frm) {
+		let bars = [];
+		let message = '';
+		let added_min = false;
+
+		// completed sessions
+		let title = __('{0} sessions completed', [frm.doc.total_sessions_completed]);
+		if (frm.doc.total_sessions_completed === 1) {
+			title = __('{0} session completed', [frm.doc.total_sessions_completed]);
+		}
+		title += __(' out of {0}', [frm.doc.total_sessions]);
+
+		bars.push({
+			'title': title,
+			'width': (frm.doc.total_sessions_completed / frm.doc.total_sessions * 100) + '%',
+			'progress_class': 'progress-bar-success'
+		});
+		if (bars[0].width == '0%') {
+			bars[0].width = '0.5%';
+			added_min = 0.5;
+		}
+		message = title;
+		frm.dashboard.add_progress(__('Status'), bars, message);
+	},
+});
+
+frappe.ui.form.on('Therapy Plan Detail', {
+	no_of_sessions: function(frm) {
+		let total = 0;
+		$.each(frm.doc.therapy_plan_details, function(_i, e) {
+			total += e.no_of_sessions;
+		});
+		frm.set_value('total_sessions', total);
+		refresh_field('total_sessions');
+	}
+});
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_plan/therapy_plan.json b/erpnext/healthcare/doctype/therapy_plan/therapy_plan.json
new file mode 100644
index 0000000..ca78b66
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan/therapy_plan.json
@@ -0,0 +1,151 @@
+{
+ "actions": [],
+ "autoname": "naming_series:",
+ "creation": "2020-03-29 20:56:49.758602",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "naming_series",
+  "patient",
+  "patient_name",
+  "column_break_4",
+  "status",
+  "start_date",
+  "section_break_3",
+  "therapy_plan_details",
+  "title",
+  "section_break_9",
+  "total_sessions",
+  "column_break_11",
+  "total_sessions_completed"
+ ],
+ "fields": [
+  {
+   "fieldname": "patient",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Patient",
+   "options": "Patient",
+   "reqd": 1
+  },
+  {
+   "fieldname": "start_date",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "label": "Start Date",
+   "reqd": 1
+  },
+  {
+   "fieldname": "section_break_3",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "therapy_plan_details",
+   "fieldtype": "Table",
+   "label": "Therapy Plan Details",
+   "options": "Therapy Plan Detail",
+   "reqd": 1
+  },
+  {
+   "fieldname": "naming_series",
+   "fieldtype": "Select",
+   "label": "Naming Series",
+   "options": "HLC-THP-.YYYY.-"
+  },
+  {
+   "fetch_from": "patient.patient_name",
+   "fieldname": "patient_name",
+   "fieldtype": "Data",
+   "label": "Patient Name",
+   "read_only": 1
+  },
+  {
+   "default": "{patient_name}",
+   "fieldname": "title",
+   "fieldtype": "Data",
+   "hidden": 1,
+   "label": "Title",
+   "no_copy": 1
+  },
+  {
+   "fieldname": "column_break_4",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "section_break_9",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "total_sessions",
+   "fieldtype": "Int",
+   "label": "Total Sessions",
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_11",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "total_sessions_completed",
+   "fieldtype": "Int",
+   "label": "Total Sessions Completed",
+   "read_only": 1
+  },
+  {
+   "fieldname": "status",
+   "fieldtype": "Select",
+   "label": "Status",
+   "options": "Not Started\nIn Progress\nCompleted\nCancelled",
+   "read_only": 1
+  }
+ ],
+ "links": [],
+ "modified": "2020-04-21 13:13:43.956014",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Therapy Plan",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Healthcare Administrator",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Physician",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "search_fields": "patient",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "patient",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_plan/therapy_plan.py b/erpnext/healthcare/doctype/therapy_plan/therapy_plan.py
new file mode 100644
index 0000000..201264f
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan/therapy_plan.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+
+class TherapyPlan(Document):
+	def validate(self):
+		self.set_totals()
+		self.set_status()
+
+	def set_status(self):
+		if not self.total_sessions_completed:
+			self.status = 'Not Started'
+		else:
+			if self.total_sessions_completed < self.total_sessions:
+				self.status = 'In Progress'
+			elif self.total_sessions_completed == self.total_sessions:
+				self.status = 'Completed'
+
+	def set_totals(self):
+		total_sessions = sum([int(d.no_of_sessions) for d in self.get('therapy_plan_details')])
+		total_sessions_completed = sum([int(d.sessions_completed) for d in self.get('therapy_plan_details')])
+		self.db_set('total_sessions', total_sessions)
+		self.db_set('total_sessions_completed', total_sessions_completed)
+
+
+@frappe.whitelist()
+def make_therapy_session(therapy_plan, patient, therapy_type):
+	therapy_type = frappe.get_doc('Therapy Type', therapy_type)
+
+	therapy_session = frappe.new_doc('Therapy Session')
+	therapy_session.therapy_plan = therapy_plan
+	therapy_session.patient = patient
+	therapy_session.therapy_type = therapy_type.name
+	therapy_session.duration = therapy_type.default_duration
+	therapy_session.rate = therapy_type.rate
+	therapy_session.exercises = therapy_type.exercises
+
+	return therapy_session.as_dict()
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_plan/therapy_plan_dashboard.py b/erpnext/healthcare/doctype/therapy_plan/therapy_plan_dashboard.py
new file mode 100644
index 0000000..df64782
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan/therapy_plan_dashboard.py
@@ -0,0 +1,13 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+	return {
+		'fieldname': 'therapy_plan',
+		'transactions': [
+			{
+				'label': _('Therapy Sessions'),
+				'items': ['Therapy Session']
+			}
+		]
+	}
diff --git a/erpnext/healthcare/doctype/therapy_plan/therapy_plan_list.js b/erpnext/healthcare/doctype/therapy_plan/therapy_plan_list.js
new file mode 100644
index 0000000..63967af
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan/therapy_plan_list.js
@@ -0,0 +1,11 @@
+frappe.listview_settings['Therapy Plan'] = {
+	get_indicator: function(doc) {
+		var colors = {
+			'Completed': 'green',
+			'In Progress': 'orange',
+			'Not Started': 'red',
+			'Cancelled': 'grey'
+		};
+		return [__(doc.status), colors[doc.status], 'status,=,' + doc.status];
+	}
+};
diff --git a/erpnext/accounts/doctype/account_subtype/__init__.py b/erpnext/healthcare/doctype/therapy_plan_detail/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/account_subtype/__init__.py
copy to erpnext/healthcare/doctype/therapy_plan_detail/__init__.py
diff --git a/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.json b/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.json
new file mode 100644
index 0000000..9eb20e2
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.json
@@ -0,0 +1,48 @@
+{
+ "actions": [],
+ "creation": "2020-03-29 20:52:57.068731",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "therapy_type",
+  "no_of_sessions",
+  "sessions_completed"
+ ],
+ "fields": [
+  {
+   "fieldname": "therapy_type",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Therapy Type",
+   "options": "Therapy Type",
+   "reqd": 1
+  },
+  {
+   "fieldname": "no_of_sessions",
+   "fieldtype": "Int",
+   "in_list_view": 1,
+   "label": "No of Sessions"
+  },
+  {
+   "default": "0",
+   "depends_on": "eval:doc.parenttype=='Therapy Plan';",
+   "fieldname": "sessions_completed",
+   "fieldtype": "Int",
+   "label": "Sessions Completed",
+   "read_only": 1
+  }
+ ],
+ "istable": 1,
+ "links": [],
+ "modified": "2020-03-30 22:02:01.740109",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Therapy Plan Detail",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.py b/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.py
new file mode 100644
index 0000000..44211f3
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_plan_detail/therapy_plan_detail.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+# import frappe
+from frappe.model.document import Document
+
+class TherapyPlanDetail(Document):
+	pass
diff --git a/erpnext/accounts/doctype/account_subtype/__init__.py b/erpnext/healthcare/doctype/therapy_session/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/account_subtype/__init__.py
copy to erpnext/healthcare/doctype/therapy_session/__init__.py
diff --git a/erpnext/healthcare/doctype/therapy_session/test_therapy_session.py b/erpnext/healthcare/doctype/therapy_session/test_therapy_session.py
new file mode 100644
index 0000000..75bb8df
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_session/test_therapy_session.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestTherapySession(unittest.TestCase):
+	pass
diff --git a/erpnext/healthcare/doctype/therapy_session/therapy_session.js b/erpnext/healthcare/doctype/therapy_session/therapy_session.js
new file mode 100644
index 0000000..bb67575
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_session/therapy_session.js
@@ -0,0 +1,60 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Therapy Session', {
+	setup: function(frm) {
+		frm.get_field('exercises').grid.editable_fields = [
+			{fieldname: 'exercise_type', columns: 7},
+			{fieldname: 'counts_target', columns: 1},
+			{fieldname: 'counts_completed', columns: 1},
+			{fieldname: 'assistance_level', columns: 1}
+		];
+	},
+
+	refresh: function(frm) {
+		if (!frm.doc.__islocal) {
+			let target = 0;
+			let completed = 0;
+			$.each(frm.doc.exercises, function(_i, e) {
+				target += e.counts_target;
+				completed += e.counts_completed;
+			});
+			frm.dashboard.add_indicator(__('Counts Targetted: {0}', [target]), 'blue');
+			frm.dashboard.add_indicator(__('Counts Completed: {0}', [completed]), (completed < target) ? 'orange' : 'green');
+		}
+
+		if (frm.doc.docstatus === 1) {
+			frm.add_custom_button(__('Patient Assessment'),function() {
+				frappe.model.open_mapped_doc({
+					method: 'erpnext.healthcare.doctype.patient_assessment.patient_assessment.create_patient_assessment',
+					frm: frm,
+				})
+			}, 'Create');
+		}
+	},
+
+	therapy_type: function(frm) {
+		if (frm.doc.therapy_type) {
+			frappe.call({
+				'method': 'frappe.client.get',
+				args: {
+					doctype: 'Therapy Type',
+					name: frm.doc.therapy_type
+				},
+				callback: function(data) {
+					frm.set_value('duration', data.message.default_duration);
+					frm.set_value('rate', data.message.rate);
+					frm.doc.exercises = [];
+					$.each(data.message.exercises, function(_i, e) {
+						let exercise = frm.add_child('exercises');
+						exercise.exercise_type = e.exercise_type;
+						exercise.difficulty_level = e.difficulty_level;
+						exercise.counts_target = e.counts_target;
+						exercise.assistance_level = e.assistance_level;
+					});
+					refresh_field('exercises');
+				}
+			});
+		}
+	}
+});
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_session/therapy_session.json b/erpnext/healthcare/doctype/therapy_session/therapy_session.json
new file mode 100644
index 0000000..5ff7196
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_session/therapy_session.json
@@ -0,0 +1,218 @@
+{
+ "actions": [],
+ "autoname": "naming_series:",
+ "creation": "2020-03-11 08:57:40.669857",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "naming_series",
+  "appointment",
+  "patient",
+  "patient_age",
+  "gender",
+  "column_break_5",
+  "therapy_plan",
+  "therapy_type",
+  "practitioner",
+  "department",
+  "details_section",
+  "duration",
+  "rate",
+  "location",
+  "company",
+  "column_break_12",
+  "service_unit",
+  "start_date",
+  "start_time",
+  "invoiced",
+  "exercises_section",
+  "exercises",
+  "amended_from"
+ ],
+ "fields": [
+  {
+   "fieldname": "naming_series",
+   "fieldtype": "Select",
+   "label": "Series",
+   "options": "HLC-THP-.YYYY.-"
+  },
+  {
+   "fieldname": "appointment",
+   "fieldtype": "Link",
+   "label": "Appointment",
+   "options": "Patient Appointment"
+  },
+  {
+   "fieldname": "patient",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Patient",
+   "options": "Patient",
+   "reqd": 1
+  },
+  {
+   "fetch_from": "patient.sex",
+   "fieldname": "gender",
+   "fieldtype": "Link",
+   "label": "Gender",
+   "options": "Gender",
+   "read_only": 1
+  },
+  {
+   "fieldname": "column_break_5",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "practitioner",
+   "fieldtype": "Link",
+   "label": "Healthcare Practitioner",
+   "options": "Healthcare Practitioner"
+  },
+  {
+   "fieldname": "department",
+   "fieldtype": "Link",
+   "label": "Medical Department",
+   "options": "Medical Department"
+  },
+  {
+   "fieldname": "details_section",
+   "fieldtype": "Section Break",
+   "label": "Details"
+  },
+  {
+   "fetch_from": "therapy_template.default_duration",
+   "fieldname": "duration",
+   "fieldtype": "Int",
+   "label": "Duration"
+  },
+  {
+   "fieldname": "location",
+   "fieldtype": "Select",
+   "label": "Location",
+   "options": "\nCenter\nHome\nTele"
+  },
+  {
+   "fieldname": "column_break_12",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fetch_from": "therapy_template.rate",
+   "fieldname": "rate",
+   "fieldtype": "Currency",
+   "label": "Rate"
+  },
+  {
+   "fieldname": "exercises_section",
+   "fieldtype": "Section Break",
+   "label": "Exercises"
+  },
+  {
+   "fieldname": "exercises",
+   "fieldtype": "Table",
+   "label": "Exercises",
+   "options": "Exercise"
+  },
+  {
+   "depends_on": "eval: doc.therapy_plan",
+   "fieldname": "therapy_type",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Therapy Type",
+   "options": "Therapy Type",
+   "reqd": 1
+  },
+  {
+   "fieldname": "therapy_plan",
+   "fieldtype": "Link",
+   "label": "Therapy Plan",
+   "options": "Therapy Plan",
+   "reqd": 1,
+   "set_only_once": 1
+  },
+  {
+   "fieldname": "amended_from",
+   "fieldtype": "Link",
+   "label": "Amended From",
+   "no_copy": 1,
+   "options": "Therapy Session",
+   "print_hide": 1,
+   "read_only": 1
+  },
+  {
+   "fieldname": "service_unit",
+   "fieldtype": "Link",
+   "label": "Healthcare Service Unit",
+   "options": "Healthcare Service Unit"
+  },
+  {
+   "fieldname": "start_date",
+   "fieldtype": "Date",
+   "label": "Start Date"
+  },
+  {
+   "fieldname": "start_time",
+   "fieldtype": "Time",
+   "label": "Start Time"
+  },
+  {
+   "fieldname": "company",
+   "fieldtype": "Link",
+   "label": "Company",
+   "options": "Company"
+  },
+  {
+   "default": "0",
+   "fieldname": "invoiced",
+   "fieldtype": "Check",
+   "label": "Invoiced",
+   "read_only": 1
+  },
+  {
+   "fieldname": "patient_age",
+   "fieldtype": "Data",
+   "label": "Patient Age",
+   "read_only": 1
+  }
+ ],
+ "is_submittable": 1,
+ "links": [],
+ "modified": "2020-04-21 13:16:46.378798",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Therapy Session",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "cancel": 1,
+   "create": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Physician",
+   "share": 1,
+   "submit": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "search_fields": "patient,appointment,therapy_plan,therapy_type",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "patient",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_session/therapy_session.py b/erpnext/healthcare/doctype/therapy_session/therapy_session.py
new file mode 100644
index 0000000..45d2ee6
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_session/therapy_session.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+from frappe.model.mapper import get_mapped_doc
+
+class TherapySession(Document):
+	def on_submit(self):
+		self.update_sessions_count_in_therapy_plan()
+
+	def on_cancel(self):
+		self.update_sessions_count_in_therapy_plan(on_cancel=True)
+
+	def update_sessions_count_in_therapy_plan(self, on_cancel=False):
+		therapy_plan = frappe.get_doc('Therapy Plan', self.therapy_plan)
+		for entry in therapy_plan.therapy_plan_details:
+			if entry.therapy_type == self.therapy_type:
+				if on_cancel:
+					entry.sessions_completed -= 1
+				else:
+					entry.sessions_completed += 1
+		therapy_plan.save()
+
+
+@frappe.whitelist()
+def create_therapy_session(source_name, target_doc=None):
+	def set_missing_values(source, target):
+		therapy_type = frappe.get_doc('Therapy Type', source.therapy_type)
+		target.exercises = therapy_type.exercises
+
+	doc = get_mapped_doc('Patient Appointment', source_name, {
+			'Patient Appointment': {
+				'doctype': 'Therapy Session',
+				'field_map': [
+					['appointment', 'name'],
+					['patient', 'patient'],
+					['patient_age', 'patient_age'],
+					['gender', 'patient_sex'],
+					['therapy_type', 'therapy_type'],
+					['therapy_plan', 'therapy_plan'],
+					['practitioner', 'practitioner'],
+					['department', 'department'],
+					['start_date', 'appointment_date'],
+					['start_time', 'appointment_time'],
+					['service_unit', 'service_unit'],
+					['company', 'company'],
+					['invoiced', 'invoiced']
+				]
+			}
+		}, target_doc, set_missing_values)
+
+	return doc
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_session/therapy_session_dashboard.py b/erpnext/healthcare/doctype/therapy_session/therapy_session_dashboard.py
new file mode 100644
index 0000000..9de7e29
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_session/therapy_session_dashboard.py
@@ -0,0 +1,13 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+	return {
+		'fieldname': 'therapy_session',
+		'transactions': [
+			{
+				'label': _('Assessments'),
+				'items': ['Patient Assessment']
+			}
+		]
+	}
diff --git a/erpnext/accounts/doctype/account_type/__init__.py b/erpnext/healthcare/doctype/therapy_type/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/account_type/__init__.py
copy to erpnext/healthcare/doctype/therapy_type/__init__.py
diff --git a/erpnext/healthcare/doctype/therapy_type/test_therapy_type.py b/erpnext/healthcare/doctype/therapy_type/test_therapy_type.py
new file mode 100644
index 0000000..03a1be8
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_type/test_therapy_type.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestTherapyType(unittest.TestCase):
+	def test_therapy_type_item(self):
+		therapy_type = create_therapy_type()
+		self.assertTrue(frappe.db.exists('Item', therapy_type.item))
+
+		therapy_type.disabled = 1
+		therapy_type.save()
+		self.assertEquals(frappe.db.get_value('Item', therapy_type.item, 'disabled'), 1)
+
+def create_therapy_type():
+	exercise = create_exercise_type()
+	therapy_type = frappe.db.exists('Therapy Type', 'Basic Rehab')
+	if not therapy_type:
+		therapy_type = frappe.new_doc('Therapy Type')
+		therapy_type.therapy_type = 'Basic Rehab'
+		therapy_type.default_duration = 30
+		therapy_type.is_billable = 1
+		therapy_type.rate = 5000
+		therapy_type.item_code = 'Basic Rehab'
+		therapy_type.item_name = 'Basic Rehab'
+		therapy_type.item_group = 'Services'
+		therapy_type.append('exercises', {
+			'exercise_type': exercise.name,
+			'counts_target': 10,
+			'assistance_level': 'Passive'
+		})
+		therapy_type.save()
+	else:
+		therapy_type = frappe.get_doc('Therapy Type', 'Basic Rehab')
+	return therapy_type
+
+def create_exercise_type():
+	exercise_type = frappe.db.exists('Exercise Type', 'Sit to Stand')
+	if not exercise_type:
+		exercise_type = frappe.new_doc('Exercise Type')
+		exercise_type.exercise_name = 'Sit to Stand'
+		exercise_type.append('steps_table', {
+			'title': 'Step 1',
+			'description': 'Squat and Rise'
+		})
+		exercise_type.save()
+	return exercise_type
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_type/therapy_type.js b/erpnext/healthcare/doctype/therapy_type/therapy_type.js
new file mode 100644
index 0000000..7a61b0d
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_type/therapy_type.js
@@ -0,0 +1,93 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Therapy Type', {
+	setup: function(frm) {
+		frm.get_field('exercises').grid.editable_fields = [
+			{fieldname: 'exercise_type', columns: 7},
+			{fieldname: 'difficulty_level', columns: 1},
+			{fieldname: 'counts_target', columns: 1},
+			{fieldname: 'assistance_level', columns: 1}
+		];
+	},
+
+	refresh: function(frm) {
+		if (!frm.doc.__islocal) {
+			cur_frm.add_custom_button(__('Change Item Code'), function() {
+				change_template_code(frm.doc);
+			});
+		}
+	},
+
+	therapy_type: function(frm) {
+		if (!frm.doc.item_code)
+			frm.set_value('item_code', frm.doc.therapy_type);
+		if (!frm.doc.description)
+			frm.set_value('description', frm.doc.therapy_type);
+		mark_change_in_item(frm);
+	},
+
+	rate: function(frm) {
+		mark_change_in_item(frm);
+	},
+
+	is_billable: function (frm) {
+		mark_change_in_item(frm);
+	},
+
+	item_group: function(frm) {
+		mark_change_in_item(frm);
+	},
+
+	description: function(frm) {
+		mark_change_in_item(frm);
+	},
+
+	medical_department: function(frm) {
+		mark_change_in_item(frm);
+	}
+});
+
+let mark_change_in_item = function(frm) {
+	if (!frm.doc.__islocal) {
+		frm.doc.change_in_item = 1;
+	}
+};
+
+let change_template_code = function(doc) {
+	let d = new frappe.ui.Dialog({
+		title:__('Change Item Code'),
+		fields:[
+			{
+				'fieldtype': 'Data',
+				'label': 'Item Code',
+				'fieldname': 'item_code',
+				reqd: 1
+			}
+		],
+		primary_action: function() {
+			let values = d.get_values();
+
+			if (values) {
+				frappe.call({
+					'method': 'erpnext.healthcare.doctype.therapy_type.therapy_type.change_item_code_from_therapy',
+					'args': {item_code: values.item_code, doc: doc},
+					callback: function () {
+						cur_frm.reload_doc();
+						frappe.show_alert({
+							message: 'Item Code renamed successfully',
+							indicator: 'green'
+						});
+					}
+				});
+			}
+			d.hide();
+		},
+		primary_action_label: __('Change Item Code')
+	});
+	d.show();
+
+	d.set_values({
+		'item_code': doc.item_code
+	});
+};
diff --git a/erpnext/healthcare/doctype/therapy_type/therapy_type.json b/erpnext/healthcare/doctype/therapy_type/therapy_type.json
new file mode 100644
index 0000000..0b3c3ca
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_type/therapy_type.json
@@ -0,0 +1,211 @@
+{
+ "actions": [],
+ "autoname": "field:therapy_type",
+ "creation": "2020-03-29 20:48:31.715063",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "disabled",
+  "section_break_2",
+  "therapy_type",
+  "default_duration",
+  "medical_department",
+  "column_break_3",
+  "is_billable",
+  "rate",
+  "healthcare_service_unit",
+  "item_details_section",
+  "item",
+  "item_code",
+  "item_name",
+  "item_group",
+  "column_break_12",
+  "description",
+  "section_break_18",
+  "therapy_for",
+  "add_exercises",
+  "section_break_6",
+  "exercises",
+  "change_in_item"
+ ],
+ "fields": [
+  {
+   "fieldname": "therapy_type",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Therapy Type",
+   "reqd": 1,
+   "unique": 1
+  },
+  {
+   "fieldname": "column_break_3",
+   "fieldtype": "Column Break"
+  },
+  {
+   "default": "0",
+   "fieldname": "is_billable",
+   "fieldtype": "Check",
+   "label": "Is Billable"
+  },
+  {
+   "depends_on": "eval:doc.is_billable;",
+   "fieldname": "rate",
+   "fieldtype": "Currency",
+   "label": "Rate",
+   "mandatory_depends_on": "eval:doc.is_billable;"
+  },
+  {
+   "fieldname": "section_break_6",
+   "fieldtype": "Section Break",
+   "label": "Exercises"
+  },
+  {
+   "fieldname": "exercises",
+   "fieldtype": "Table",
+   "label": "Exercises",
+   "options": "Exercise"
+  },
+  {
+   "fieldname": "default_duration",
+   "fieldtype": "Int",
+   "label": "Default Duration (In Minutes)"
+  },
+  {
+   "default": "0",
+   "fieldname": "disabled",
+   "fieldtype": "Check",
+   "label": "Disabled"
+  },
+  {
+   "fieldname": "item_details_section",
+   "fieldtype": "Section Break",
+   "label": "Item Details"
+  },
+  {
+   "fieldname": "item",
+   "fieldtype": "Link",
+   "label": "Item",
+   "options": "Item",
+   "read_only": 1
+  },
+  {
+   "fieldname": "item_code",
+   "fieldtype": "Data",
+   "label": "Item Code",
+   "reqd": 1,
+   "set_only_once": 1
+  },
+  {
+   "fieldname": "item_group",
+   "fieldtype": "Link",
+   "label": "Item Group",
+   "options": "Item Group",
+   "reqd": 1
+  },
+  {
+   "fieldname": "item_name",
+   "fieldtype": "Data",
+   "label": "Item Name",
+   "reqd": 1
+  },
+  {
+   "fieldname": "column_break_12",
+   "fieldtype": "Column Break"
+  },
+  {
+   "fieldname": "description",
+   "fieldtype": "Small Text",
+   "label": "Description"
+  },
+  {
+   "fieldname": "section_break_2",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "medical_department",
+   "fieldtype": "Link",
+   "label": "Medical Department",
+   "options": "Medical Department"
+  },
+  {
+   "default": "0",
+   "fieldname": "change_in_item",
+   "fieldtype": "Check",
+   "hidden": 1,
+   "label": "Change In Item",
+   "print_hide": 1,
+   "read_only": 1,
+   "report_hide": 1
+  },
+  {
+   "fieldname": "therapy_for",
+   "fieldtype": "Table MultiSelect",
+   "label": "Therapy For",
+   "options": "Body Part Link"
+  },
+  {
+   "fieldname": "healthcare_service_unit",
+   "fieldtype": "Link",
+   "label": "Healthcare Service Unit",
+   "options": "Healthcare Service Unit"
+  },
+  {
+   "depends_on": "eval: doc.therapy_for",
+   "fieldname": "add_exercises",
+   "fieldtype": "Button",
+   "label": "Add Exercises",
+   "options": "add_exercises"
+  },
+  {
+   "fieldname": "section_break_18",
+   "fieldtype": "Section Break"
+  }
+ ],
+ "links": [],
+ "modified": "2020-04-21 13:09:04.006289",
+ "modified_by": "Administrator",
+ "module": "Healthcare",
+ "name": "Therapy Type",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Healthcare Administrator",
+   "share": 1,
+   "write": 1
+  },
+  {
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Physician",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/healthcare/doctype/therapy_type/therapy_type.py b/erpnext/healthcare/doctype/therapy_type/therapy_type.py
new file mode 100644
index 0000000..ea3d84e
--- /dev/null
+++ b/erpnext/healthcare/doctype/therapy_type/therapy_type.py
@@ -0,0 +1,122 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+import json
+from frappe import _
+from frappe.utils import cint
+from frappe.model.document import Document
+from frappe.model.rename_doc import rename_doc
+
+class TherapyType(Document):
+	def validate(self):
+		self.enable_disable_item()
+
+	def after_insert(self):
+		create_item_from_therapy(self)
+
+	def on_update(self):
+		if self.change_in_item:
+			self.update_item_and_item_price()
+
+	def enable_disable_item(self):
+		if self.is_billable:
+			if self.disabled:
+				frappe.db.set_value('Item', self.item, 'disabled', 1)
+			else:
+				frappe.db.set_value('Item', self.item, 'disabled', 0)
+
+	def update_item_and_item_price(self):
+		if self.is_billable and self.item:
+			item_doc = frappe.get_doc('Item', {'item_code': self.item})
+			item_doc.item_name = self.item_name
+			item_doc.item_group = self.item_group
+			item_doc.description = self.description
+			item_doc.disabled = 0
+			item_doc.ignore_mandatory = True
+			item_doc.save(ignore_permissions=True)
+
+			if self.rate:
+				item_price = frappe.get_doc('Item Price', {'item_code': self.item})
+				item_price.item_name = self.item_name
+				item_price.price_list_name = self.rate
+				item_price.ignore_mandatory = True
+				item_price.save()
+
+		elif not self.is_billable and self.item:
+			frappe.db.set_value('Item', self.item, 'disabled', 1)
+
+		self.db_set('change_in_item', 0)
+
+	def add_exercises(self):
+		exercises = self.get_exercises_for_body_parts()
+		last_idx = max([cint(d.idx) for d in self.get('exercises')] or [0,])
+		for i, d in enumerate(exercises):
+			ch = self.append('exercises', {})
+			ch.exercise_type = d.parent
+			ch.idx = last_idx + i + 1
+
+	def get_exercises_for_body_parts(self):
+		body_parts = [entry.body_part for entry in self.therapy_for]
+
+		exercises = frappe.db.sql(
+			"""
+				SELECT DISTINCT
+					b.parent, e.name, e.difficulty_level
+				FROM
+				 	`tabExercise Type` e, `tabBody Part Link` b
+				WHERE
+					b.body_part IN %(body_parts)s AND b.parent=e.name
+			""", {'body_parts': body_parts}, as_dict=1)
+
+		return exercises
+
+
+def create_item_from_therapy(doc):
+	disabled = doc.disabled
+	if doc.is_billable and not doc.disabled:
+		disabled = 0
+
+	uom = frappe.db.exists('UOM', 'Unit') or frappe.db.get_single_value('Stock Settings', 'stock_uom')
+
+	item = frappe.get_doc({
+		'doctype': 'Item',
+		'item_code': doc.item_code,
+		'item_name': doc.item_name,
+		'item_group': doc.item_group,
+		'description': doc.description,
+		'is_sales_item': 1,
+		'is_service_item': 1,
+		'is_purchase_item': 0,
+		'is_stock_item': 0,
+		'show_in_website': 0,
+		'is_pro_applicable': 0,
+		'disabled': disabled,
+		'stock_uom': uom
+	}).insert(ignore_permissions=True, ignore_mandatory=True)
+
+	make_item_price(item.name, doc.rate)
+	doc.db_set('item', item.name)
+
+
+def make_item_price(item, item_price):
+	price_list_name = frappe.db.get_value('Price List', {'selling': 1})
+	frappe.get_doc({
+		'doctype': 'Item Price',
+		'price_list': price_list_name,
+		'item_code': item,
+		'price_list_rate': item_price
+	}).insert(ignore_permissions=True, ignore_mandatory=True)
+
+@frappe.whitelist()
+def change_item_code_from_therapy(item_code, doc):
+	doc = frappe._dict(json.loads(doc))
+
+	if frappe.db.exists('Item', {'item_code': item_code}):
+		frappe.throw(_('Item with Item Code {0} already exists').format(item_code))
+	else:
+		rename_doc('Item', doc.item, item_code, ignore_permissions=True)
+		frappe.db.set_value('Therapy Type', doc.name, 'item_code', item_code)
+	return
diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py
index 246242a..9a32c73 100644
--- a/erpnext/healthcare/utils.py
+++ b/erpnext/healthcare/utils.py
@@ -30,8 +30,9 @@
 		lab_tests = get_lab_tests_to_invoice(patient)
 		clinical_procedures = get_clinical_procedures_to_invoice(patient)
 		inpatient_services = get_inpatient_services_to_invoice(patient)
+		therapy_sessions = get_therapy_sessions_to_invoice(patient)
 
-		items_to_invoice += encounters + lab_tests + clinical_procedures + inpatient_services
+		items_to_invoice += encounters + lab_tests + clinical_procedures + inpatient_services + therapy_sessions
 		return items_to_invoice
 
 def validate_customer_created(patient):
@@ -243,6 +244,25 @@
 	return services_to_invoice
 
 
+def get_therapy_sessions_to_invoice(patient):
+	therapy_sessions_to_invoice = []
+	therapy_sessions = frappe.get_list(
+		'Therapy Session',
+		fields='*',
+		filters={'patient': patient.name, 'invoiced': False}
+	)
+	for therapy in therapy_sessions:
+		if not therapy.appointment:
+			if therapy.therapy_type and frappe.db.get_value('Therapy Type', therapy.therapy_type, 'is_billable'):
+				therapy_sessions_to_invoice.append({
+					'reference_type': 'Therapy Session',
+					'reference_name': therapy.name,
+					'service': frappe.db.get_value('Therapy Type', therapy.therapy_type, 'item')
+				})
+
+	return therapy_sessions_to_invoice
+
+
 def get_service_item_and_practitioner_charge(doc):
 	is_inpatient = doc.inpatient_record
 	if is_inpatient:
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 412b5a2..e6f6c8e 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -270,7 +270,7 @@
 scheduler_events = {
 	"all": [
 		"erpnext.projects.doctype.project.project.project_status_update_reminder",
-		"erpnext.healthcare_healthcare.doctype.patient_appointment.patient_appointment.send_appointment_reminder",
+		"erpnext.healthcare.doctype.patient_appointment.patient_appointment.send_appointment_reminder",
 		"erpnext.crm.doctype.social_media_post.social_media_post.process_scheduled_social_media_posts"
 	],
 	"hourly": [
diff --git a/erpnext/hr/doctype/upload_attendance/upload_attendance.py b/erpnext/hr/doctype/upload_attendance/upload_attendance.py
index 1707e35..f75bb41 100644
--- a/erpnext/hr/doctype/upload_attendance/upload_attendance.py
+++ b/erpnext/hr/doctype/upload_attendance/upload_attendance.py
@@ -9,6 +9,8 @@
 from frappe import _
 from frappe.utils.csvutils import UnicodeWriter
 from frappe.model.document import Document
+from erpnext.hr.doctype.employee.employee import get_holiday_list_for_employee
+from erpnext.hr.utils import get_holidays_for_employee
 
 class UploadAttendance(Document):
 	pass
@@ -48,6 +50,7 @@
 def get_data(args):
 	dates = get_dates(args)
 	employees = get_active_employees()
+	holidays = get_holidays_for_employees([employee.name for employee in employees], args["from_date"], args["to_date"])
 	existing_attendance_records = get_existing_attendance_records(args)
 	data = []
 	for date in dates:
@@ -63,6 +66,9 @@
 				and getdate(employee.date_of_joining) <= getdate(date) \
 				and getdate(employee.relieving_date) >= getdate(date):
 					existing_attendance = existing_attendance_records[tuple([getdate(date), employee.name])]
+
+			employee_holiday_list = get_holiday_list_for_employee(employee.name)
+
 			row = [
 				existing_attendance and existing_attendance.name or "",
 				employee.name, employee.employee_name, date,
@@ -70,9 +76,22 @@
 				existing_attendance and existing_attendance.leave_type or "", employee.company,
 				existing_attendance and existing_attendance.naming_series or get_naming_series(),
 			]
+			if date in holidays[employee_holiday_list]:
+				row[4] =  "Holiday"
 			data.append(row)
+
 	return data
 
+def get_holidays_for_employees(employees, from_date, to_date):
+	holidays = {}
+	for employee in employees:
+		holiday_list = get_holiday_list_for_employee(employee)
+		holiday = get_holidays_for_employee(employee, getdate(from_date), getdate(to_date))
+		if holiday_list not in holidays:
+			holidays[holiday_list] = holiday
+
+	return holidays
+
 def writedata(w, data):
 	for row in data:
 		w.writerow(row)
@@ -123,6 +142,11 @@
 	frappe.enqueue(import_attendances, rows=rows, now=True if len(rows) < 200 else False)
 
 def import_attendances(rows):
+
+	def remove_holidays(rows):
+		rows = [ row for row in rows if row[4] != "Holiday"]
+		return
+
 	from frappe.modules import scrub
 
 	rows = list(filter(lambda x: x and any(x), rows))
@@ -133,6 +157,8 @@
 	ret = []
 	error = False
 
+	rows = remove_holidays(rows)
+
 	from frappe.utils.csvutils import check_record, import_doc
 
 	for i, row in enumerate(rows):
diff --git a/erpnext/loan_management/doctype/loan_application/loan_application.js b/erpnext/loan_management/doctype/loan_application/loan_application.js
index aba5f42..6cf47bf 100644
--- a/erpnext/loan_management/doctype/loan_application/loan_application.js
+++ b/erpnext/loan_management/doctype/loan_application/loan_application.js
@@ -31,7 +31,7 @@
 	add_toolbar_buttons: function(frm) {
 		if (frm.doc.status == "Approved") {
 
-			if (frm.doc.is_secured) {
+			if (frm.doc.is_secured_loan) {
 				frappe.db.get_value("Loan Security Pledge", {"loan_application": frm.doc.name, "docstatus": 1}, "name", (r) => {
 					if (!r) {
 						frm.add_custom_button(__('Loan Security Pledge'), function() {
diff --git a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
index 2918486..c9e36a8 100644
--- a/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
+++ b/erpnext/loan_management/doctype/loan_disbursement/loan_disbursement.py
@@ -84,7 +84,7 @@
 		gle_map.append(
 			self.get_gl_dict({
 				"account": loan_details.loan_account,
-				"against": loan_details.applicant,
+				"against": loan_details.payment_account,
 				"debit": self.disbursed_amount,
 				"debit_in_account_currency": self.disbursed_amount,
 				"against_voucher_type": "Loan",
@@ -100,7 +100,7 @@
 		gle_map.append(
 			self.get_gl_dict({
 				"account": loan_details.payment_account,
-				"against": loan_details.applicant,
+				"against": loan_details.loan_account,
 				"credit": self.disbursed_amount,
 				"credit_in_account_currency": self.disbursed_amount,
 				"against_voucher_type": "Loan",
diff --git a/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.py b/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.py
index b405cca..eb61358 100644
--- a/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.py
+++ b/erpnext/loan_management/doctype/loan_security_pledge/loan_security_pledge.py
@@ -30,7 +30,8 @@
 			if not pledge.qty and not pledge.amount:
 				frappe.throw(_("Qty or Amount is mandatroy for loan security"))
 
-			pledge.loan_security_price = get_loan_security_price(pledge.loan_security)
+			if not (self.loan_application and pledge.loan_security_price):
+				pledge.loan_security_price = get_loan_security_price(pledge.loan_security)
 
 			if not pledge.qty:
 				pledge.qty = cint(pledge.amount/pledge.loan_security_price)
diff --git a/erpnext/loan_management/doctype/loan_security_price/loan_security_price.py b/erpnext/loan_management/doctype/loan_security_price/loan_security_price.py
index 2855b52..32d81af 100644
--- a/erpnext/loan_management/doctype/loan_security_price/loan_security_price.py
+++ b/erpnext/loan_management/doctype/loan_security_price/loan_security_price.py
@@ -37,7 +37,7 @@
 	}, 'loan_security_price')
 
 	if not loan_security_price:
-		frappe.throw(_("No valid <b>Loan Security Price</b> found for {0}").format(frappe.bold(loan_security)))
+		frappe.throw(_("No valid Loan Security Price found for {0}").format(frappe.bold(loan_security)))
 	else:
 		return loan_security_price
 
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 6ccd12a..b1fc4de 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -193,7 +193,7 @@
 					if self.rm_cost_as_per == 'Valuation Rate':
 						rate = self.get_valuation_rate(arg) * (arg.get("conversion_factor") or 1)
 					elif self.rm_cost_as_per == 'Last Purchase Rate':
-						rate = (arg.get('last_purchase_rate') \
+						rate = flt(arg.get('last_purchase_rate') \
 							or frappe.db.get_value("Item", arg['item_code'], "last_purchase_rate")) \
 								* (arg.get("conversion_factor") or 1)
 					elif self.rm_cost_as_per == "Price List":
@@ -246,12 +246,13 @@
 			if rate:
 				d.rate = rate
 			d.amount = flt(d.rate) * flt(d.qty)
+			d.db_update()
 
 		if self.docstatus == 1:
 			self.flags.ignore_validate_update_after_submit = True
 			self.calculate_cost()
 		if save:
-			self.save()
+			self.db_update()
 		self.update_exploded_items()
 
 		# update parent BOMs
diff --git a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
index 2758a42..e6c10ad 100644
--- a/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
+++ b/erpnext/manufacturing/doctype/bom_update_tool/bom_update_tool.py
@@ -82,7 +82,7 @@
 
 @frappe.whitelist()
 def enqueue_update_cost():
-	frappe.enqueue("erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_cost")
+	frappe.enqueue("erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_cost", timeout=40000)
 	frappe.msgprint(_("Queued for updating latest price in all Bill of Materials. It may take a few minutes."))
 
 def update_latest_price_in_all_boms():
@@ -98,6 +98,9 @@
 	doc.replace_bom()
 
 def update_cost():
+	frappe.db.auto_commit_on_many_writes = 1
 	bom_list = get_boms_in_bottom_up_order()
 	for bom in bom_list:
-		frappe.get_doc("BOM", bom).update_cost(update_parent=False, from_child_bom=True)
\ No newline at end of file
+		frappe.get_doc("BOM", bom).update_cost(update_parent=False, from_child_bom=True)
+
+	frappe.db.auto_commit_on_many_writes = 0
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.py b/erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.py
index 154addf..ac9a409 100644
--- a/erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.py
+++ b/erpnext/manufacturing/doctype/bom_update_tool/test_bom_update_tool.py
@@ -5,6 +5,9 @@
 from __future__ import unicode_literals
 import unittest
 import frappe
+from erpnext.stock.doctype.item.test_item import create_item
+from erpnext.manufacturing.doctype.production_plan.test_production_plan import make_bom
+from erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool import update_cost
 
 test_records = frappe.get_test_records('BOM')
 
@@ -27,4 +30,31 @@
 		# reverse, as it affects other testcases
 		update_tool.current_bom = bom_doc.name
 		update_tool.new_bom = current_bom
-		update_tool.replace_bom()
\ No newline at end of file
+		update_tool.replace_bom()
+
+	def test_bom_cost(self):
+		for item in ["BOM Cost Test Item 1", "BOM Cost Test Item 2", "BOM Cost Test Item 3"]:
+			item_doc = create_item(item, valuation_rate=100)
+			if item_doc.valuation_rate != 100.00:
+				frappe.db.set_value("Item", item_doc.name, "valuation_rate", 100)
+
+		bom_no = frappe.db.get_value('BOM', {'item': 'BOM Cost Test Item 1'}, "name")
+		if not bom_no:
+			doc = make_bom(item = 'BOM Cost Test Item 1',
+				raw_materials =['BOM Cost Test Item 2', 'BOM Cost Test Item 3'], currency="INR")
+		else:
+			doc = frappe.get_doc("BOM", bom_no)
+
+		self.assertEquals(doc.total_cost, 200)
+
+		frappe.db.set_value("Item", "BOM Cost Test Item 2", "valuation_rate", 200)
+		update_cost()
+
+		doc.load_from_db()
+		self.assertEquals(doc.total_cost, 300)
+
+		frappe.db.set_value("Item", "BOM Cost Test Item 2", "valuation_rate", 100)
+		update_cost()
+
+		doc.load_from_db()
+		self.assertEquals(doc.total_cost, 200)
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.js b/erpnext/manufacturing/doctype/production_plan/production_plan.js
index 96e5cd5..b49b0ba 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.js
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.js
@@ -188,7 +188,7 @@
 	},
 
 	get_items_for_mr: function(frm) {
-		const set_fields = ['actual_qty', 'item_code','item_name', 'description', 'uom', 
+		const set_fields = ['actual_qty', 'item_code','item_name', 'description', 'uom',
 			'min_order_qty', 'quantity', 'sales_order', 'warehouse', 'projected_qty', 'material_request_type'];
 		frappe.call({
 			method: "erpnext.manufacturing.doctype.production_plan.production_plan.get_items_for_material_requests",
diff --git a/erpnext/manufacturing/doctype/production_plan/production_plan.py b/erpnext/manufacturing/doctype/production_plan/production_plan.py
index 358a542..c3f27cd 100644
--- a/erpnext/manufacturing/doctype/production_plan/production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/production_plan.py
@@ -346,6 +346,7 @@
 		if not wo.fg_warehouse:
 			wo.fg_warehouse = warehouse.get('fg_warehouse')
 		try:
+			wo.flags.ignore_mandatory = True
 			wo.insert()
 			return wo.name
 		except OverProductionError:
diff --git a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
index f70c9cc..26f580d 100644
--- a/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
+++ b/erpnext/manufacturing/doctype/production_plan/test_production_plan.py
@@ -192,9 +192,10 @@
 	args = frappe._dict(args)
 
 	bom = frappe.get_doc({
-		'doctype': "BOM",
+		'doctype': 'BOM',
 		'is_default': 1,
 		'item': args.item,
+		'currency': args.currency or 'USD',
 		'quantity': args.quantity or 1,
 		'company': args.company or '_Test Company'
 	})
@@ -211,4 +212,5 @@
 		})
 
 	bom.insert(ignore_permissions=True)
-	bom.submit()
\ No newline at end of file
+	bom.submit()
+	return bom
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.js b/erpnext/manufacturing/doctype/work_order/work_order.js
index d541866..4314517 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.js
+++ b/erpnext/manufacturing/doctype/work_order/work_order.js
@@ -313,7 +313,7 @@
 				"Work in Progress": "progress-bar-warning",
 				"Completed": "progress-bar-success"
 			};
-	
+
 			let bars = [];
 			let message = '';
 			let title = '';
@@ -404,7 +404,6 @@
 	},
 
 	before_submit: function(frm) {
-		frm.toggle_reqd(["fg_warehouse", "wip_warehouse"], true);
 		frm.fields_dict.required_items.grid.toggle_reqd("source_warehouse", true);
 		frm.toggle_reqd("transfer_material_against",
 			frm.doc.operations && frm.doc.operations.length > 0);
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.json b/erpnext/manufacturing/doctype/work_order/work_order.json
index e6990fd..00a67a0 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.json
+++ b/erpnext/manufacturing/doctype/work_order/work_order.json
@@ -231,6 +231,7 @@
    "fieldname": "wip_warehouse",
    "fieldtype": "Link",
    "label": "Work-in-Progress Warehouse",
+   "mandatory_depends_on": "eval:!doc.skip_transfer || doc.from_wip_warehouse",
    "options": "Warehouse"
   },
   {
@@ -238,7 +239,8 @@
    "fieldname": "fg_warehouse",
    "fieldtype": "Link",
    "label": "Target Warehouse",
-   "options": "Warehouse"
+   "options": "Warehouse",
+   "reqd": 1
   },
   {
    "fieldname": "column_break_12",
@@ -481,7 +483,7 @@
  "image_field": "image",
  "is_submittable": 1,
  "links": [],
- "modified": "2020-01-31 12:46:23.636033",
+ "modified": "2020-04-24 19:32:43.323054",
  "modified_by": "Administrator",
  "module": "Manufacturing",
  "name": "Work Order",
diff --git a/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py b/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py
index 65f4d08..75ebcbc 100644
--- a/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py
+++ b/erpnext/manufacturing/report/bom_stock_report/bom_stock_report.py
@@ -18,10 +18,10 @@
 	"""return columns"""
 	columns = [
 		_("Item") + ":Link/Item:150",
-		_("Description") + "::500",
-		_("Qty per BOM Line") + ":Float:100",
-		_("Required Qty") + ":Float:100",
-		_("In Stock Qty") + ":Float:100",
+		_("Description") + "::300",
+		_("BOM Qty") + ":Float:160",
+		_("Required Qty") + ":Float:120",
+		_("In Stock Qty") + ":Float:120",
 		_("Enough Parts to Build") + ":Float:200",
 	]
 
@@ -59,13 +59,14 @@
 				bom_item.item_code,
 				bom_item.description ,
 				bom_item.{qty_field},
-				bom_item.{qty_field} * {qty_to_produce},
+				bom_item.{qty_field} * {qty_to_produce} / bom.quantity,
 				sum(ledger.actual_qty) as actual_qty,
-				sum(FLOOR(ledger.actual_qty / (bom_item.{qty_field} * {qty_to_produce})))
+				sum(FLOOR(ledger.actual_qty / (bom_item.{qty_field} * {qty_to_produce} / bom.quantity)))
 			FROM
-				{table} AS bom_item
+				`tabBOM` AS bom INNER JOIN {table} AS bom_item
+					ON bom.name = bom_item.parent
 				LEFT JOIN `tabBin` AS ledger
-				ON bom_item.item_code = ledger.item_code
+					ON bom_item.item_code = ledger.item_code
 				{conditions}
 			WHERE
 				bom_item.parent = '{bom}' and bom_item.parenttype='BOM'
diff --git a/erpnext/non_profit/desk_page/non_profit/non_profit.json b/erpnext/non_profit/desk_page/non_profit/non_profit.json
index a476857..ebe6194 100644
--- a/erpnext/non_profit/desk_page/non_profit/non_profit.json
+++ b/erpnext/non_profit/desk_page/non_profit/non_profit.json
@@ -42,7 +42,7 @@
  "idx": 0,
  "is_standard": 1,
  "label": "Non Profit",
- "modified": "2020-04-01 11:28:51.430882",
+ "modified": "2020-04-13 13:41:52.373705",
  "modified_by": "Administrator",
  "module": "Non Profit",
  "name": "Non Profit",
@@ -50,5 +50,31 @@
  "pin_to_bottom": 0,
  "pin_to_top": 0,
  "restrict_to_domain": "Non Profit",
- "shortcuts": []
+ "shortcuts": [
+  {
+   "label": "Member",
+   "link_to": "Member",
+   "type": "DocType"
+  },
+  {
+   "label": "Membership Settings",
+   "link_to": "Membership Settings",
+   "type": "DocType"
+  },
+  {
+   "label": "Membership",
+   "link_to": "Membership",
+   "type": "DocType"
+  },
+  {
+   "label": "Chapter",
+   "link_to": "Chapter",
+   "type": "DocType"
+  },
+  {
+   "label": "Chapter Member",
+   "link_to": "Chapter Member",
+   "type": "DocType"
+  }
+ ]
 }
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/member/member.js b/erpnext/non_profit/doctype/member/member.js
index eb74dc1..3e9d0ba 100644
--- a/erpnext/non_profit/doctype/member/member.js
+++ b/erpnext/non_profit/doctype/member/member.js
@@ -2,6 +2,14 @@
 // For license information, please see license.txt
 
 frappe.ui.form.on('Member', {
+	setup: function(frm) {
+		frappe.db.get_single_value("Membership Settings", "enable_razorpay").then(val => {
+			if (val && (frm.doc.subscription_id || frm.doc.customer_id)) {
+				frm.set_df_property('razorpay_details_section', 'hidden', false);
+			}
+		})
+	},
+
 	refresh: function(frm) {
 
 		frappe.dynamic_link = {doc: frm.doc, fieldname: 'name', doctype: 'Member'};
diff --git a/erpnext/non_profit/doctype/member/member.json b/erpnext/non_profit/doctype/member/member.json
index 9414974..bb73a84 100644
--- a/erpnext/non_profit/doctype/member/member.json
+++ b/erpnext/non_profit/doctype/member/member.json
@@ -1,604 +1,216 @@
 {
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 1, 
- "autoname": "naming_series:", 
- "beta": 0, 
- "creation": "2017-09-11 09:24:52.898356", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "naming_series:",
+ "creation": "2017-09-11 09:24:52.898356",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "naming_series",
+  "member_name",
+  "membership_expiry_date",
+  "column_break_5",
+  "membership_type",
+  "email",
+  "email_id",
+  "image",
+  "customer_section",
+  "customer",
+  "customer_name",
+  "supplier_section",
+  "supplier",
+  "address_contacts",
+  "address_html",
+  "column_break_9",
+  "contact_html",
+  "razorpay_details_section",
+  "subscription_id",
+  "customer_id",
+  "subscription_activated",
+  "column_break_21",
+  "subscription_start",
+  "subscription_end"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "default": "", 
-   "fieldname": "naming_series", 
-   "fieldtype": "Select", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Series", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "NPO-MEM-.YYYY.-", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "naming_series",
+   "fieldtype": "Select",
+   "label": "Series",
+   "options": "NPO-MEM-.YYYY.-",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "member_name", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Member Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "member_name",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "label": "Member Name",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "membership_expiry_date", 
-   "fieldtype": "Date", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Membership Expiry Date", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "membership_expiry_date",
+   "fieldtype": "Date",
+   "label": "Membership Expiry Date"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_5", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_5",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "membership_type", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Membership Type", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Membership Type", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "membership_type",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Membership Type",
+   "options": "Membership Type",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "email", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Email", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "User", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "email",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "User",
+   "options": "User"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "image", 
-   "fieldtype": "Attach Image", 
-   "hidden": 1, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Image", 
-   "length": 0, 
-   "no_copy": 1, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 1, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "image",
+   "fieldtype": "Attach Image",
+   "hidden": 1,
+   "label": "Image",
+   "no_copy": 1,
+   "print_hide": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 1, 
-   "columns": 0, 
-   "fieldname": "customer_section", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Customer", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "collapsible": 1,
+   "fieldname": "customer_section",
+   "fieldtype": "Section Break",
+   "label": "Customer"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "customer", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Customer", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Customer", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "customer",
+   "fieldtype": "Link",
+   "label": "Customer",
+   "options": "Customer"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fetch_from": "customer.customer_name", 
-   "fieldname": "customer_name", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Customer Name", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fetch_from": "customer.customer_name",
+   "fieldname": "customer_name",
+   "fieldtype": "Data",
+   "label": "Customer Name",
+   "read_only": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 1, 
-   "columns": 0, 
-   "fieldname": "supplier_section", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Supplier", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "collapsible": 1,
+   "fieldname": "supplier_section",
+   "fieldtype": "Section Break",
+   "label": "Supplier"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "supplier", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Supplier", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Supplier", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "supplier",
+   "fieldtype": "Link",
+   "label": "Supplier",
+   "options": "Supplier"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "address_contacts", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Address and Contact", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "fa fa-map-marker", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "address_contacts",
+   "fieldtype": "Section Break",
+   "label": "Address and Contact",
+   "options": "fa fa-map-marker"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "address_html", 
-   "fieldtype": "HTML", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Address HTML", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "address_html",
+   "fieldtype": "HTML",
+   "label": "Address HTML"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_9", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_9",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "contact_html", 
-   "fieldtype": "HTML", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Contact HTML", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
+   "fieldname": "contact_html",
+   "fieldtype": "HTML",
+   "label": "Contact HTML"
+  },
+  {
+   "fieldname": "email_id",
+   "fieldtype": "Data",
+   "label": "Email Address"
+  },
+  {
+   "fieldname": "subscription_id",
+   "fieldtype": "Data",
+   "label": "Subscription ID",
+   "read_only": 1
+  },
+  {
+   "fieldname": "customer_id",
+   "fieldtype": "Data",
+   "label": "Customer ID",
+   "read_only": 1
+  },
+  {
+   "fieldname": "razorpay_details_section",
+   "fieldtype": "Section Break",
+   "hidden": 1,
+   "label": "Razorpay Details"
+  },
+  {
+   "fieldname": "column_break_21",
+   "fieldtype": "Column Break"
+  },
+  {
+   "default": "0",
+   "fieldname": "subscription_activated",
+   "fieldtype": "Check",
+   "label": "Subscription Activated"
+  },
+  {
+   "fieldname": "subscription_start",
+   "fieldtype": "Date",
+   "label": "Subscription Start "
+  },
+  {
+   "fieldname": "subscription_end",
+   "fieldtype": "Date",
+   "label": "Subscription End"
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_field": "image", 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2018-08-21 14:44:23.218109", 
- "modified_by": "Administrator", 
- "module": "Non Profit", 
- "name": "Member", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "image_field": "image",
+ "links": [],
+ "modified": "2020-04-07 14:20:33.215700",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Member",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Non Profit Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Non Profit Manager",
+   "share": 1,
    "write": 1
-  }, 
+  },
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Non Profit Member", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Non Profit Member",
+   "share": 1,
    "write": 1
   }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Non Profit", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "title_field": "member_name", 
- "track_changes": 1, 
- "track_seen": 0, 
- "track_views": 0
+ ],
+ "quick_entry": 1,
+ "restrict_to_domain": "Non Profit",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "member_name",
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/member/member.py b/erpnext/non_profit/doctype/member/member.py
index 9afaf90..571f87a 100644
--- a/erpnext/non_profit/doctype/member/member.py
+++ b/erpnext/non_profit/doctype/member/member.py
@@ -3,9 +3,12 @@
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
+import frappe
+from frappe import _
 from frappe.model.document import Document
 from frappe.contacts.address_and_contact import load_address_and_contact
-
+from frappe.utils import cint
+from frappe.integrations.utils import get_payment_gateway_controller
 
 class Member(Document):
 	def onload(self):
@@ -14,8 +17,114 @@
 
 
 	def validate(self):
-		self.validate_email_type(self.email)
+		if self.email:
+			self.validate_email_type(self.email)
+		if self.email_id:
+			self.validate_email_type(self.email_id)
 
 	def validate_email_type(self, email):
 		from frappe.utils import validate_email_address
-		validate_email_address(email.strip(), True)
\ No newline at end of file
+		validate_email_address(email.strip(), True)
+
+	def setup_subscription(self):
+		membership_settings = frappe.get_doc("Membership Settings")
+		if not membership_settings.enable_razorpay:
+			frappe.throw("Please enable Razorpay to setup subscription")
+
+		controller = get_payment_gateway_controller("Razorpay")
+		settings = controller.get_settings({})
+
+		plan_id = frappe.get_value("Membership Type", self.membership_type, "razorpay_plan_id")
+
+		if not plan_id:
+			frappe.throw(_("Please setup Razorpay Plan ID"))
+
+		subscription_details = {
+			"plan_id": plan_id,
+			"billing_frequency": cint(membership_settings.billing_frequency),
+			"customer_notify": 1
+		}
+
+		args = {
+			'subscription_details': subscription_details
+		}
+
+		subscription = controller.setup_subscription(settings, **args)
+
+		return subscription
+
+def get_or_create_member(user_details):
+	member_list = frappe.get_all("Member", filters={'email': user_details.email, 'membership_type': user_details.plan_id})
+	if member_list and member_list[0]:
+		return member_list[0]['name']
+	else:
+		return create_member(user_details)
+
+def create_member(user_details):
+	member = frappe.new_doc("Member")
+	member.update({
+		"member_name": user_details.fullname,
+		"email_id": user_details.email,
+		"pan_number": user_details.pan,
+		"membership_type": user_details.plan_id,
+		"customer": create_customer(user_details)
+	})
+
+	member.insert(ignore_permissions=True)
+	return member
+
+def create_customer(user_details):
+	customer = frappe.new_doc("Customer")
+	customer.customer_name = user_details.fullname
+	customer.customer_type = "Individual"
+	customer.insert(ignore_permissions=True)
+
+	try:
+		contact = frappe.new_doc("Contact")
+		contact.first_name = user_details.fullname
+		contact.add_phone(user_details.mobile, is_primary_phone=1, is_primary_mobile_no=1)
+		contact.add_email(user_details.email, is_primary=1)
+		contact.insert(ignore_permissions=True)
+
+		contact.append("links", {
+			"link_doctype": "Customer",
+			"link_name": customer.name
+		})
+
+		contact.insert()
+	except Exception as e:
+		frappe.log_error(frappe.get_traceback(), _("Contact Creation Failed"))
+		pass
+
+	return customer.name
+
+@frappe.whitelist(allow_guest=True)
+def create_member_subscription_order(user_details):
+	"""Create Member subscription and order for payment
+
+	Args:
+		user_details (TYPE): Description
+
+	Returns:
+		Dictionary: Dictionary with subscription details
+		{
+			'subscription_details': {
+										'plan_id': 'plan_EXwyxDYDCj3X4v',
+										'billing_frequency': 24,
+										'customer_notify': 1
+									},
+			'subscription_id': 'sub_EZycCvXFvqnC6p'
+		}
+	"""
+	# {"plan_id":"IFF Starter","fullname":"Shivam Mishra","mobile":"7506056962","email":"shivam@shivam.dev","pan":"Testing123"}
+	user_details = frappe._dict(user_details)
+	member = get_or_create_member(user_details)
+	if not member:
+		member = create_member(user_details)
+
+	subscription = member.setup_subscription()
+
+	member.subscription_id = subscription.get('subscription_id')
+	member.save(ignore_permissions=True)
+
+	return subscription
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/membership/membership.js b/erpnext/non_profit/doctype/membership/membership.js
index 4210879..554549a 100644
--- a/erpnext/non_profit/doctype/membership/membership.js
+++ b/erpnext/non_profit/doctype/membership/membership.js
@@ -2,7 +2,13 @@
 // For license information, please see license.txt
 
 frappe.ui.form.on('Membership', {
-	onload:function(frm) {
+	setup: function(frm) {
+		frappe.db.get_single_value("Membership Settings", "enable_razorpay").then(val => {
+			if (val) frm.set_df_property('razorpay_details_section', 'hidden', false);
+		})
+	},
+
+	onload: function(frm) {
 		frm.add_fetch('membership_type', 'amount', 'amount');
 	}
 });
diff --git a/erpnext/non_profit/doctype/membership/membership.json b/erpnext/non_profit/doctype/membership/membership.json
index 9a204b1..9f10d0c 100644
--- a/erpnext/non_profit/doctype/membership/membership.json
+++ b/erpnext/non_profit/doctype/membership/membership.json
@@ -1,501 +1,164 @@
 {
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "autoname": "NPO-MSH-.YYYY.-.#####", 
- "beta": 0, 
- "creation": "2017-09-11 11:39:18.492184", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "autoname": "NPO-MSH-.YYYY.-.#####",
+ "creation": "2017-09-11 11:39:18.492184",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "member",
+  "membership_type",
+  "column_break_3",
+  "membership_status",
+  "membership_validity_section",
+  "from_date",
+  "to_date",
+  "column_break_8",
+  "member_since_date",
+  "payment_details",
+  "paid",
+  "currency",
+  "amount",
+  "razorpay_details_section",
+  "subscription_id",
+  "payment_id",
+  "webhook_payload"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "member", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Member", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Member", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "member",
+   "fieldtype": "Link",
+   "label": "Member",
+   "options": "Member"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "membership_type", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Membership Type", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Membership Type", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "membership_type",
+   "fieldtype": "Link",
+   "in_list_view": 1,
+   "label": "Membership Type",
+   "options": "Membership Type",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_3", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_3",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "membership_status", 
-   "fieldtype": "Select", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Membership Status", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "New\nCurrent\nExpired\nPending\nCancelled", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "membership_status",
+   "fieldtype": "Select",
+   "label": "Membership Status",
+   "options": "New\nCurrent\nExpired\nPending\nCancelled"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "membership_validity_section", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Validity", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "membership_validity_section",
+   "fieldtype": "Section Break",
+   "label": "Validity"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "from_date", 
-   "fieldtype": "Date", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "From", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "from_date",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "label": "From",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "to_date", 
-   "fieldtype": "Date", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "To", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "to_date",
+   "fieldtype": "Date",
+   "in_list_view": 1,
+   "label": "To",
+   "reqd": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "column_break_8", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "column_break_8",
+   "fieldtype": "Column Break"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "member_since_date", 
-   "fieldtype": "Date", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Member Since", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "member_since_date",
+   "fieldtype": "Date",
+   "label": "Member Since"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "payment_details", 
-   "fieldtype": "Section Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Payment Details", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "payment_details",
+   "fieldtype": "Section Break",
+   "label": "Payment Details"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "paid", 
-   "fieldtype": "Check", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Paid", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "default": "0",
+   "fieldname": "paid",
+   "fieldtype": "Check",
+   "label": "Paid"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "currency", 
-   "fieldtype": "Select", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Currency", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "USD\nINR", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "currency",
+   "fieldtype": "Select",
+   "label": "Currency",
+   "options": "USD\nINR"
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_in_quick_entry": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "amount", 
-   "fieldtype": "Float", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 0, 
-   "in_standard_filter": 0, 
-   "label": "Amount", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 0, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "translatable": 0, 
-   "unique": 0
+   "fieldname": "amount",
+   "fieldtype": "Float",
+   "label": "Amount"
+  },
+  {
+   "fieldname": "razorpay_details_section",
+   "fieldtype": "Section Break",
+   "hidden": 1,
+   "label": "Razorpay Details"
+  },
+  {
+   "fieldname": "subscription_id",
+   "fieldtype": "Data",
+   "label": "Subscription ID",
+   "read_only": 1
+  },
+  {
+   "fieldname": "payment_id",
+   "fieldtype": "Data",
+   "label": "Payment ID",
+   "read_only": 1
+  },
+  {
+   "fieldname": "webhook_payload",
+   "fieldtype": "Code",
+   "label": "Webhook Payload",
+   "options": "JSON",
+   "read_only": 1
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2018-08-21 16:15:42.323446", 
- "modified_by": "Administrator", 
- "module": "Non Profit", 
- "name": "Membership", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "links": [],
+ "modified": "2020-04-06 14:29:33.856060",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Membership",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Non Profit Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Non Profit Manager",
+   "share": 1,
    "write": 1
-  }, 
+  },
   {
-   "amend": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Non Profit Member", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Non Profit Member",
+   "share": 1,
    "write": 1
   }
- ], 
- "quick_entry": 0, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Non Profit", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 1, 
- "track_seen": 0, 
- "track_views": 0
+ ],
+ "restrict_to_domain": "Non Profit",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/membership/membership.py b/erpnext/non_profit/doctype/membership/membership.py
index 98bee56..a523a23 100644
--- a/erpnext/non_profit/doctype/membership/membership.py
+++ b/erpnext/non_profit/doctype/membership/membership.py
@@ -3,9 +3,13 @@
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
+import json
 import frappe
+import six
+from datetime import datetime
 from frappe.model.document import Document
-from frappe.utils import add_days, add_years, nowdate, getdate
+from frappe.email import sendmail_to_system_managers
+from frappe.utils import add_days, add_years, nowdate, getdate, add_months, get_link_to_form
 from frappe import _
 import erpnext
 
@@ -43,11 +47,80 @@
 		else:
 			self.from_date = nowdate()
 
-		self.to_date = add_years(self.from_date, 1)
+		if frappe.db.get_single_value("Membership Settings", "billing_cycle") == "Yearly":
+			self.to_date = add_years(self.from_date, 1)
+		else:
+			self.to_date = add_months(self.from_date, 1)
 
 	def on_payment_authorized(self, status_changed_to=None):
 		if status_changed_to in ("Completed", "Authorized"):
 			self.load_from_db()
 			self.db_set('paid', 1)
 
+def get_member_based_on_subscription(subscription_id, email):
+	members = frappe.get_all("Member", filters={
+					'subscription_id': subscription_id,
+					'email_id': email
+				}, order_by="creation desc")
 
+	return frappe.get_doc("Member", members[0]['name'])
+
+
+@frappe.whitelist()
+def trigger_razorpay_subscription(data):
+	if isinstance(data, six.string_types):
+		data = json.loads(data)
+	data = frappe._dict(data)
+
+	subscription = data.payload.get("subscription", {}).get('entity', {})
+	subscription = frappe._dict(subscription)
+
+	payment = data.payload.get("payment", {}).get('entity', {})
+	payment = frappe._dict(payment)
+
+	try:
+		data_json = json.dumps(data, indent=4, sort_keys=True)
+		member = get_member_based_on_subscription(subscription.id, payment.email)
+	except Exception as e:
+		error_log = frappe.log_error(frappe.get_traceback() + '\n' + data_json , _("Membership Webhook Failed"))
+		notify_failure(error_log)
+		raise e
+
+	if data.event == "subscription.activated":
+		member.customer_id = payment.customer_id
+		member.subscription_start = datetime.fromtimestamp(subscription.start_at)
+		member.subscription_end = datetime.fromtimestamp(subscription.end_at)
+		member.subscription_activated = 1
+		member.save(ignore_permissions=True)
+	elif data.event == "subscription.charged":
+		membership = frappe.new_doc("Membership")
+		membership.update({
+			"member": member.name,
+			"membership_status": "Current",
+			"membership_type": member.membership_type,
+			"currency": "INR",
+			"paid": 1,
+			"payment_id": payment.id,
+			"webhook_payload": data_json,
+			"from_date": datetime.fromtimestamp(subscription.current_start),
+			"to_date": datetime.fromtimestamp(subscription.current_end),
+			"amount": payment.amount / 100 # Convert to rupees from paise
+		})
+		membership.insert(ignore_permissions=True)
+
+	return True
+
+
+
+def notify_failure(log):
+	try:
+		content = """Dear System Manager,
+Razorpay webhook for creating renewing membership subscription failed due to some reason. Please check the following error log linked below
+
+Error Log: {0}
+
+Regards,
+Administrator""".format(get_link_to_form("Error Log", log.name))
+		sendmail_to_system_managers("[Important] [ERPNext] Razorpay membership webhook failed , please check.", content)
+	except:
+		pass
diff --git a/erpnext/accounts/doctype/account_subtype/__init__.py b/erpnext/non_profit/doctype/membership_settings/__init__.py
similarity index 100%
copy from erpnext/accounts/doctype/account_subtype/__init__.py
copy to erpnext/non_profit/doctype/membership_settings/__init__.py
diff --git a/erpnext/non_profit/doctype/membership_settings/membership_settings.js b/erpnext/non_profit/doctype/membership_settings/membership_settings.js
new file mode 100644
index 0000000..c01a0b2
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership_settings/membership_settings.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Membership Settings', {
+	refresh: function(frm) {
+
+	}
+});
diff --git a/erpnext/non_profit/doctype/membership_settings/membership_settings.json b/erpnext/non_profit/doctype/membership_settings/membership_settings.json
new file mode 100644
index 0000000..56b8eac
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership_settings/membership_settings.json
@@ -0,0 +1,62 @@
+{
+ "actions": [],
+ "creation": "2020-03-29 12:57:03.005120",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "enable_razorpay",
+  "razorpay_settings_section",
+  "billing_cycle",
+  "billing_frequency"
+ ],
+ "fields": [
+  {
+   "fieldname": "billing_cycle",
+   "fieldtype": "Select",
+   "label": "Billing Cycle",
+   "options": "Monthly\nYearly"
+  },
+  {
+   "default": "0",
+   "fieldname": "enable_razorpay",
+   "fieldtype": "Check",
+   "label": "Enable RazorPay For Memberships"
+  },
+  {
+   "depends_on": "eval:doc.enable_razorpay",
+   "fieldname": "razorpay_settings_section",
+   "fieldtype": "Section Break",
+   "label": "RazorPay Settings"
+  },
+  {
+   "description": "The number of billing cycles for which the customer should be charged. For example, if a customer is buying a 1-year membership that should be billed on a monthly basis, this value should be 12.",
+   "fieldname": "billing_frequency",
+   "fieldtype": "Int",
+   "label": "Billing Frequency"
+  }
+ ],
+ "issingle": 1,
+ "links": [],
+ "modified": "2020-04-07 18:42:51.496807",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Membership Settings",
+ "owner": "Administrator",
+ "permissions": [
+  {
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "print": 1,
+   "read": 1,
+   "role": "System Manager",
+   "share": 1,
+   "write": 1
+  }
+ ],
+ "quick_entry": 1,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
+}
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/membership_settings/membership_settings.py b/erpnext/non_profit/doctype/membership_settings/membership_settings.py
new file mode 100644
index 0000000..2b8e37f
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership_settings/membership_settings.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.integrations.utils import get_payment_gateway_controller
+from frappe.model.document import Document
+
+class MembershipSettings(Document):
+	pass
+
+@frappe.whitelist()
+def get_plans_for_membership(*args, **kwargs):
+	controller = get_payment_gateway_controller("Razorpay")
+	plans = controller.get_plans()
+	return [plan.get("item") for plan in plans.get("items")]
\ No newline at end of file
diff --git a/erpnext/non_profit/doctype/membership_settings/test_membership_settings.py b/erpnext/non_profit/doctype/membership_settings/test_membership_settings.py
new file mode 100644
index 0000000..2ad7984
--- /dev/null
+++ b/erpnext/non_profit/doctype/membership_settings/test_membership_settings.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+# import frappe
+import unittest
+
+class TestMembershipSettings(unittest.TestCase):
+	pass
diff --git a/erpnext/non_profit/doctype/membership_type/membership_type.js b/erpnext/non_profit/doctype/membership_type/membership_type.js
index 3ef39ae..226981d 100644
--- a/erpnext/non_profit/doctype/membership_type/membership_type.js
+++ b/erpnext/non_profit/doctype/membership_type/membership_type.js
@@ -2,7 +2,9 @@
 // For license information, please see license.txt
 
 frappe.ui.form.on('Membership Type', {
-	refresh: function() {
-
+	refresh: function(frm) {
+		frappe.db.get_single_value("Membership Settings", "enable_razorpay").then(val => {
+			if (val) frm.set_df_property('razorpay_plan_id', 'hidden', false);
+		})
 	}
 });
diff --git a/erpnext/non_profit/doctype/membership_type/membership_type.json b/erpnext/non_profit/doctype/membership_type/membership_type.json
index 35a7902..319078f 100644
--- a/erpnext/non_profit/doctype/membership_type/membership_type.json
+++ b/erpnext/non_profit/doctype/membership_type/membership_type.json
@@ -1,124 +1,63 @@
 {
- "allow_copy": 0, 
- "allow_guest_to_view": 0, 
- "allow_import": 0, 
- "allow_rename": 0, 
- "autoname": "field:membership_type", 
- "beta": 0, 
- "creation": "2017-09-18 12:56:56.343999", 
- "custom": 0, 
- "docstatus": 0, 
- "doctype": "DocType", 
- "document_type": "", 
- "editable_grid": 1, 
- "engine": "InnoDB", 
+ "actions": [],
+ "autoname": "field:membership_type",
+ "creation": "2017-09-18 12:56:56.343999",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+  "membership_type",
+  "amount",
+  "razorpay_plan_id"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "membership_type", 
-   "fieldtype": "Data", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 1, 
-   "label": "Membership Type", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
-  }, 
+   "fieldname": "membership_type",
+   "fieldtype": "Data",
+   "in_list_view": 1,
+   "in_standard_filter": 1,
+   "label": "Membership Type",
+   "reqd": 1,
+   "unique": 1
+  },
   {
-   "allow_bulk_edit": 0, 
-   "allow_on_submit": 0, 
-   "bold": 0, 
-   "collapsible": 0, 
-   "columns": 0, 
-   "fieldname": "amount", 
-   "fieldtype": "Float", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_global_search": 0, 
-   "in_list_view": 1, 
-   "in_standard_filter": 0, 
-   "label": "Amount", 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 0, 
-   "remember_last_selected_value": 0, 
-   "report_hide": 0, 
-   "reqd": 1, 
-   "search_index": 0, 
-   "set_only_once": 0, 
-   "unique": 0
+   "fieldname": "amount",
+   "fieldtype": "Float",
+   "in_list_view": 1,
+   "label": "Amount",
+   "reqd": 1
+  },
+  {
+   "fieldname": "razorpay_plan_id",
+   "fieldtype": "Data",
+   "hidden": 1,
+   "label": "Razorpay Plan ID",
+   "unique": 1
   }
- ], 
- "has_web_view": 0, 
- "hide_heading": 0, 
- "hide_toolbar": 0, 
- "idx": 0, 
- "image_view": 0, 
- "in_create": 0, 
- "is_submittable": 0, 
- "issingle": 0, 
- "istable": 0, 
- "max_attachments": 0, 
- "modified": "2017-12-05 07:03:45.860757", 
- "modified_by": "Administrator", 
- "module": "Non Profit", 
- "name": "Membership Type", 
- "name_case": "", 
- "owner": "Administrator", 
+ ],
+ "links": [],
+ "modified": "2020-03-30 12:54:07.850857",
+ "modified_by": "Administrator",
+ "module": "Non Profit",
+ "name": "Membership Type",
+ "owner": "Administrator",
  "permissions": [
   {
-   "amend": 0, 
-   "apply_user_permissions": 0, 
-   "cancel": 0, 
-   "create": 1, 
-   "delete": 1, 
-   "email": 1, 
-   "export": 1, 
-   "if_owner": 0, 
-   "import": 0, 
-   "permlevel": 0, 
-   "print": 1, 
-   "read": 1, 
-   "report": 1, 
-   "role": "Non Profit Manager", 
-   "set_user_permissions": 0, 
-   "share": 1, 
-   "submit": 0, 
+   "create": 1,
+   "delete": 1,
+   "email": 1,
+   "export": 1,
+   "print": 1,
+   "read": 1,
+   "report": 1,
+   "role": "Non Profit Manager",
+   "share": 1,
    "write": 1
   }
- ], 
- "quick_entry": 1, 
- "read_only": 0, 
- "read_only_onload": 0, 
- "restrict_to_domain": "Non Profit", 
- "show_name_in_global_search": 0, 
- "sort_field": "modified", 
- "sort_order": "DESC", 
- "track_changes": 1, 
- "track_seen": 0
+ ],
+ "quick_entry": 1,
+ "restrict_to_domain": "Non Profit",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 9ef0b8d..eb2b35c 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -662,8 +662,11 @@
 erpnext.patches.v12_0.move_bank_account_swift_number_to_bank
 erpnext.patches.v12_0.rename_bank_reconciliation_fields # 2020-01-22
 erpnext.patches.v12_0.set_received_qty_in_material_request_as_per_stock_uom
+erpnext.patches.v12_0.rename_account_type_doctype
 erpnext.patches.v12_0.recalculate_requested_qty_in_bin
 erpnext.patches.v12_0.update_healthcare_refactored_changes
 erpnext.patches.v12_0.set_total_batch_quantity
 erpnext.patches.v12_0.rename_mws_settings_fields
 erpnext.patches.v12_0.set_updated_purpose_in_pick_list
+erpnext.patches.v12_0.repost_stock_ledger_entries_for_target_warehouse
+erpnext.patches.v12_0.update_end_date_and_status_in_email_campaign
\ No newline at end of file
diff --git a/erpnext/patches/v12_0/rename_account_type_doctype.py b/erpnext/patches/v12_0/rename_account_type_doctype.py
new file mode 100644
index 0000000..ffb4e93
--- /dev/null
+++ b/erpnext/patches/v12_0/rename_account_type_doctype.py
@@ -0,0 +1,7 @@
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+	frappe.rename_doc('DocType', 'Account Type', 'Bank Account Type', force=True)
+	frappe.rename_doc('DocType', 'Account Subtype', 'Bank Account Subtype', force=True)
+	frappe.reload_doc('accounts', 'doctype', 'bank_account')
\ No newline at end of file
diff --git a/erpnext/patches/v12_0/repost_stock_ledger_entries_for_target_warehouse.py b/erpnext/patches/v12_0/repost_stock_ledger_entries_for_target_warehouse.py
new file mode 100644
index 0000000..13e935b
--- /dev/null
+++ b/erpnext/patches/v12_0/repost_stock_ledger_entries_for_target_warehouse.py
@@ -0,0 +1,71 @@
+# Copyright (c) 2020, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+	warehouse_perm = frappe.get_all("User Permission",
+		fields=["count(*) as p_count", "is_default", "user"], filters={"allow": "Warehouse"}, group_by="user")
+
+	if not warehouse_perm:
+		return
+
+	execute_patch = False
+	for perm_data in warehouse_perm:
+		if perm_data.p_count == 1 or (perm_data.p_count > 1 and frappe.get_all("User Permission",
+			filters = {"user": perm_data.user, "allow": "warehouse", "is_default": 1}, limit=1)):
+			execute_patch = True
+			break
+
+	if not execute_patch: return
+
+	for doctype in ["Sales Invoice", "Delivery Note"]:
+		if not frappe.get_meta(doctype + ' Item').get_field("target_warehouse").hidden: continue
+
+		cond = ""
+		if doctype == "Sales Invoice":
+			cond = " AND parent_doc.update_stock = 1"
+
+		data = frappe.db.sql(""" SELECT parent_doc.name as name, child_doc.name as child_name
+			FROM
+				`tab{doctype}` parent_doc, `tab{doctype} Item` child_doc
+			WHERE
+				parent_doc.name = child_doc.parent AND parent_doc.docstatus < 2
+				AND child_doc.target_warehouse is not null AND child_doc.target_warehouse != ''
+				AND child_doc.creation > '2020-04-16' {cond}
+		""".format(doctype=doctype, cond=cond), as_dict=1)
+
+		if data:
+			names = [d.child_name for d in data]
+			frappe.db.sql(""" UPDATE `tab{0} Item` set target_warehouse = null
+				WHERE name in ({1}) """.format(doctype, ','.join(["%s"] * len(names) )), tuple(names))
+
+			frappe.db.sql(""" UPDATE `tabPacked Item` set target_warehouse = null
+				WHERE parenttype = '{0}' and parent_detail_docname in ({1})
+			""".format(doctype, ','.join(["%s"] * len(names) )), tuple(names))
+
+			parent_names = list(set([d.name for d in data]))
+
+			for d in parent_names:
+				doc = frappe.get_doc(doctype, d)
+				if doc.docstatus != 1: continue
+
+				doc.docstatus = 2
+				doc.update_stock_ledger()
+				doc.make_gl_entries_on_cancel(repost_future_gle=False)
+
+				# update stock & gl entries for submit state of PR
+				doc.docstatus = 1
+				doc.update_stock_ledger()
+				doc.make_gl_entries()
+
+	if frappe.get_meta('Sales Order Item').get_field("target_warehouse").hidden:
+		frappe.db.sql(""" UPDATE `tabSales Order Item` set target_warehouse = null
+			WHERE creation > '2020-04-16' and docstatus < 2 """)
+
+		frappe.db.sql(""" UPDATE `tabPacked Item` set target_warehouse = null
+			WHERE creation > '2020-04-16' and docstatus < 2 and parenttype = 'Sales Order' """)
+
+
+
diff --git a/erpnext/patches/v12_0/set_permission_einvoicing.py b/erpnext/patches/v12_0/set_permission_einvoicing.py
index 1095c8c..e223510 100644
--- a/erpnext/patches/v12_0/set_permission_einvoicing.py
+++ b/erpnext/patches/v12_0/set_permission_einvoicing.py
@@ -10,6 +10,8 @@
 
 	make_custom_fields()
 
+	frappe.reload_doc("regional", "doctype", "import_supplier_invoice")
+
 	add_permission('Import Supplier Invoice', 'Accounts Manager', 0)
 	update_permission_property('Import Supplier Invoice', 'Accounts Manager', 0, 'write', 1)
-	update_permission_property('Import Supplier Invoice', 'Accounts Manager', 0, 'create', 1)
\ No newline at end of file
+	update_permission_property('Import Supplier Invoice', 'Accounts Manager', 0, 'create', 1)
diff --git a/erpnext/patches/v12_0/update_end_date_and_status_in_email_campaign.py b/erpnext/patches/v12_0/update_end_date_and_status_in_email_campaign.py
new file mode 100644
index 0000000..db71a73
--- /dev/null
+++ b/erpnext/patches/v12_0/update_end_date_and_status_in_email_campaign.py
@@ -0,0 +1,24 @@
+from __future__ import unicode_literals
+import frappe
+from frappe.utils import add_days, getdate, today
+
+def execute():
+    if frappe.db.exists('DocType', 'Email Campaign'):
+        email_campaign = frappe.get_all('Email Campaign')
+        for campaign in email_campaign:
+            doc = frappe.get_doc("Email Campaign",campaign["name"])
+            send_after_days = []
+
+            camp = frappe.get_doc("Campaign", doc.campaign_name)
+            for entry in camp.get("campaign_schedules"):
+                send_after_days.append(entry.send_after_days)
+            if send_after_days:
+                end_date = add_days(getdate(doc.start_date), max(send_after_days))
+                doc.db_set("end_date", end_date)
+            today_date = getdate(today())
+            if doc.start_date > today_date:
+                doc.db_set("status", "Scheduled")
+            elif end_date >= today_date:
+                doc.db_set("status", "In Progress")
+            elif end_date < today_date:
+                doc.db_set("status", "Completed") 
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json
index 49abab1..f3cecd9 100644
--- a/erpnext/projects/doctype/project/project.json
+++ b/erpnext/projects/doctype/project/project.json
@@ -83,7 +83,6 @@
    "oldfieldname": "status",
    "oldfieldtype": "Select",
    "options": "Open\nCompleted\nCancelled",
-   "reqd": 1,
    "search_index": 1
   },
   {
diff --git a/erpnext/public/build.json b/erpnext/public/build.json
index 1490374..e94d1ff 100644
--- a/erpnext/public/build.json
+++ b/erpnext/public/build.json
@@ -1,18 +1,18 @@
 {
-    "css/erpnext.css": [
-        "public/less/erpnext.less",
-        "public/less/hub.less",
-        "public/less/call_popup.less"
-    ],
-    "css/marketplace.css": [
-        "public/less/hub.less"
-    ],
-    "js/erpnext-web.min.js": [
-        "public/js/website_utils.js",
-        "public/js/shopping_cart.js"
-    ],
+	"css/erpnext.css": [
+		"public/less/erpnext.less",
+		"public/less/hub.less",
+		"public/less/call_popup.less"
+	],
+	"css/marketplace.css": [
+		"public/less/hub.less"
+	],
+	"js/erpnext-web.min.js": [
+		"public/js/website_utils.js",
+		"public/js/shopping_cart.js"
+	],
 	"css/erpnext-web.css": [
-        "public/scss/website.scss"
+		"public/scss/website.scss"
 	],
 	"js/marketplace.min.js": [
 		"public/js/hub/marketplace.js"
@@ -47,15 +47,15 @@
 		"public/js/templates/item_quick_entry.html",
 		"public/js/utils/item_quick_entry.js",
 		"public/js/utils/customer_quick_entry.js",
-        "public/js/education/student_button.html",
-        "public/js/education/assessment_result_tool.html",
-        "public/js/hub/hub_factory.js",
-        "public/js/call_popup/call_popup.js",
-        "public/js/utils/dimension_tree_filter.js"
-    ],
-    "js/item-dashboard.min.js": [
-        "stock/dashboard/item_dashboard.html",
-        "stock/dashboard/item_dashboard_list.html",
-        "stock/dashboard/item_dashboard.js"
-    ]
+		"public/js/education/student_button.html",
+		"public/js/education/assessment_result_tool.html",
+		"public/js/hub/hub_factory.js",
+		"public/js/call_popup/call_popup.js",
+		"public/js/utils/dimension_tree_filter.js"
+	],
+	"js/item-dashboard.min.js": [
+		"stock/dashboard/item_dashboard.html",
+		"stock/dashboard/item_dashboard_list.html",
+		"stock/dashboard/item_dashboard.js"
+	]
 }
diff --git a/erpnext/public/css/erpnext.css b/erpnext/public/css/erpnext.css
index c55e422..6e4efcb 100644
--- a/erpnext/public/css/erpnext.css
+++ b/erpnext/public/css/erpnext.css
@@ -370,3 +370,39 @@
 .leaderboard .list-item_content {
   padding-right: 45px;
 }
+.exercise-card {
+	box-shadow: 0 1px 3px rgba(0,0,0,0.30);
+	border-radius: 2px;
+	padding: 6px 6px 6px 8px;
+	margin-top: 10px;
+	height: 100% !important;
+}
+.exercise-card .card-img-top {
+	width: 100%;
+	height: 15vw;
+	object-fit: cover;
+}
+.exercise-card .btn-edit {
+	position: absolute;
+	bottom: 10px;
+	left: 20px;
+}
+.exercise-card .btn-del {
+	position: absolute;
+	bottom: 10px;
+	left: 50px;
+}
+.exercise-card .card-body {
+		margin-bottom: 10px;
+}
+.exercise-card .card-footer {
+		padding: 10px;
+}
+.exercise-row {
+	height: 100% !important;
+	display: flex;
+	flex-wrap: wrap;
+}
+.exercise-col {
+	padding: 10px;
+}
diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js
index afbdbc6..d5dc412 100644
--- a/erpnext/public/js/controllers/buying.js
+++ b/erpnext/public/js/controllers/buying.js
@@ -444,75 +444,69 @@
 				"fieldname": "quantity",
 				"reqd": 1,
 				"default": 1
-			},
-			{
-				"fieldtype": "Button",
-				"label": __("Get Items"),
-				"fieldname": "get_items",
-				"cssClass": "btn-primary"
 			}
-		]
-	});
-
-	dialog.fields_dict.get_items.$input.click(function() {
-		var args = dialog.get_values();
-		if(!args) return;
-		dialog.hide();
-		return frappe.call({
-			type: "GET",
-			method: "erpnext.stock.doctype.packed_item.packed_item.get_items_from_product_bundle",
-			args: {
+		],
+		primary_action_label: 'Get Items',
+		primary_action(args){
+			if(!args) return;
+			dialog.hide();
+			return frappe.call({
+				type: "GET",
+				method: "erpnext.stock.doctype.packed_item.packed_item.get_items_from_product_bundle",
 				args: {
-					item_code: args.product_bundle,
-					quantity: args.quantity,
-					parenttype: frm.doc.doctype,
-					parent: frm.doc.name,
-					supplier: frm.doc.supplier,
-					currency: frm.doc.currency,
-					conversion_rate: frm.doc.conversion_rate,
-					price_list: frm.doc.buying_price_list,
-					price_list_currency: frm.doc.price_list_currency,
-					plc_conversion_rate: frm.doc.plc_conversion_rate,
-					company: frm.doc.company,
-					is_subcontracted: frm.doc.is_subcontracted,
-					transaction_date: frm.doc.transaction_date || frm.doc.posting_date,
-					ignore_pricing_rule: frm.doc.ignore_pricing_rule,
-					doctype: frm.doc.doctype
-				}
-			},
-			freeze: true,
-			callback: function(r) {
-				const first_row_is_empty = function(child_table){
-					if($.isArray(child_table) && child_table.length > 0) {
-						return !child_table[0].item_code;
+					args: {
+						item_code: args.product_bundle,
+						quantity: args.quantity,
+						parenttype: frm.doc.doctype,
+						parent: frm.doc.name,
+						supplier: frm.doc.supplier,
+						currency: frm.doc.currency,
+						conversion_rate: frm.doc.conversion_rate,
+						price_list: frm.doc.buying_price_list,
+						price_list_currency: frm.doc.price_list_currency,
+						plc_conversion_rate: frm.doc.plc_conversion_rate,
+						company: frm.doc.company,
+						is_subcontracted: frm.doc.is_subcontracted,
+						transaction_date: frm.doc.transaction_date || frm.doc.posting_date,
+						ignore_pricing_rule: frm.doc.ignore_pricing_rule,
+						doctype: frm.doc.doctype
 					}
-					return false;
-				};
+				},
+				freeze: true,
+				callback: function(r) {
+					const first_row_is_empty = function(child_table){
+						if($.isArray(child_table) && child_table.length > 0) {
+							return !child_table[0].item_code;
+						}
+						return false;
+					};
 
-				const remove_empty_first_row = function(frm){
-				if (first_row_is_empty(frm.doc.items)){
-					frm.doc.items = frm.doc.items.splice(1);
-					}
-				};
+					const remove_empty_first_row = function(frm){
+					if (first_row_is_empty(frm.doc.items)){
+						frm.doc.items = frm.doc.items.splice(1);
+						}
+					};
 
-				if(!r.exc && r.message) {
-					remove_empty_first_row(frm);
-					for ( var i=0; i< r.message.length; i++ ) {
-						var d = frm.add_child("items");
-						var item = r.message[i];
-						for ( var key in  item) {
-							if ( !is_null(item[key]) ) {
-								d[key] = item[key];
+					if(!r.exc && r.message) {
+						remove_empty_first_row(frm);
+						for ( var i=0; i< r.message.length; i++ ) {
+							var d = frm.add_child("items");
+							var item = r.message[i];
+							for ( var key in  item) {
+								if ( !is_null(item[key]) ) {
+									d[key] = item[key];
+								}
+							}
+							if(frappe.meta.get_docfield(d.doctype, "price_list_rate", d.name)) {
+								frm.script_manager.trigger("price_list_rate", d.doctype, d.name);
 							}
 						}
-						if(frappe.meta.get_docfield(d.doctype, "price_list_rate", d.name)) {
-							frm.script_manager.trigger("price_list_rate", d.doctype, d.name);
-						}
+						frm.refresh_field("items");
 					}
-					frm.refresh_field("items");
 				}
-			}
-		})
+			})
+		}
 	});
+
 	dialog.show();
 }
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index f126f6a..4296447 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -499,7 +499,6 @@
 							conversion_factor: item.conversion_factor,
 							weight_per_unit: item.weight_per_unit,
 							weight_uom: item.weight_uom,
-							uom : item.uom,
 							manufacturer: item.manufacturer,
 							stock_uom: item.stock_uom,
 							pos_profile: me.frm.doc.doctype == 'Sales Invoice' ? me.frm.doc.pos_profile : '',
@@ -1413,7 +1412,7 @@
 				me.frm.doc.items.forEach(d => {
 					if (in_list(data.apply_rule_on_other_items, d[data.apply_rule_on])) {
 						for(var k in data) {
-							if (in_list(fields, k) && data[k]) {
+							if (in_list(fields, k) && data[k] && (data.price_or_product_discount === 'price' || k === 'pricing_rules')) {
 								frappe.model.set_value(d.doctype, d.name, k, data[k]);
 							}
 						}
@@ -1434,6 +1433,8 @@
 			for (let key in free_item_data) {
 				row_to_modify[key] = free_item_data[key];
 			}
+		} if (items && items.length && free_item_data) {
+			items[0].qty = free_item_data.qty
 		}
 	},
 
diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less
index abe4868..8685837 100644
--- a/erpnext/public/less/erpnext.less
+++ b/erpnext/public/less/erpnext.less
@@ -458,4 +458,50 @@
 	.list-item_content {
 		padding-right: 45px;
 	}
+}
+
+// Healthcare
+
+.exercise-card {
+	box-shadow: 0 1px 3px rgba(0,0,0,0.30);
+	border-radius: 2px;
+	padding: 6px 6px 6px 8px;
+	margin-top: 10px;
+	height: 100% !important;
+
+	.card-img-top {
+		width: 100%;
+		height: 15vw;
+		object-fit: cover;
+	}
+
+	.btn-edit {
+		position: absolute;
+		bottom: 10px;
+		left: 20px;
+	}
+
+	.btn-del {
+		position: absolute;
+		bottom: 10px;
+		left: 50px;
+	}
+
+	.card-body {
+		margin-bottom: 10px;
+	}
+
+	.card-footer {
+		padding: 10px;
+	}
+}
+
+.exercise-row {
+	height: 100% !important;
+	display: flex;
+	flex-wrap: wrap;
+}
+
+.exercise-col {
+	padding: 10px;
 }
\ No newline at end of file
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index 28b1f8f..4be6804 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -85,7 +85,7 @@
 	hsn_sac_field = dict(fieldname='gst_hsn_code', label='HSN/SAC',
 		fieldtype='Data', fetch_from='item_code.gst_hsn_code', insert_after='description',
 		allow_on_submit=1, print_hide=1, fetch_if_empty=1)
-	nil_rated_exempt = dict(fieldname='is_nil_exempt', label='Is nil rated or exempted',
+	nil_rated_exempt = dict(fieldname='is_nil_exempt', label='Is Nil Rated or Exempted',
 		fieldtype='Check', fetch_from='item_code.is_nil_exempt', insert_after='gst_hsn_code',
 		print_hide=1)
 	is_non_gst = dict(fieldname='is_non_gst', label='Is Non GST',
@@ -388,7 +388,7 @@
 		'Item': [
 			dict(fieldname='gst_hsn_code', label='HSN/SAC',
 				fieldtype='Link', options='GST HSN Code', insert_after='item_group'),
-			dict(fieldname='is_nil_exempt', label='Is nil rated or exempted',
+			dict(fieldname='is_nil_exempt', label='Is Nil Rated or Exempted',
 				fieldtype='Check', insert_after='gst_hsn_code'),
 			dict(fieldname='is_non_gst', label='Is Non GST ',
 				fieldtype='Check', insert_after='is_nil_exempt')
@@ -497,6 +497,14 @@
 				'depends_on':'eval:in_list(["SEZ", "Overseas", "Deemed Export"], doc.gst_category)',
 				'options': '\nWith Payment of Tax\nWithout Payment of Tax'
 			}
+		],
+		"Member": [
+			{
+				'fieldname': 'pan_number',
+				'label': 'PAN Details',
+				'fieldtype': 'Data',
+				'insert_after': 'email'
+			}
 		]
 	}
 	create_custom_fields(custom_fields, update=update)
@@ -718,4 +726,4 @@
 			doctype="Tax Withholding Category", accounts=accounts,
 			rates=[{"fiscal_year": fiscal_year, "tax_withholding_rate": 20,
 			"single_threshold": 2500, "cumulative_threshold": 0}])
-	]
+	]
\ No newline at end of file
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 61aa608..3c1ffe9 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -148,9 +148,14 @@
 					}
 
 					this.frm.add_custom_button(__('Pick List'), () => this.create_pick_list(), __('Create'));
+					
+					const order_is_a_sale = ["Sales", "Shopping Cart"].indexOf(doc.order_type) !== -1;
+					const order_is_maintenance = ["Maintenance"].indexOf(doc.order_type) !== -1;
+					// order type has been customised then show all the action buttons
+					const order_is_a_custom_sale = ["Sales", "Shopping Cart", "Maintenance"].indexOf(doc.order_type) === -1;
 
 					// delivery note
-					if(flt(doc.per_delivered, 6) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1 && allow_delivery) {
+					if(flt(doc.per_delivered, 6) < 100 && (order_is_a_sale || order_is_a_custom_sale) && allow_delivery) {
 						this.frm.add_custom_button(__('Delivery Note'), () => this.make_delivery_note_based_on_delivery_date(), __('Create'));
 						this.frm.add_custom_button(__('Work Order'), () => this.make_work_order(), __('Create'));
 					}
@@ -161,8 +166,7 @@
 					}
 
 					// material request
-					if(!doc.order_type || ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1
-						&& flt(doc.per_delivered, 6) < 100) {
+					if(!doc.order_type || (order_is_a_sale || order_is_a_custom_sale) && flt(doc.per_delivered, 6) < 100) {
 						this.frm.add_custom_button(__('Material Request'), () => this.make_material_request(), __('Create'));
 						this.frm.add_custom_button(__('Request for Raw Materials'), () => this.make_raw_material_request(), __('Create'));
 					}
@@ -171,14 +175,13 @@
 						this.frm.add_custom_button(__('Purchase Order'), () => this.make_purchase_order(), __('Create'));
 
 					// maintenance
-					if(flt(doc.per_delivered, 2) < 100 &&
-							["Sales", "Shopping Cart"].indexOf(doc.order_type)===-1) {
+					if(flt(doc.per_delivered, 2) < 100 && (order_is_maintenance || order_is_a_custom_sale)) {
 						this.frm.add_custom_button(__('Maintenance Visit'), () => this.make_maintenance_visit(), __('Create'));
 						this.frm.add_custom_button(__('Maintenance Schedule'), () => this.make_maintenance_schedule(), __('Create'));
 					}
 
 					// project
-					if(flt(doc.per_delivered, 2) < 100 && ["Sales", "Shopping Cart"].indexOf(doc.order_type)!==-1 && allow_delivery) {
+					if(flt(doc.per_delivered, 2) < 100 && (order_is_a_sale || order_is_a_custom_sale) && allow_delivery) {
 							this.frm.add_custom_button(__('Project'), () => this.make_project(), __('Create'));
 					}
 
diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json
index 54e87f7..6462d3b 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.json
+++ b/erpnext/selling/doctype/sales_order/sales_order.json
@@ -60,9 +60,9 @@
   "base_total",
   "base_net_total",
   "column_break_33",
+  "total_net_weight",
   "total",
   "net_total",
-  "total_net_weight",
   "taxes_section",
   "tax_category",
   "column_break_38",
@@ -1196,7 +1196,7 @@
  "idx": 105,
  "is_submittable": 1,
  "links": [],
- "modified": "2019-12-30 19:15:28.605085",
+ "modified": "2020-04-17 12:50:39.640534",
  "modified_by": "Administrator",
  "module": "Selling",
  "name": "Sales Order",
diff --git a/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py b/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py
index 28dd056..aa57665 100644
--- a/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py
+++ b/erpnext/selling/report/customer_acquisition_and_loyalty/customer_acquisition_and_loyalty.py
@@ -53,10 +53,11 @@
 				new[1], repeat[1], new[1] + repeat[1]])
 
 	return [
-		_("Year"), _("Month"),
-		_("New Customers") + ":Int",
-		_("Repeat Customers") + ":Int",
-		_("Total") + ":Int",
+		_("Year") + "::100",
+		_("Month") + "::100",
+		_("New Customers") + ":Int:100",
+		_("Repeat Customers") + ":Int:100",
+		_("Total") + ":Int:100",
 		_("New Customer Revenue") + ":Currency:150",
 		_("Repeat Customer Revenue") + ":Currency:150",
 		_("Total Revenue") + ":Currency:150"
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json
index 6f9d83d..9f5dee9 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.json
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.json
@@ -66,9 +66,9 @@
   "base_total",
   "base_net_total",
   "column_break_33",
+  "total_net_weight",
   "total",
   "net_total",
-  "total_net_weight",
   "taxes_section",
   "tax_category",
   "column_break_39",
@@ -1256,7 +1256,7 @@
  "idx": 146,
  "is_submittable": 1,
  "links": [],
- "modified": "2019-12-31 19:17:13.122644",
+ "modified": "2020-04-17 12:51:41.288600",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Delivery Note",
diff --git a/erpnext/stock/doctype/material_request/material_request.js b/erpnext/stock/doctype/material_request/material_request.js
index 6110ea8..b97da69 100644
--- a/erpnext/stock/doctype/material_request/material_request.js
+++ b/erpnext/stock/doctype/material_request/material_request.js
@@ -12,7 +12,8 @@
 			'Purchase Order': 'Purchase Order',
 			'Request for Quotation': 'Request for Quotation',
 			'Supplier Quotation': 'Supplier Quotation',
-			'Work Order': 'Work Order'
+			'Work Order': 'Work Order',
+			'Purchase Receipt': 'Purchase Receipt'
 		};
 
 		// formatter for material request item
@@ -27,11 +28,20 @@
 
 		// set schedule_date
 		set_schedule_date(frm);
-		frm.fields_dict["items"].grid.get_field("warehouse").get_query = function(doc) {
+
+		let filters = {'company': frm.doc.company}
+
+		frm.set_query("warehouse", "items", function() {
 			return {
-				filters: {'company': doc.company}
+				filters: filters
 			};
-		};
+		});
+
+		frm.set_query("set_warehouse", function(){
+			return {
+				filters: filters
+			};
+		});
 	},
 
 	onload_post_render: function(frm) {
@@ -129,12 +139,13 @@
 			source_doctype: "Sales Order",
 			target: frm,
 			setters: {
-				company: frm.doc.company
+				customer: frm.doc.customer || undefined
 			},
 			get_query_filters: {
 				docstatus: 1,
 				status: ["not in", ["Closed", "On Hold"]],
 				per_delivered: ["<", 99.99],
+				company: frm.doc.company
 			}
 		});
 	},
@@ -182,46 +193,46 @@
 					options:"BOM", reqd: 1, get_query: function() {
 						return {filters: { docstatus:1 }};
 					}},
-				{"fieldname":"warehouse", "fieldtype":"Link", "label":__("Warehouse"),
+				{"fieldname":"warehouse", "fieldtype":"Link", "label":__("For Warehouse"),
 					options:"Warehouse", reqd: 1},
 				{"fieldname":"qty", "fieldtype":"Float", "label":__("Quantity"),
 					reqd: 1, "default": 1},
 				{"fieldname":"fetch_exploded", "fieldtype":"Check",
-					"label":__("Fetch exploded BOM (including sub-assemblies)"), "default":1},
-				{fieldname:"fetch", "label":__("Get Items from BOM"), "fieldtype":"Button"}
-			]
-		});
-		d.get_input("fetch").on("click", function() {
-			var values = d.get_values();
-			if(!values) return;
-			values["company"] = frm.doc.company;
-			if(!frm.doc.company) frappe.throw(__("Company field is required"));
-			frappe.call({
-				method: "erpnext.manufacturing.doctype.bom.bom.get_bom_items",
-				args: values,
-				callback: function(r) {
-					if (!r.message) {
-						frappe.throw(__("BOM does not contain any stock item"));
-					} else {
-						erpnext.utils.remove_empty_first_row(frm, "items");
-						$.each(r.message, function(i, item) {
-							var d = frappe.model.add_child(cur_frm.doc, "Material Request Item", "items");
-							d.item_code = item.item_code;
-							d.item_name = item.item_name;
-							d.description = item.description;
-							d.warehouse = values.warehouse;
-							d.uom = item.stock_uom;
-							d.stock_uom = item.stock_uom;
-							d.conversion_factor = 1;
-							d.qty = item.qty;
-							d.project = item.project;
-						});
+					"label":__("Fetch exploded BOM (including sub-assemblies)"), "default":1}
+			],
+			primary_action_label: 'Get Items',
+			primary_action(values) {
+				if(!values) return;
+				values["company"] = frm.doc.company;
+				if(!frm.doc.company) frappe.throw(__("Company field is required"));
+				frappe.call({
+					method: "erpnext.manufacturing.doctype.bom.bom.get_bom_items",
+					args: values,
+					callback: function(r) {
+						if (!r.message) {
+							frappe.throw(__("BOM does not contain any stock item"));
+						} else {
+							erpnext.utils.remove_empty_first_row(frm, "items");
+							$.each(r.message, function(i, item) {
+								var d = frappe.model.add_child(cur_frm.doc, "Material Request Item", "items");
+								d.item_code = item.item_code;
+								d.item_name = item.item_name;
+								d.description = item.description;
+								d.warehouse = values.warehouse;
+								d.uom = item.stock_uom;
+								d.stock_uom = item.stock_uom;
+								d.conversion_factor = 1;
+								d.qty = item.qty;
+								d.project = item.project;
+							});
+						}
+						d.hide();
+						refresh_field("items");
 					}
-					d.hide();
-					refresh_field("items");
-				}
-			});
+				});
+			}
 		});
+
 		d.show();
 	},
 
@@ -248,7 +259,8 @@
 					run_link_triggers: true
 				});
 			},
-			__('Enter Supplier')
+			__('Enter Supplier'),
+			__('Create')
 		)
 	},
 
diff --git a/erpnext/stock/doctype/material_request/material_request.json b/erpnext/stock/doctype/material_request/material_request.json
index d0025d1..536f5fa 100644
--- a/erpnext/stock/doctype/material_request/material_request.json
+++ b/erpnext/stock/doctype/material_request/material_request.json
@@ -1,9 +1,11 @@
 {
+ "actions": [],
  "allow_import": 1,
  "autoname": "naming_series:",
  "creation": "2013-03-07 14:48:38",
  "doctype": "DocType",
  "document_type": "Document",
+ "engine": "InnoDB",
  "field_order": [
   "type_section",
   "naming_series",
@@ -14,6 +16,8 @@
   "schedule_date",
   "company",
   "amended_from",
+  "warehouse_section",
+  "set_warehouse",
   "items_section",
   "scan_barcode",
   "items",
@@ -66,7 +70,7 @@
    "fieldtype": "Select",
    "in_list_view": 1,
    "in_standard_filter": 1,
-   "label": "Type",
+   "label": "Purpose",
    "options": "Purchase\nMaterial Transfer\nMaterial Issue\nManufacture\nCustomer Provided",
    "reqd": 1
   },
@@ -85,7 +89,7 @@
    "allow_on_submit": 1,
    "fieldname": "schedule_date",
    "fieldtype": "Date",
-   "label": "Required Date"
+   "label": "Required By"
   },
   {
    "fieldname": "company",
@@ -190,6 +194,7 @@
    "width": "100px"
   },
   {
+   "depends_on": "eval:doc.docstatus==1",
    "fieldname": "per_ordered",
    "fieldtype": "Percent",
    "label": "% Ordered",
@@ -200,6 +205,7 @@
    "read_only": 1
   },
   {
+   "depends_on": "eval:doc.docstatus==1",
    "fieldname": "per_received",
    "fieldtype": "Percent",
    "label": "% Received",
@@ -270,12 +276,24 @@
    "options": "Job Card",
    "print_hide": 1,
    "read_only": 1
+  },
+  {
+   "fieldname": "warehouse_section",
+   "fieldtype": "Section Break"
+  },
+  {
+   "description": "Sets 'For Warehouse' in each row of the Items table.",
+   "fieldname": "set_warehouse",
+   "fieldtype": "Link",
+   "label": "Set Warehouse",
+   "options": "Warehouse"
   }
  ],
  "icon": "fa fa-ticket",
  "idx": 70,
  "is_submittable": 1,
- "modified": "2019-04-29 11:45:07.570292",
+ "links": [],
+ "modified": "2020-03-02 20:21:09.990867",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Material Request",
diff --git a/erpnext/stock/doctype/material_request/material_request_dashboard.py b/erpnext/stock/doctype/material_request/material_request_dashboard.py
index cbd6478..0e4fb7a 100644
--- a/erpnext/stock/doctype/material_request/material_request_dashboard.py
+++ b/erpnext/stock/doctype/material_request/material_request_dashboard.py
@@ -8,7 +8,12 @@
 		'transactions': [
 			{
 				'label': _('Related'),
-				'items': ['Request for Quotation', 'Supplier Quotation', 'Purchase Order', 'Stock Entry', 'Pick List']
+				'items': ['Request for Quotation', 'Supplier Quotation', 'Purchase Order']
+			},
+			{
+				'label': _('Stock'),
+				'items': ['Stock Entry', 'Purchase Receipt', 'Pick List']
+
 			},
 			{
 				'label': _('Manufacturing'),
diff --git a/erpnext/stock/doctype/material_request_item/material_request_item.json b/erpnext/stock/doctype/material_request_item/material_request_item.json
index 5604913..2bdc268 100644
--- a/erpnext/stock/doctype/material_request_item/material_request_item.json
+++ b/erpnext/stock/doctype/material_request_item/material_request_item.json
@@ -7,36 +7,38 @@
  "engine": "InnoDB",
  "field_order": [
   "item_code",
-  "col_break1",
   "item_name",
+  "col_break1",
+  "schedule_date",
   "section_break_4",
   "description",
   "item_group",
   "brand",
   "image_section",
   "image",
-  "manufacture_details",
-  "manufacturer",
   "column_break_12",
   "manufacturer_part_no",
   "quantity_and_warehouse",
   "qty",
-  "uom",
-  "conversion_factor",
   "stock_uom",
   "warehouse",
   "col_break2",
-  "schedule_date",
-  "rate",
-  "amount",
+  "uom",
+  "conversion_factor",
   "stock_qty",
+  "rate_and_amount_section_break",
+  "rate",
+  "col_break3",
+  "amount",
+  "manufacture_details",
+  "manufacturer",
   "more_info",
   "lead_time_date",
   "sales_order",
   "sales_order_item",
   "production_plan",
   "material_request_plan_item",
-  "col_break3",
+  "col_break4",
   "min_order_qty",
   "projected_qty",
   "actual_qty",
@@ -175,7 +177,7 @@
    "fieldname": "schedule_date",
    "fieldtype": "Date",
    "in_list_view": 1,
-   "label": "Required Date",
+   "label": "Required By",
    "oldfieldname": "schedule_date",
    "oldfieldtype": "Date",
    "print_width": "100px",
@@ -185,14 +187,12 @@
   {
    "fieldname": "rate",
    "fieldtype": "Currency",
-   "label": "Rate",
-   "no_copy": 1
+   "label": "Rate"
   },
   {
    "fieldname": "amount",
    "fieldtype": "Currency",
    "label": "Amount",
-   "no_copy": 1,
    "read_only": 1
   },
   {
@@ -204,6 +204,7 @@
    "read_only": 1
   },
   {
+   "collapsible": 1,
    "fieldname": "more_info",
    "fieldtype": "Section Break",
    "label": "More Information"
@@ -331,6 +332,7 @@
    "read_only": 1
   },
   {
+   "collapsible": 1,
    "fieldname": "accounting_details",
    "fieldtype": "Section Break",
    "label": "Accounting Details"
@@ -389,6 +391,7 @@
    "fieldtype": "Column Break"
   },
   {
+   "collapsible": 1,
    "fieldname": "manufacture_details",
    "fieldtype": "Section Break",
    "label": "Manufacture"
@@ -406,7 +409,16 @@
   {
    "fieldname": "manufacturer_part_no",
    "fieldtype": "Data",
-   "label": "Manufacturer Part Number"
+   "label": "Manufacturer Part Number",
+   "read_only": 1
+  },
+  {
+   "fieldname": "rate_and_amount_section_break",
+   "fieldtype": "Section Break"
+  },
+  {
+   "fieldname": "col_break4",
+   "fieldtype": "Column Break"
   }
  ],
  "idx": 1,
diff --git a/erpnext/stock/doctype/pick_list/test_pick_list.py b/erpnext/stock/doctype/pick_list/test_pick_list.py
index 6b4f73b..1b9ff41 100644
--- a/erpnext/stock/doctype/pick_list/test_pick_list.py
+++ b/erpnext/stock/doctype/pick_list/test_pick_list.py
@@ -111,6 +111,7 @@
 
 		stock_reconciliation = frappe.get_doc({
 			'doctype': 'Stock Reconciliation',
+			'purpose': 'Stock Reconciliation',
 			'company': '_Test Company',
 			'items': [{
 				'item_code': '_Test Serialized Item',
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
index e38bb38..467a206 100755
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
@@ -16,10 +16,10 @@
   "supplier_name",
   "supplier_delivery_note",
   "column_break1",
+  "company",
   "posting_date",
   "posting_time",
   "set_posting_time",
-  "company",
   "is_return",
   "return_against",
   "section_addresses",
@@ -49,19 +49,19 @@
   "items_section",
   "scan_barcode",
   "items",
-  "pricing_rule_details",
-  "pricing_rules",
-  "get_current_stock",
-  "raw_material_details",
-  "supplied_items",
   "section_break0",
   "total_qty",
   "base_total",
   "base_net_total",
   "column_break_27",
+  "total_net_weight",
   "total",
   "net_total",
-  "total_net_weight",
+  "pricing_rule_details",
+  "pricing_rules",
+  "raw_material_details",
+  "get_current_stock",
+  "supplied_items",
   "taxes_charges_section",
   "tax_category",
   "shipping_col",
@@ -113,13 +113,13 @@
   "auto_repeat",
   "printing_settings",
   "letter_head",
-  "select_print_heading",
   "language",
-  "group_same_items",
-  "column_break_97",
-  "other_details",
   "instructions",
+  "column_break_97",
+  "select_print_heading",
+  "other_details",
   "remarks",
+  "group_same_items",
   "transporter_info",
   "transporter_name",
   "column_break5",
@@ -404,6 +404,7 @@
    "fieldtype": "Section Break"
   },
   {
+   "description": "Sets 'Accepted Warehouse' in each row of the items table.",
    "fieldname": "set_warehouse",
    "fieldtype": "Link",
    "label": "Accepted Warehouse",
@@ -411,7 +412,7 @@
    "print_hide": 1
   },
   {
-   "description": "Warehouse where you are maintaining stock of rejected items",
+   "description": "Sets 'Rejected Warehouse' in each row of the items table.",
    "fieldname": "rejected_warehouse",
    "fieldtype": "Link",
    "label": "Rejected Warehouse",
@@ -429,7 +430,7 @@
    "default": "No",
    "fieldname": "is_subcontracted",
    "fieldtype": "Select",
-   "label": "Raw Materials Supplied",
+   "label": "Raw Materials Consumed",
    "oldfieldname": "is_subcontracted",
    "oldfieldtype": "Select",
    "options": "No\nYes",
@@ -465,6 +466,7 @@
    "reqd": 1
   },
   {
+   "collapsible": 1,
    "fieldname": "pricing_rule_details",
    "fieldtype": "Section Break",
    "label": "Pricing Rules"
@@ -477,9 +479,10 @@
    "read_only": 1
   },
   {
+   "depends_on": "supplied_items",
    "fieldname": "get_current_stock",
    "fieldtype": "Button",
-   "label": "Get current stock",
+   "label": "Get Current Stock",
    "oldfieldtype": "Button",
    "options": "get_current_stock",
    "print_hide": 1
@@ -489,7 +492,7 @@
    "collapsible_depends_on": "supplied_items",
    "fieldname": "raw_material_details",
    "fieldtype": "Section Break",
-   "label": "Raw Materials Supplied",
+   "label": "Raw Materials Consumed",
    "oldfieldtype": "Section Break",
    "options": "fa fa-table",
    "print_hide": 1,
@@ -498,7 +501,7 @@
   {
    "fieldname": "supplied_items",
    "fieldtype": "Table",
-   "label": "Supplied Items",
+   "label": "Consumed Items",
    "no_copy": 1,
    "oldfieldname": "pr_raw_material_details",
    "oldfieldtype": "Table",
@@ -1082,7 +1085,7 @@
  "idx": 261,
  "is_submittable": 1,
  "links": [],
- "modified": "2020-04-06 16:31:37.444891",
+ "modified": "2020-04-18 18:02:18.020763",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Purchase Receipt",
@@ -1149,4 +1152,4 @@
  "timeline_field": "supplier",
  "title_field": "title",
  "track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
index b15f23c..bc6bce9 100644
--- a/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
+++ b/erpnext/stock/doctype/purchase_receipt_item/purchase_receipt_item.json
@@ -15,15 +15,11 @@
   "item_name",
   "section_break_4",
   "description",
-  "item_group",
   "brand",
-  "image_section",
+  "image_column",
+  "item_group",
   "image",
   "image_view",
-  "manufacture_details",
-  "manufacturer",
-  "column_break_16",
-  "manufacturer_part_no",
   "received_and_accepted",
   "received_qty",
   "qty",
@@ -32,6 +28,7 @@
   "uom",
   "stock_uom",
   "conversion_factor",
+  "stock_qty",
   "retain_sample",
   "sample_quantity",
   "rate_and_amount",
@@ -60,11 +57,6 @@
   "rm_supp_cost",
   "landed_cost_voucher_amount",
   "billed_amt",
-  "item_weight_details",
-  "weight_per_unit",
-  "total_weight",
-  "column_break_41",
-  "weight_uom",
   "warehouse_and_reference",
   "warehouse",
   "rejected_warehouse",
@@ -77,20 +69,27 @@
   "asset_category",
   "schedule_date",
   "quality_inspection",
-  "stock_qty",
   "purchase_order_item",
   "material_request_item",
   "section_break_45",
   "allow_zero_valuation_rate",
   "bom",
-  "col_break5",
   "serial_no",
+  "col_break5",
+  "include_exploded_items",
   "batch_no",
-  "column_break_48",
   "rejected_serial_no",
   "expense_account",
-  "include_exploded_items",
   "item_tax_rate",
+  "item_weight_details",
+  "weight_per_unit",
+  "total_weight",
+  "column_break_41",
+  "weight_uom",
+  "manufacture_details",
+  "manufacturer",
+  "column_break_16",
+  "manufacturer_part_no",
   "accounting_dimensions_section",
   "project",
   "dimension_col_break",
@@ -526,7 +525,7 @@
   {
    "fieldname": "stock_qty",
    "fieldtype": "Float",
-   "label": "Qty as per Stock UOM",
+   "label": "Accepted Qty as per Stock UOM",
    "oldfieldname": "stock_qty",
    "oldfieldtype": "Currency",
    "print_hide": 1,
@@ -553,7 +552,7 @@
    "fieldname": "batch_no",
    "fieldtype": "Link",
    "in_list_view": 1,
-   "label": "Batch No!",
+   "label": "Batch No",
    "no_copy": 1,
    "oldfieldname": "batch_no",
    "oldfieldtype": "Link",
@@ -561,10 +560,6 @@
    "print_hide": 1
   },
   {
-   "fieldname": "column_break_48",
-   "fieldtype": "Column Break"
-  },
-  {
    "depends_on": "eval:!doc.is_fixed_asset",
    "fieldname": "rejected_serial_no",
    "fieldtype": "Small Text",
@@ -658,6 +653,7 @@
    "read_only": 1
   },
   {
+   "fetch_from": "item_code.brand",
    "fieldname": "brand",
    "fieldtype": "Link",
    "hidden": 1,
@@ -669,9 +665,9 @@
    "read_only": 1
   },
   {
+   "fetch_from": "item_code.item_group",
    "fieldname": "item_group",
    "fieldtype": "Link",
-   "hidden": 1,
    "label": "Item Group",
    "oldfieldname": "item_group",
    "oldfieldtype": "Link",
@@ -749,21 +745,18 @@
    "fieldtype": "Section Break"
   },
   {
-   "collapsible": 1,
-   "fieldname": "image_section",
-   "fieldtype": "Section Break",
-   "label": "Image"
-  },
-  {
    "fieldname": "material_request",
    "fieldtype": "Link",
    "label": "Material Request",
-   "options": "Material Request"
+   "options": "Material Request",
+   "read_only": 1
   },
   {
    "fieldname": "material_request_item",
    "fieldtype": "Data",
-   "label": "Material Request Item"
+   "hidden": 1,
+   "label": "Material Request Item",
+   "read_only": 1
   },
   {
    "fieldname": "expense_account",
@@ -826,12 +819,17 @@
    "ignore_user_permissions": 1,
    "label": "Supplier Warehouse",
    "options": "Warehouse"
+  },
+  {
+   "collapsible": 1,
+   "fieldname": "image_column",
+   "fieldtype": "Column Break"
   }
  ],
  "idx": 1,
  "istable": 1,
  "links": [],
- "modified": "2020-04-07 18:38:21.141558",
+ "modified": "2020-04-10 19:01:21.154963",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Purchase Receipt Item",
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 7cf822b..95f9d46 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -865,14 +865,6 @@
 
 					self.add_to_stock_entry_detail(item_dict)
 
-				if self.purpose != "Send to Subcontractor" and self.purpose in ["Manufacture", "Repack"]:
-					scrap_item_dict = self.get_bom_scrap_material(self.fg_completed_qty)
-					for item in itervalues(scrap_item_dict):
-						if self.pro_doc and self.pro_doc.scrap_warehouse:
-							item["to_warehouse"] = self.pro_doc.scrap_warehouse
-
-					self.add_to_stock_entry_detail(scrap_item_dict, bom_no=self.bom_no)
-
 			# fetch the serial_no of the first stock entry for the second stock entry
 			if self.work_order and self.purpose == "Manufacture":
 				self.set_serial_nos(self.work_order)
@@ -883,9 +875,20 @@
 			if self.purpose in ("Manufacture", "Repack"):
 				self.load_items_from_bom()
 
+		self.set_scrap_items()
 		self.set_actual_qty()
 		self.calculate_rate_and_amount(raise_error_if_no_rate=False)
 
+	def set_scrap_items(self):
+		if self.purpose != "Send to Subcontractor" and self.purpose in ["Manufacture", "Repack"]:
+			scrap_item_dict = self.get_bom_scrap_material(self.fg_completed_qty)
+			for item in itervalues(scrap_item_dict):
+				item.idx = ''
+				if self.pro_doc and self.pro_doc.scrap_warehouse:
+					item["to_warehouse"] = self.pro_doc.scrap_warehouse
+
+			self.add_to_stock_entry_detail(scrap_item_dict, bom_no=self.bom_no)
+
 	def set_work_order_details(self):
 		if not getattr(self, "pro_doc", None):
 			self.pro_doc = frappe._dict()
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json
index 7f4efba..b7d1497 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.json
@@ -4,6 +4,7 @@
  "description": "This tool helps you to update or fix the quantity and valuation of stock in the system. It is typically used to synchronise the system values and what actually exists in your warehouses.",
  "doctype": "DocType",
  "document_type": "Document",
+ "engine": "InnoDB",
  "field_order": [
   "naming_series",
   "company",
@@ -44,11 +45,11 @@
    "reqd": 1
   },
   {
-   "default": "Stock Reconciliation",
    "fieldname": "purpose",
    "fieldtype": "Select",
    "label": "Purpose",
-   "options": "Opening Stock\nStock Reconciliation"
+   "options": "\nOpening Stock\nStock Reconciliation",
+   "reqd": 1
   },
   {
    "fieldname": "col1",
@@ -153,7 +154,7 @@
  "idx": 1,
  "is_submittable": 1,
  "max_attachments": 1,
- "modified": "2019-05-26 09:03:09.542141",
+ "modified": "2020-04-08 17:02:47.196206",
  "modified_by": "Administrator",
  "module": "Stock",
  "name": "Stock Reconciliation",
diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
index e6d7e3f..51d027f 100644
--- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py
@@ -240,6 +240,7 @@
 def create_stock_reconciliation(**args):
 	args = frappe._dict(args)
 	sr = frappe.new_doc("Stock Reconciliation")
+	sr.purpose = args.purpose or "Stock Reconciliation"
 	sr.posting_date = args.posting_date or nowdate()
 	sr.posting_time = args.posting_time or nowtime()
 	sr.set_posting_time = 1
diff --git a/erpnext/stock/reorder_item.py b/erpnext/stock/reorder_item.py
index 9777673..4c721ac 100644
--- a/erpnext/stock/reorder_item.py
+++ b/erpnext/stock/reorder_item.py
@@ -4,6 +4,7 @@
 from __future__ import unicode_literals
 import frappe
 import erpnext
+import json
 from frappe.utils import flt, nowdate, add_days, cint
 from frappe import _
 
@@ -198,19 +199,16 @@
 		subject=_('Auto Material Requests Generated'), message = msg)
 
 def notify_errors(exceptions_list):
-	subject = "[Important] [ERPNext] Auto Reorder Errors"
-	content = """Dear System Manager,
+	subject = _("[Important] [ERPNext] Auto Reorder Errors")
+	content = _("Dear System Manager,") + "<br>" + _("An error occured for certain Items while creating Material Requests based on Re-order level. \
+		Please rectify these issues :") + "<br>"
 
-An error occured for certain Items while creating Material Requests based on Re-order level.
+	for exception in exceptions_list:
+		exception = json.loads(exception)
+		error_message = """<div class='small text-muted'>{0}</div><br>""".format(_(exception.get("message")))
+		content += error_message
 
-Please rectify these issues:
----
-<pre>
-%s
-</pre>
----
-Regards,
-Administrator""" % ("\n\n".join(exceptions_list),)
+	content += _("Regards,") + "<br>" + _("Administrator")
 
 	from frappe.email import sendmail_to_system_managers
 	sendmail_to_system_managers(subject, content)
diff --git a/erpnext/stock/report/stock_balance/stock_balance.py b/erpnext/stock/report/stock_balance/stock_balance.py
index ff03381..ab87ee1 100644
--- a/erpnext/stock/report/stock_balance/stock_balance.py
+++ b/erpnext/stock/report/stock_balance/stock_balance.py
@@ -170,6 +170,8 @@
 	from_date = getdate(filters.get("from_date"))
 	to_date = getdate(filters.get("to_date"))
 
+	float_precision = cint(frappe.db.get_default("float_precision")) or 3
+
 	for d in sle:
 		key = (d.company, d.item_code, d.warehouse)
 		if key not in iwb_map:
@@ -184,7 +186,7 @@
 		qty_dict = iwb_map[(d.company, d.item_code, d.warehouse)]
 
 		if d.voucher_type == "Stock Reconciliation":
-			qty_diff = flt(d.qty_after_transaction) - qty_dict.bal_qty
+			qty_diff = flt(d.qty_after_transaction) - flt(qty_dict.bal_qty)
 		else:
 			qty_diff = flt(d.actual_qty)
 
@@ -195,7 +197,7 @@
 			qty_dict.opening_val += value_diff
 
 		elif d.posting_date >= from_date and d.posting_date <= to_date:
-			if qty_diff > 0:
+			if flt(qty_diff, float_precision) >= 0:
 				qty_dict.in_qty += qty_diff
 				qty_dict.in_val += value_diff
 			else:
@@ -206,16 +208,15 @@
 		qty_dict.bal_qty += qty_diff
 		qty_dict.bal_val += value_diff
 
-	iwb_map = filter_items_with_no_transactions(iwb_map)
+	iwb_map = filter_items_with_no_transactions(iwb_map, float_precision)
 
 	return iwb_map
 
-def filter_items_with_no_transactions(iwb_map):
+def filter_items_with_no_transactions(iwb_map, float_precision):
 	for (company, item, warehouse) in sorted(iwb_map):
 		qty_dict = iwb_map[(company, item, warehouse)]
 
 		no_transactions = True
-		float_precision = cint(frappe.db.get_default("float_precision")) or 3
 		for key, val in iteritems(qty_dict):
 			val = flt(val, float_precision)
 			qty_dict[key] = val
diff --git a/erpnext/support/doctype/issue/issue.py b/erpnext/support/doctype/issue/issue.py
index fd72807..117267f 100644
--- a/erpnext/support/doctype/issue/issue.py
+++ b/erpnext/support/doctype/issue/issue.py
@@ -335,8 +335,13 @@
 
 	ignore_permissions = False
 	if is_website_user():
-		if not filters: filters = []
-		filters.append(("Issue", "customer", "=", customer)) if customer else filters.append(("Issue", "raised_by", "=", user))
+		if not filters: filters = {}
+
+		if customer:
+			filters["customer"] = customer
+		else:
+			filters["raised_by"] = user
+
 		ignore_permissions = True
 
 	return get_list(doctype, txt, filters, limit_start, limit_page_length, ignore_permissions=ignore_permissions)
diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py
index f88ffd4..14674c0 100644
--- a/erpnext/utilities/transaction_base.py
+++ b/erpnext/utilities/transaction_base.py
@@ -126,7 +126,7 @@
 						frappe.msgprint(_("Row #{0}: Rate must be same as {1}: {2} ({3} / {4}) ")
 							.format(d.idx, ref_dt, d.get(ref_dn_field), d.rate, ref_rate))
 						frappe.throw(_("To allow different rates, disable the {0} checkbox in {1}.")
-							.format(frappe.bold("Maintain Same Rate Throughout Sales Cycle"), 
+							.format(frappe.bold(_("Maintain Same Rate Throughout Sales Cycle")),
 							get_link_to_form("Selling Settings", "Selling Settings", frappe.bold("Selling Settings"))))
 
 	def get_link_filters(self, for_doctype):
@@ -179,4 +179,6 @@
 				qty = d.get(f)
 				if qty:
 					if abs(cint(qty) - flt(qty)) > 0.0000001:
-						frappe.throw(_("Quantity ({0}) cannot be a fraction in row {1}").format(qty, d.idx), UOMMustBeIntegerError)
+						frappe.throw(_("Row {1}: Quantity ({0}) cannot be a fraction. To allow this, disable '{2}' in UOM {3}.") \
+							.format(qty, d.idx, frappe.bold(_("Must be Whole Number")), frappe.bold(d.get(uom_field))),
+								UOMMustBeIntegerError)