Merge pull request #24735 from FHenry/fix_create_item_tax_with_salespurchasetax

fix: add item taxes at the same times as sales and purchase taxes
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 342f21b..03c3eb0 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
@@ -22,9 +22,10 @@
 		'allow_account_creation_against_child_company'])
 
 	if parent_company and (not allow_account_creation_against_child_company):
-		frappe.throw(_("""{0} is a child company. Please import accounts against parent company
-			or enable {1} in company master""").format(frappe.bold(company),
-			frappe.bold('Allow Account Creation Against Child Company')), title='Wrong Company')
+		msg = _("{} is a child company. ").format(frappe.bold(company))
+		msg += _("Please import accounts against parent company or enable {} in company master.").format(
+			frappe.bold('Allow Account Creation Against Child Company'))
+		frappe.throw(msg, title=_('Wrong Company'))
 
 	if frappe.db.get_all('GL Entry', {"company": company}, "name", limit=1):
 		return False
@@ -74,7 +75,9 @@
 			if as_dict:
 				data.append({frappe.scrub(header): row[index] for index, header in enumerate(headers)})
 			else:
-				if not row[1]: row[1] = row[0]
+				if not row[1]:
+					row[1] = row[0]
+					row[3] = row[2]
 				data.append(row)
 
 	# convert csv data
@@ -96,7 +99,9 @@
 		if as_dict:
 			data.append({frappe.scrub(header): row[index] for index, header in enumerate(headers)})
 		else:
-			if not row[1]: row[1] = row[0]
+			if not row[1]:
+					row[1] = row[0]
+					row[3] = row[2]
 			data.append(row)
 
 	return data
@@ -147,7 +152,13 @@
 		from frappe import _
 
 		for row in data:
-			account_name, parent_account = row[0:2]
+			account_name, parent_account, account_number, parent_account_number = row[0:4]
+			if account_number:
+				account_name = "{} - {}".format(account_number, account_name)
+			if parent_account_number:
+				parent_account_number = cstr(parent_account_number).strip()
+				parent_account = "{} - {}".format(parent_account_number, parent_account)
+
 			if parent_account == account_name == child:
 				return [parent_account]
 			elif account_name == child:
@@ -159,20 +170,23 @@
 
 	charts_map, paths = {}, []
 
-	line_no = 3
+	line_no = 2
 	error_messages = []
 
 	for i in data:
-		account_name, dummy, account_number, is_group, account_type, root_type = i
+		account_name, parent_account, account_number, parent_account_number, is_group, account_type, root_type = i
 
 		if not account_name:
 			error_messages.append("Row {0}: Please enter Account Name".format(line_no))
 
+		if account_number:
+			account_number = cstr(account_number).strip()
+			account_name = "{} - {}".format(account_number, account_name)
+
 		charts_map[account_name] = {}
 		if cint(is_group) == 1: charts_map[account_name]["is_group"] = is_group
 		if account_type: charts_map[account_name]["account_type"] = account_type
 		if root_type: charts_map[account_name]["root_type"] = root_type
-		if account_number: charts_map[account_name]["account_number"] = account_number
 		path = return_parent(data, account_name)[::-1]
 		paths.append(path) # List of path is created
 		line_no += 1
@@ -221,7 +235,7 @@
 
 def get_template(template_type):
 
-	fields = ["Account Name", "Parent Account", "Account Number", "Is Group", "Account Type", "Root Type"]
+	fields = ["Account Name", "Parent Account", "Account Number", "Parent Account Number", "Is Group", "Account Type", "Root Type"]
 	writer = UnicodeWriter()
 	writer.writerow(fields)
 
@@ -241,23 +255,23 @@
 
 def get_sample_template(writer):
 	template = [
-		["Application Of Funds(Assets)", "", "", 1, "", "Asset"],
-		["Sources Of Funds(Liabilities)", "", "", 1, "", "Liability"],
-		["Equity", "", "", 1, "", "Equity"],
-		["Expenses", "", "", 1, "", "Expense"],
-		["Income", "", "", 1, "", "Income"],
-		["Bank Accounts", "Application Of Funds(Assets)", "", 1, "Bank", "Asset"],
-		["Cash In Hand", "Application Of Funds(Assets)", "", 1, "Cash", "Asset"],
-		["Stock Assets", "Application Of Funds(Assets)", "", 1, "Stock", "Asset"],
-		["Cost Of Goods Sold", "Expenses", "", 0, "Cost of Goods Sold", "Expense"],
-		["Asset Depreciation", "Expenses", "", 0, "Depreciation", "Expense"],
-		["Fixed Assets", "Application Of Funds(Assets)", "", 0, "Fixed Asset", "Asset"],
-		["Accounts Payable", "Sources Of Funds(Liabilities)", "", 0, "Payable", "Liability"],
-		["Accounts Receivable", "Application Of Funds(Assets)", "", 1, "Receivable", "Asset"],
-		["Stock Expenses", "Expenses", "", 0, "Stock Adjustment", "Expense"],
-		["Sample Bank", "Bank Accounts", "", 0, "Bank", "Asset"],
-		["Cash", "Cash In Hand", "", 0, "Cash", "Asset"],
-		["Stores", "Stock Assets", "", 0, "Stock", "Asset"],
+		["Application Of Funds(Assets)", "", "", "", 1, "", "Asset"],
+		["Sources Of Funds(Liabilities)", "", "", "", 1, "", "Liability"],
+		["Equity", "", "", "", 1, "", "Equity"],
+		["Expenses", "", "", "", 1, "", "Expense"],
+		["Income", "", "", "", 1, "", "Income"],
+		["Bank Accounts", "Application Of Funds(Assets)", "", "", 1, "Bank", "Asset"],
+		["Cash In Hand", "Application Of Funds(Assets)", "", "", 1, "Cash", "Asset"],
+		["Stock Assets", "Application Of Funds(Assets)", "", "", 1, "Stock", "Asset"],
+		["Cost Of Goods Sold", "Expenses", "", "", 0, "Cost of Goods Sold", "Expense"],
+		["Asset Depreciation", "Expenses", "", "", 0, "Depreciation", "Expense"],
+		["Fixed Assets", "Application Of Funds(Assets)", "", "", 0, "Fixed Asset", "Asset"],
+		["Accounts Payable", "Sources Of Funds(Liabilities)", "", "", 0, "Payable", "Liability"],
+		["Accounts Receivable", "Application Of Funds(Assets)", "", "", 1, "Receivable", "Asset"],
+		["Stock Expenses", "Expenses", "", "", 0, "Stock Adjustment", "Expense"],
+		["Sample Bank", "Bank Accounts", "", "", 0, "Bank", "Asset"],
+		["Cash", "Cash In Hand", "", "", 0, "Cash", "Asset"],
+		["Stores", "Stock Assets", "", "", 0, "Stock", "Asset"],
 	]
 
 	for row in template:
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 4217711..4076be7 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -1059,7 +1059,8 @@
 			)
 
 	def make_gle_for_rounding_adjustment(self, gl_entries):
-		if flt(self.rounding_adjustment, self.precision("rounding_adjustment")) and self.base_rounding_adjustment:
+		if flt(self.rounding_adjustment, self.precision("rounding_adjustment")) and self.base_rounding_adjustment \
+			and not self.is_internal_transfer():
 			round_off_account, round_off_cost_center = \
 				get_round_off_account_and_cost_center(self.company)
 
diff --git a/erpnext/controllers/selling_controller.py b/erpnext/controllers/selling_controller.py
index c61b67b..fb52c1f 100644
--- a/erpnext/controllers/selling_controller.py
+++ b/erpnext/controllers/selling_controller.py
@@ -142,6 +142,11 @@
 				self.base_net_total * sales_person.allocated_percentage / 100.0,
 				self.precision("allocated_amount", sales_person))
 
+			if sales_person.commission_rate:
+				sales_person.incentives = flt(
+					sales_person.allocated_amount * flt(sales_person.commission_rate) / 100.0, 
+					self.precision("incentives", sales_person))
+
 			total += sales_person.allocated_percentage
 
 		if sales_team and total != 100.0:
diff --git a/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py b/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py
index ca04e8a..3200363 100644
--- a/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py
+++ b/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py
@@ -7,7 +7,7 @@
 def execute():
 	frappe.reload_doc('stock', 'doctype', 'repost_item_valuation')
 
-	reposting_project_deployed_on = frappe.db.get_value("DocType", "Repost Item Valuation", "creation")
+	reposting_project_deployed_on = get_creation_time()
 
 	data = frappe.db.sql('''
 		SELECT
@@ -48,3 +48,7 @@
 		update_gl_entries_after(posting_date, posting_time, company=row.name)
 
 	frappe.db.auto_commit_on_many_writes = 0
+
+def get_creation_time():
+	return frappe.db.sql(''' SELECT create_time FROM
+		INFORMATION_SCHEMA.TABLES where TABLE_NAME = "tabRepost Item Valuation" ''', as_list=1)[0][0]
\ No newline at end of file
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index 7116348..855ff5f 100755
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -17,319 +17,326 @@
 class EndDateCannotBeGreaterThanProjectEndDateError(frappe.ValidationError): pass
 
 class Task(NestedSet):
-    nsm_parent_field = 'parent_task'
+	nsm_parent_field = 'parent_task'
 
-    def get_feed(self):
-        return '{0}: {1}'.format(_(self.status), self.subject)
+	def get_feed(self):
+		return '{0}: {1}'.format(_(self.status), self.subject)
 
-    def get_customer_details(self):
-        cust = frappe.db.sql("select customer_name from `tabCustomer` where name=%s", self.customer)
-        if cust:
-            ret = {'customer_name': cust and cust[0][0] or ''}
-            return ret
+	def get_customer_details(self):
+		cust = frappe.db.sql("select customer_name from `tabCustomer` where name=%s", self.customer)
+		if cust:
+			ret = {'customer_name': cust and cust[0][0] or ''}
+			return ret
 
-    def validate(self):
-        self.validate_dates()
-        self.validate_parent_expected_end_date()
-        self.validate_parent_project_dates()
-        self.validate_progress()
-        self.validate_status()
-        self.update_depends_on()
-        self.validate_dependencies_for_template_task()
+	def validate(self):
+		self.validate_dates()
+		self.validate_parent_expected_end_date()
+		self.validate_parent_project_dates()
+		self.validate_progress()
+		self.validate_status()
+		self.update_depends_on()
+		self.validate_dependencies_for_template_task()
 
-    def validate_dates(self):
-        if self.exp_start_date and self.exp_end_date and getdate(self.exp_start_date) > getdate(self.exp_end_date):
-            frappe.throw(_("{0} can not be greater than {1}").format(frappe.bold("Expected Start Date"), \
-                frappe.bold("Expected End Date")))
+	def validate_dates(self):
+		if self.exp_start_date and self.exp_end_date and getdate(self.exp_start_date) > getdate(self.exp_end_date):
+			frappe.throw(_("{0} can not be greater than {1}").format(frappe.bold("Expected Start Date"), \
+				frappe.bold("Expected End Date")))
 
-        if self.act_start_date and self.act_end_date and getdate(self.act_start_date) > getdate(self.act_end_date):
-            frappe.throw(_("{0} can not be greater than {1}").format(frappe.bold("Actual Start Date"), \
-                frappe.bold("Actual End Date")))
+		if self.act_start_date and self.act_end_date and getdate(self.act_start_date) > getdate(self.act_end_date):
+			frappe.throw(_("{0} can not be greater than {1}").format(frappe.bold("Actual Start Date"), \
+				frappe.bold("Actual End Date")))
 
-    def validate_parent_expected_end_date(self):
-        if self.parent_task:
-            parent_exp_end_date = frappe.db.get_value("Task", self.parent_task, "exp_end_date")
-            if parent_exp_end_date and getdate(self.get("exp_end_date")) > getdate(parent_exp_end_date):
-                frappe.throw(_("Expected End Date should be less than or equal to parent task's Expected End Date {0}.").format(getdate(parent_exp_end_date)))
+	def validate_parent_expected_end_date(self):
+		if self.parent_task:
+			parent_exp_end_date = frappe.db.get_value("Task", self.parent_task, "exp_end_date")
+			if parent_exp_end_date and getdate(self.get("exp_end_date")) > getdate(parent_exp_end_date):
+				frappe.throw(_("Expected End Date should be less than or equal to parent task's Expected End Date {0}.").format(getdate(parent_exp_end_date)))
 
-    def validate_parent_project_dates(self):
-        if not self.project or frappe.flags.in_test:
-            return
+	def validate_parent_project_dates(self):
+		if not self.project or frappe.flags.in_test:
+			return
 
-        expected_end_date = frappe.db.get_value("Project", self.project, "expected_end_date")
+		expected_end_date = frappe.db.get_value("Project", self.project, "expected_end_date")
 
-        if expected_end_date:
-            validate_project_dates(getdate(expected_end_date), self, "exp_start_date", "exp_end_date", "Expected")
-            validate_project_dates(getdate(expected_end_date), self, "act_start_date", "act_end_date", "Actual")
+		if expected_end_date:
+			validate_project_dates(getdate(expected_end_date), self, "exp_start_date", "exp_end_date", "Expected")
+			validate_project_dates(getdate(expected_end_date), self, "act_start_date", "act_end_date", "Actual")
 
-    def validate_status(self):
-        if self.is_template and self.status != "Template":
-            self.status = "Template"
-        if self.status!=self.get_db_value("status") and self.status == "Completed":
-            for d in self.depends_on:
-                if frappe.db.get_value("Task", d.task, "status") not in ("Completed", "Cancelled"):
-                    frappe.throw(_("Cannot complete task {0} as its dependant task {1} are not ccompleted / cancelled.").format(frappe.bold(self.name), frappe.bold(d.task)))
+	def validate_status(self):
+		if self.is_template and self.status != "Template":
+			self.status = "Template"
+		if self.status!=self.get_db_value("status") and self.status == "Completed":
+			for d in self.depends_on:
+				if frappe.db.get_value("Task", d.task, "status") not in ("Completed", "Cancelled"):
+					frappe.throw(_("Cannot complete task {0} as its dependant task {1} are not ccompleted / cancelled.").format(frappe.bold(self.name), frappe.bold(d.task)))
 
-            close_all_assignments(self.doctype, self.name)
+			close_all_assignments(self.doctype, self.name)
 
-    def validate_progress(self):
-        if flt(self.progress or 0) > 100:
-            frappe.throw(_("Progress % for a task cannot be more than 100."))
+	def validate_progress(self):
+		if flt(self.progress or 0) > 100:
+			frappe.throw(_("Progress % for a task cannot be more than 100."))
 
-        if flt(self.progress) == 100:
-            self.status = 'Completed'
+		if flt(self.progress) == 100:
+			self.status = 'Completed'
 
-        if self.status == 'Completed':
-            self.progress = 100
+		if self.status == 'Completed':
+			self.progress = 100
 
-    def validate_dependencies_for_template_task(self):
-        if self.is_template:
-            self.validate_parent_template_task()
-            self.validate_depends_on_tasks()
-        
-    def validate_parent_template_task(self):
-        if self.parent_task:
-            if not frappe.db.get_value("Task", self.parent_task, "is_template"):
-                parent_task_format = """<a href="#Form/Task/{0}">{0}</a>""".format(self.parent_task)
-                frappe.throw(_("Parent Task {0} is not a Template Task").format(parent_task_format))
-                
-    def validate_depends_on_tasks(self):
-        if self.depends_on:
-            for task in self.depends_on:
-                if not frappe.db.get_value("Task", task.task, "is_template"):
-                    dependent_task_format = """<a href="#Form/Task/{0}">{0}</a>""".format(task.task)
-                    frappe.throw(_("Dependent Task {0} is not a Template Task").format(dependent_task_format))
+	def validate_dependencies_for_template_task(self):
+		if self.is_template:
+			self.validate_parent_template_task()
+			self.validate_depends_on_tasks()
 
-    def update_depends_on(self):
-        depends_on_tasks = self.depends_on_tasks or ""
-        for d in self.depends_on:
-            if d.task and d.task not in depends_on_tasks:
-                depends_on_tasks += d.task + ","
-        self.depends_on_tasks = depends_on_tasks
+	def validate_parent_template_task(self):
+		if self.parent_task:
+			if not frappe.db.get_value("Task", self.parent_task, "is_template"):
+				parent_task_format = """<a href="#Form/Task/{0}">{0}</a>""".format(self.parent_task)
+				frappe.throw(_("Parent Task {0} is not a Template Task").format(parent_task_format))
 
-    def update_nsm_model(self):
-        frappe.utils.nestedset.update_nsm(self)
+	def validate_depends_on_tasks(self):
+		if self.depends_on:
+			for task in self.depends_on:
+				if not frappe.db.get_value("Task", task.task, "is_template"):
+					dependent_task_format = """<a href="#Form/Task/{0}">{0}</a>""".format(task.task)
+					frappe.throw(_("Dependent Task {0} is not a Template Task").format(dependent_task_format))
 
-    def on_update(self):
-        self.update_nsm_model()
-        self.check_recursion()
-        self.reschedule_dependent_tasks()
-        self.update_project()
-        self.unassign_todo()
-        self.populate_depends_on()
+	def update_depends_on(self):
+		depends_on_tasks = self.depends_on_tasks or ""
+		for d in self.depends_on:
+			if d.task and d.task not in depends_on_tasks:
+				depends_on_tasks += d.task + ","
+		self.depends_on_tasks = depends_on_tasks
 
-    def unassign_todo(self):
-        if self.status == "Completed":
-            close_all_assignments(self.doctype, self.name)
-        if self.status == "Cancelled":
-            clear(self.doctype, self.name)
+	def update_nsm_model(self):
+		frappe.utils.nestedset.update_nsm(self)
 
-    def update_total_expense_claim(self):
-        self.total_expense_claim = frappe.db.sql("""select sum(total_sanctioned_amount) from `tabExpense Claim`
-            where project = %s and task = %s and docstatus=1""",(self.project, self.name))[0][0]
+	def on_update(self):
+		self.update_nsm_model()
+		self.check_recursion()
+		self.reschedule_dependent_tasks()
+		self.update_project()
+		self.unassign_todo()
+		self.populate_depends_on()
 
-    def update_time_and_costing(self):
-        tl = frappe.db.sql("""select min(from_time) as start_date, max(to_time) as end_date,
-            sum(billing_amount) as total_billing_amount, sum(costing_amount) as total_costing_amount,
-            sum(hours) as time from `tabTimesheet Detail` where task = %s and docstatus=1"""
-            ,self.name, as_dict=1)[0]
-        if self.status == "Open":
-            self.status = "Working"
-        self.total_costing_amount= tl.total_costing_amount
-        self.total_billing_amount= tl.total_billing_amount
-        self.actual_time= tl.time
-        self.act_start_date= tl.start_date
-        self.act_end_date= tl.end_date
+	def unassign_todo(self):
+		if self.status == "Completed":
+			close_all_assignments(self.doctype, self.name)
+		if self.status == "Cancelled":
+			clear(self.doctype, self.name)
 
-    def update_project(self):
-        if self.project and not self.flags.from_project:
-            frappe.get_cached_doc("Project", self.project).update_project()
+	def update_total_expense_claim(self):
+		self.total_expense_claim = frappe.db.sql("""select sum(total_sanctioned_amount) from `tabExpense Claim`
+			where project = %s and task = %s and docstatus=1""",(self.project, self.name))[0][0]
 
-    def check_recursion(self):
-        if self.flags.ignore_recursion_check: return
-        check_list = [['task', 'parent'], ['parent', 'task']]
-        for d in check_list:
-            task_list, count = [self.name], 0
-            while (len(task_list) > count ):
-                tasks = frappe.db.sql(" select %s from `tabTask Depends On` where %s = %s " %
-                    (d[0], d[1], '%s'), cstr(task_list[count]))
-                count = count + 1
-                for b in tasks:
-                    if b[0] == self.name:
-                        frappe.throw(_("Circular Reference Error"), CircularReferenceError)
-                    if b[0]:
-                        task_list.append(b[0])
+	def update_time_and_costing(self):
+		tl = frappe.db.sql("""select min(from_time) as start_date, max(to_time) as end_date,
+			sum(billing_amount) as total_billing_amount, sum(costing_amount) as total_costing_amount,
+			sum(hours) as time from `tabTimesheet Detail` where task = %s and docstatus=1"""
+			,self.name, as_dict=1)[0]
+		if self.status == "Open":
+			self.status = "Working"
+		self.total_costing_amount= tl.total_costing_amount
+		self.total_billing_amount= tl.total_billing_amount
+		self.actual_time= tl.time
+		self.act_start_date= tl.start_date
+		self.act_end_date= tl.end_date
 
-                if count == 15:
-                    break
+	def update_project(self):
+		if self.project and not self.flags.from_project:
+			frappe.get_cached_doc("Project", self.project).update_project()
 
-    def reschedule_dependent_tasks(self):
-        end_date = self.exp_end_date or self.act_end_date
-        if end_date:
-            for task_name in frappe.db.sql("""
-                select name from `tabTask` as parent
-                where parent.project = %(project)s
-                    and parent.name in (
-                        select parent from `tabTask Depends On` as child
-                        where child.task = %(task)s and child.project = %(project)s)
-            """, {'project': self.project, 'task':self.name }, as_dict=1):
-                task = frappe.get_doc("Task", task_name.name)
-                if task.exp_start_date and task.exp_end_date and task.exp_start_date < getdate(end_date) and task.status == "Open":
-                    task_duration = date_diff(task.exp_end_date, task.exp_start_date)
-                    task.exp_start_date = add_days(end_date, 1)
-                    task.exp_end_date = add_days(task.exp_start_date, task_duration)
-                    task.flags.ignore_recursion_check = True
-                    task.save()
+	def check_recursion(self):
+		if self.flags.ignore_recursion_check: return
+		check_list = [['task', 'parent'], ['parent', 'task']]
+		for d in check_list:
+			task_list, count = [self.name], 0
+			while (len(task_list) > count ):
+				tasks = frappe.db.sql(" select %s from `tabTask Depends On` where %s = %s " %
+					(d[0], d[1], '%s'), cstr(task_list[count]))
+				count = count + 1
+				for b in tasks:
+					if b[0] == self.name:
+						frappe.throw(_("Circular Reference Error"), CircularReferenceError)
+					if b[0]:
+						task_list.append(b[0])
 
-    def has_webform_permission(self):
-        project_user = frappe.db.get_value("Project User", {"parent": self.project, "user":frappe.session.user} , "user")
-        if project_user:
-            return True
+				if count == 15:
+					break
 
-    def populate_depends_on(self):
-        if self.parent_task:
-            parent = frappe.get_doc('Task', self.parent_task)
-            if self.name not in [row.task for row in parent.depends_on]:
-                parent.append("depends_on", {
-                    "doctype": "Task Depends On",
-                    "task": self.name,
-                    "subject": self.subject
-                })
-                parent.save()
+	def reschedule_dependent_tasks(self):
+		end_date = self.exp_end_date or self.act_end_date
+		if end_date:
+			for task_name in frappe.db.sql("""
+				select name from `tabTask` as parent
+				where parent.project = %(project)s
+					and parent.name in (
+						select parent from `tabTask Depends On` as child
+						where child.task = %(task)s and child.project = %(project)s)
+			""", {'project': self.project, 'task':self.name }, as_dict=1):
+				task = frappe.get_doc("Task", task_name.name)
+				if task.exp_start_date and task.exp_end_date and task.exp_start_date < getdate(end_date) and task.status == "Open":
+					task_duration = date_diff(task.exp_end_date, task.exp_start_date)
+					task.exp_start_date = add_days(end_date, 1)
+					task.exp_end_date = add_days(task.exp_start_date, task_duration)
+					task.flags.ignore_recursion_check = True
+					task.save()
 
-    def on_trash(self):
-        if check_if_child_exists(self.name):
-            throw(_("Child Task exists for this Task. You can not delete this Task."))
+	def has_webform_permission(self):
+		project_user = frappe.db.get_value("Project User", {"parent": self.project, "user":frappe.session.user} , "user")
+		if project_user:
+			return True
 
-        self.update_nsm_model()
+	def populate_depends_on(self):
+		if self.parent_task:
+			parent = frappe.get_doc('Task', self.parent_task)
+			if self.name not in [row.task for row in parent.depends_on]:
+				parent.append("depends_on", {
+					"doctype": "Task Depends On",
+					"task": self.name,
+					"subject": self.subject
+				})
+				parent.save()
 
-    def after_delete(self):
-        self.update_project()
+	def on_trash(self):
+		if check_if_child_exists(self.name):
+			throw(_("Child Task exists for this Task. You can not delete this Task."))
 
-    def update_status(self):
-        if self.status not in ('Cancelled', 'Completed') and self.exp_end_date:
-            from datetime import datetime
-            if self.exp_end_date < datetime.now().date():
-                self.db_set('status', 'Overdue', update_modified=False)
-                self.update_project()
+		self.update_nsm_model()
+
+	def after_delete(self):
+		self.update_project()
+
+	def update_status(self):
+		if self.status not in ('Cancelled', 'Completed') and self.exp_end_date:
+			from datetime import datetime
+			if self.exp_end_date < datetime.now().date():
+				self.db_set('status', 'Overdue', update_modified=False)
+				self.update_project()
 
 @frappe.whitelist()
 def check_if_child_exists(name):
-    child_tasks = frappe.get_all("Task", filters={"parent_task": name})
-    child_tasks = [get_link_to_form("Task", task.name) for task in child_tasks]
-    return child_tasks
+	child_tasks = frappe.get_all("Task", filters={"parent_task": name})
+	child_tasks = [get_link_to_form("Task", task.name) for task in child_tasks]
+	return child_tasks
 
 
 @frappe.whitelist()
 @frappe.validate_and_sanitize_search_inputs
 def get_project(doctype, txt, searchfield, start, page_len, filters):
-    from erpnext.controllers.queries import get_match_cond
-    return frappe.db.sql(""" select name from `tabProject`
-            where %(key)s like %(txt)s
-                %(mcond)s
-            order by name
-            limit %(start)s, %(page_len)s""" % {
-                'key': searchfield,
-                'txt': frappe.db.escape('%' + txt + '%'),
-                'mcond':get_match_cond(doctype),
-                'start': start,
-                'page_len': page_len
-            })
+	from erpnext.controllers.queries import get_match_cond
+	meta = frappe.get_meta(doctype)
+	searchfields = meta.get_search_fields()
+	search_columns = ", " + ", ".join(searchfields) if searchfields else ''
+	search_cond = " or " + " or ".join([field + " like %(txt)s" for field in searchfields])
+
+	return frappe.db.sql(""" select name {search_columns} from `tabProject`
+		where %(key)s like %(txt)s
+			%(mcond)s
+			{search_condition}
+		order by name
+		limit %(start)s, %(page_len)s""".format(search_columns = search_columns,
+			search_condition=search_cond), {
+			'key': searchfield,
+			'txt': '%' + txt + '%',
+			'mcond':get_match_cond(doctype),
+			'start': start,
+			'page_len': page_len
+		})
 
 
 @frappe.whitelist()
 def set_multiple_status(names, status):
-    names = json.loads(names)
-    for name in names:
-        task = frappe.get_doc("Task", name)
-        task.status = status
-        task.save()
+	names = json.loads(names)
+	for name in names:
+		task = frappe.get_doc("Task", name)
+		task.status = status
+		task.save()
 
 def set_tasks_as_overdue():
-    tasks = frappe.get_all("Task", filters={"status": ["not in", ["Cancelled", "Completed"]]}, fields=["name", "status", "review_date"])
-    for task in tasks:
-        if task.status == "Pending Review":
-            if getdate(task.review_date) > getdate(today()):
-                continue
-        frappe.get_doc("Task", task.name).update_status()
+	tasks = frappe.get_all("Task", filters={"status": ["not in", ["Cancelled", "Completed"]]}, fields=["name", "status", "review_date"])
+	for task in tasks:
+		if task.status == "Pending Review":
+			if getdate(task.review_date) > getdate(today()):
+				continue
+		frappe.get_doc("Task", task.name).update_status()
 
 
 @frappe.whitelist()
 def make_timesheet(source_name, target_doc=None, ignore_permissions=False):
-    def set_missing_values(source, target):
-        target.append("time_logs", {
-            "hours": source.actual_time,
-            "completed": source.status == "Completed",
-            "project": source.project,
-            "task": source.name
-        })
+	def set_missing_values(source, target):
+		target.append("time_logs", {
+			"hours": source.actual_time,
+			"completed": source.status == "Completed",
+			"project": source.project,
+			"task": source.name
+		})
 
-    doclist = get_mapped_doc("Task", source_name, {
-            "Task": {
-                "doctype": "Timesheet"
-            }
-        }, target_doc, postprocess=set_missing_values, ignore_permissions=ignore_permissions)
+	doclist = get_mapped_doc("Task", source_name, {
+			"Task": {
+				"doctype": "Timesheet"
+			}
+		}, target_doc, postprocess=set_missing_values, ignore_permissions=ignore_permissions)
 
-    return doclist
+	return doclist
 
 
 @frappe.whitelist()
 def get_children(doctype, parent, task=None, project=None, is_root=False):
 
-    filters = [['docstatus', '<', '2']]
+	filters = [['docstatus', '<', '2']]
 
-    if task:
-        filters.append(['parent_task', '=', task])
-    elif parent and not is_root:
-        # via expand child
-        filters.append(['parent_task', '=', parent])
-    else:
-        filters.append(['ifnull(`parent_task`, "")', '=', ''])
+	if task:
+		filters.append(['parent_task', '=', task])
+	elif parent and not is_root:
+		# via expand child
+		filters.append(['parent_task', '=', parent])
+	else:
+		filters.append(['ifnull(`parent_task`, "")', '=', ''])
 
-    if project:
-        filters.append(['project', '=', project])
+	if project:
+		filters.append(['project', '=', project])
 
-    tasks = frappe.get_list(doctype, fields=[
-        'name as value',
-        'subject as title',
-        'is_group as expandable'
-    ], filters=filters, order_by='name')
+	tasks = frappe.get_list(doctype, fields=[
+		'name as value',
+		'subject as title',
+		'is_group as expandable'
+	], filters=filters, order_by='name')
 
-    # return tasks
-    return tasks
+	# return tasks
+	return tasks
 
 @frappe.whitelist()
 def add_node():
-    from frappe.desk.treeview import make_tree_args
-    args = frappe.form_dict
-    args.update({
-        "name_field": "subject"
-    })
-    args = make_tree_args(**args)
+	from frappe.desk.treeview import make_tree_args
+	args = frappe.form_dict
+	args.update({
+		"name_field": "subject"
+	})
+	args = make_tree_args(**args)
 
-    if args.parent_task == 'All Tasks' or args.parent_task == args.project:
-        args.parent_task = None
+	if args.parent_task == 'All Tasks' or args.parent_task == args.project:
+		args.parent_task = None
 
-    frappe.get_doc(args).insert()
+	frappe.get_doc(args).insert()
 
 @frappe.whitelist()
 def add_multiple_tasks(data, parent):
-    data = json.loads(data)
-    new_doc = {'doctype': 'Task', 'parent_task': parent if parent!="All Tasks" else ""}
-    new_doc['project'] = frappe.db.get_value('Task', {"name": parent}, 'project') or ""
+	data = json.loads(data)
+	new_doc = {'doctype': 'Task', 'parent_task': parent if parent!="All Tasks" else ""}
+	new_doc['project'] = frappe.db.get_value('Task', {"name": parent}, 'project') or ""
 
-    for d in data:
-        if not d.get("subject"): continue
-        new_doc['subject'] = d.get("subject")
-        new_task = frappe.get_doc(new_doc)
-        new_task.insert()
+	for d in data:
+		if not d.get("subject"): continue
+		new_doc['subject'] = d.get("subject")
+		new_task = frappe.get_doc(new_doc)
+		new_task.insert()
 
 def on_doctype_update():
-    frappe.db.add_index("Task", ["lft", "rgt"])
+	frappe.db.add_index("Task", ["lft", "rgt"])
 
 def validate_project_dates(project_end_date, task, task_start, task_end, actual_or_expected_date):
-    if task.get(task_start) and date_diff(project_end_date, getdate(task.get(task_start))) < 0:
-        frappe.throw(_("Task's {0} Start Date cannot be after Project's End Date.").format(actual_or_expected_date))
+	if task.get(task_start) and date_diff(project_end_date, getdate(task.get(task_start))) < 0:
+		frappe.throw(_("Task's {0} Start Date cannot be after Project's End Date.").format(actual_or_expected_date))
 
-    if task.get(task_end) and date_diff(project_end_date, getdate(task.get(task_end))) < 0:
-        frappe.throw(_("Task's {0} End Date cannot be after Project's End Date.").format(actual_or_expected_date))
+	if task.get(task_end) and date_diff(project_end_date, getdate(task.get(task_end))) < 0:
+		frappe.throw(_("Task's {0} End Date cannot be after Project's End Date.").format(actual_or_expected_date))
diff --git a/erpnext/quality_management/doctype/non_conformance/non_conformance.json b/erpnext/quality_management/doctype/non_conformance/non_conformance.json
index bfeb96b..8dfe2d6 100644
--- a/erpnext/quality_management/doctype/non_conformance/non_conformance.json
+++ b/erpnext/quality_management/doctype/non_conformance/non_conformance.json
@@ -70,18 +70,18 @@
   },
   {
    "fieldname": "corrective_action",
-   "fieldtype": "Text",
+   "fieldtype": "Text Editor",
    "label": "Corrective Action"
   },
   {
    "fieldname": "preventive_action",
-   "fieldtype": "Text",
+   "fieldtype": "Text Editor",
    "label": "Preventive Action"
   }
  ],
  "index_web_pages_for_search": 1,
  "links": [],
- "modified": "2020-10-26 15:27:47.247814",
+ "modified": "2021-02-26 15:27:47.247814",
  "modified_by": "Administrator",
  "module": "Quality Management",
  "name": "Non Conformance",
@@ -115,4 +115,4 @@
  "sort_field": "modified",
  "sort_order": "DESC",
  "track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/erpnext/regional/india/e_invoice/utils.py b/erpnext/regional/india/e_invoice/utils.py
index eea85cd..96f7f1b 100644
--- a/erpnext/regional/india/e_invoice/utils.py
+++ b/erpnext/regional/india/e_invoice/utils.py
@@ -202,9 +202,11 @@
 		item[attr] = 0
 
 	for t in invoice.taxes:
-		# this contains item wise tax rate & tax amount (incl. discount)
-		item_tax_detail = json.loads(t.item_wise_tax_detail).get(item.item_code)
-		if t.account_head in gst_accounts_list:
+		is_applicable = t.tax_amount and t.account_head in gst_accounts_list
+		if is_applicable:
+			# this contains item wise tax rate & tax amount (incl. discount)
+			item_tax_detail = json.loads(t.item_wise_tax_detail).get(item.item_code)
+
 			item_tax_rate = item_tax_detail[0]
 			# item tax amount excluding discount amount
 			item_tax_amount = (item_tax_rate / 100) * item.base_net_amount
@@ -229,7 +231,7 @@
 
 	if invoice.apply_discount_on == 'Net Total' and invoice.discount_amount:
 		invoice_value_details.base_total = abs(invoice.base_total)
-		invoice_value_details.invoice_discount_amt = invoice.base_discount_amount
+		invoice_value_details.invoice_discount_amt = abs(invoice.base_discount_amount)
 	else:
 		invoice_value_details.base_total = abs(invoice.base_net_total)
 		# since tax already considers discount amount
diff --git a/erpnext/selling/page/point_of_sale/pos_controller.js b/erpnext/selling/page/point_of_sale/pos_controller.js
index 338a3cc..74b4bb0 100644
--- a/erpnext/selling/page/point_of_sale/pos_controller.js
+++ b/erpnext/selling/page/point_of_sale/pos_controller.js
@@ -498,10 +498,11 @@
 
 	async on_cart_update(args) {
 		frappe.dom.freeze();
+		let item_row = undefined;
 		try {
 			let { field, value, item } = args;
 			const { item_code, batch_no, serial_no, uom } = item;
-			let item_row = this.get_item_from_frm(item_code, batch_no, uom);
+			item_row = this.get_item_from_frm(item_code, batch_no, uom);
 
 			const item_selected_from_selector = field === 'qty' && value === "+1"
 
@@ -553,10 +554,12 @@
 				this.check_serial_batch_selection_needed(item_row) && this.edit_item_details_of(item_row);
 				this.update_cart_html(item_row);
 			}
+
 		} catch (error) {
 			console.log(error);
 		} finally {
 			frappe.dom.unfreeze();
+			return item_row;
 		}
 	}
 
diff --git a/erpnext/selling/page/point_of_sale/pos_item_cart.js b/erpnext/selling/page/point_of_sale/pos_item_cart.js
index 044e803..9ab9eef 100644
--- a/erpnext/selling/page/point_of_sale/pos_item_cart.js
+++ b/erpnext/selling/page/point_of_sale/pos_item_cart.js
@@ -472,7 +472,8 @@
 		if (!frm) frm = this.events.get_frm();
 
 		this.render_net_total(frm.doc.net_total);
-		this.render_grand_total(frm.doc.grand_total);
+		const grand_total = cint(frappe.sys_defaults.disable_rounded_total) ? frm.doc.grand_total : frm.doc.rounded_total;
+		this.render_grand_total(grand_total);
 
 		const taxes = frm.doc.taxes.map(t => {
 			return {
diff --git a/erpnext/selling/page/point_of_sale/pos_item_selector.js b/erpnext/selling/page/point_of_sale/pos_item_selector.js
index 7c116e9..e0d5b73 100644
--- a/erpnext/selling/page/point_of_sale/pos_item_selector.js
+++ b/erpnext/selling/page/point_of_sale/pos_item_selector.js
@@ -152,6 +152,10 @@
 		this.item_group_field.toggle_label(false);
 	}
 
+	set_search_value(value) {
+		$(this.search_field.$input[0]).val(value).trigger("input");
+	}
+
 	bind_events() {
 		const me = this;
 		window.onScan = onScan;
@@ -159,7 +163,7 @@
 			onScan: (sScancode) => {
 				if (this.search_field && this.$component.is(':visible')) {
 					this.search_field.set_focus();
-					$(this.search_field.$input[0]).val(sScancode).trigger("input");
+					this.set_search_value(sScancode);
 					this.barcode_scanned = true;
 				}
 			}
@@ -178,6 +182,7 @@
 			uom = uom === "undefined" ? undefined : uom;
 
 			me.events.item_selected({ field: 'qty', value: "+1", item: { item_code, batch_no, serial_no, uom }});
+			me.set_search_value('');
 		});
 
 		this.search_field.$input.on('input', (e) => {
diff --git a/erpnext/selling/page/point_of_sale/pos_payment.js b/erpnext/selling/page/point_of_sale/pos_payment.js
index bcbac3b..22a279d 100644
--- a/erpnext/selling/page/point_of_sale/pos_payment.js
+++ b/erpnext/selling/page/point_of_sale/pos_payment.js
@@ -223,7 +223,8 @@
 
 			if (success) {
 				title = __("Payment Received");
-				if (amount >= doc.grand_total) {
+				const grand_total = cint(frappe.sys_defaults.disable_rounded_total) ? doc.grand_total : doc.rounded_total;
+				if (amount >= grand_total) {
 					frappe.dom.unfreeze();
 					message = __("Payment of {0} received successfully.", [format_currency(amount, doc.currency, 0)]);
 					this.events.submit_invoice();
@@ -243,7 +244,8 @@
 
 	auto_set_remaining_amount() {
 		const doc = this.events.get_frm().doc;
-		const remaining_amount = doc.grand_total - doc.paid_amount;
+		const grand_total = cint(frappe.sys_defaults.disable_rounded_total) ? doc.grand_total : doc.rounded_total;
+		const remaining_amount = grand_total - doc.paid_amount;
 		const current_value = this.selected_mode ? this.selected_mode.get_value() : undefined;
 		if (!current_value && remaining_amount > 0 && this.selected_mode) {
 			this.selected_mode.set_value(remaining_amount);
@@ -389,7 +391,7 @@
 	}
 
 	attach_cash_shortcuts(doc) {
-		const grand_total = doc.grand_total;
+		const grand_total = cint(frappe.sys_defaults.disable_rounded_total) ? doc.grand_total : doc.rounded_total;
 		const currency = doc.currency;
 
 		const shortcuts = this.get_cash_shortcuts(flt(grand_total));
@@ -499,7 +501,8 @@
 	update_totals_section(doc) {
 		if (!doc) doc = this.events.get_frm().doc;
 		const paid_amount = doc.paid_amount;
-		const remaining = doc.grand_total - doc.paid_amount;
+		const grand_total = cint(frappe.sys_defaults.disable_rounded_total) ? doc.grand_total : doc.rounded_total;
+		const remaining = grand_total - doc.paid_amount;
 		const change = doc.change_amount || remaining <= 0 ? -1 * remaining : undefined;
 		const currency = doc.currency;
 		const label = change ? __('Change') : __('To Be Paid');
@@ -507,7 +510,7 @@
 		this.$totals.html(
 			`<div class="col">
 				<div class="total-label">Grand Total</div>
-				<div class="value">${format_currency(doc.grand_total, currency)}</div>
+				<div class="value">${format_currency(grand_total, currency)}</div>
 			</div>
 			<div class="seperator-y"></div>
 			<div class="col">
diff --git a/erpnext/stock/__init__.py b/erpnext/stock/__init__.py
index 9e240cc..283f7d5 100644
--- a/erpnext/stock/__init__.py
+++ b/erpnext/stock/__init__.py
@@ -38,7 +38,7 @@
 			frappe.flags.warehouse_account_map[company] = warehouse_account
 		else:
 			frappe.flags.warehouse_account_map = warehouse_account
-	
+
 	return frappe.flags.warehouse_account_map.get(company) or frappe.flags.warehouse_account_map
 
 def get_warehouse_account(warehouse, warehouse_account=None):
@@ -64,6 +64,10 @@
 	if not account and warehouse.company:
 		account = get_company_default_inventory_account(warehouse.company)
 
+	if not account and warehouse.company:
+		account = frappe.db.get_value('Account',
+			{'account_type': 'Stock', 'is_group': 0, 'company': warehouse.company}, 'name')
+
 	if not account and warehouse.company and not warehouse.is_group:
 		frappe.throw(_("Please set Account in Warehouse {0} or Default Inventory Account in Company {1}")
 			.format(warehouse.name, warehouse.company))
diff --git a/erpnext/stock/doctype/batch/batch.py b/erpnext/stock/doctype/batch/batch.py
index c8424f1..8fdda56 100644
--- a/erpnext/stock/doctype/batch/batch.py
+++ b/erpnext/stock/doctype/batch/batch.py
@@ -93,7 +93,7 @@
 
 			if create_new_batch:
 				if batch_number_series:
-					self.batch_id = make_autoname(batch_number_series)
+					self.batch_id = make_autoname(batch_number_series, doc=self)
 				elif batch_uses_naming_series():
 					self.batch_id = self.get_name_from_naming_series()
 				else: