Merge pull request #21401 from rohitwaghchaure/fixed-taget-warehouse-mandatory-issue

fix: make target warehouse field mandatory while saving the work order
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/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index b7c97a7..05f0147 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};
@@ -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/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/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/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/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/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/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_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..a83d193 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -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/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/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/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/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/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index 3443abc..4296447 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -1412,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]);
 							}
 						}
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