GL Entry on asset sale (#12514)

* GL Entry on asset sale

* Asset sale test case fixed
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index c457f9a..477e37d 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -675,28 +675,28 @@
 		# income account gl entries
 		for item in self.get("items"):
 			if flt(item.base_net_amount):
-				account_currency = get_account_currency(item.income_account)
-				gl_entries.append(
-					self.get_gl_dict({
-						"account": item.income_account,
-						"against": self.customer,
-						"credit": item.base_net_amount,
-						"credit_in_account_currency": item.base_net_amount \
-							if account_currency==self.company_currency else item.net_amount,
-						"cost_center": item.cost_center
-					}, account_currency)
-				)
-
 				if item.is_fixed_asset:
 					asset = frappe.get_doc("Asset", item.asset)
 
-					fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset, is_sale=True)
+					fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset, item.base_net_amount)
 					for gle in fixed_asset_gl_entries:
 						gle["against"] = self.customer
 						gl_entries.append(self.get_gl_dict(gle))
 
 					asset.db_set("disposal_date", self.posting_date)
 					asset.set_status("Sold" if self.docstatus==1 else None)
+				else:
+					account_currency = get_account_currency(item.income_account)
+					gl_entries.append(
+						self.get_gl_dict({
+							"account": item.income_account,
+							"against": self.customer,
+							"credit": item.base_net_amount,
+							"credit_in_account_currency": item.base_net_amount \
+								if account_currency==self.company_currency else item.net_amount,
+							"cost_center": item.cost_center
+						}, account_currency)
+					)
 
 		# expense account gl entries
 		if cint(self.update_stock) and \
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index 857aade..8bba0b6 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -51,9 +51,6 @@
 				if not self.get(field):
 					self.set(field, value)
 
-		self.value_after_depreciation = (flt(self.gross_purchase_amount) -
-			flt(self.opening_accumulated_depreciation))
-
 	def validate_asset_values(self):
 		if flt(self.expected_value_after_useful_life) >= flt(self.gross_purchase_amount):
 			frappe.throw(_("Expected Value After Useful Life must be less than Gross Purchase Amount"))
@@ -61,7 +58,10 @@
 		if not flt(self.gross_purchase_amount):
 			frappe.throw(_("Gross Purchase Amount is mandatory"), frappe.MandatoryError)
 
-		if not self.is_existing_asset and self.calculate_depreciation:
+		if not self.calculate_depreciation:
+			return
+
+		if not self.is_existing_asset:
 			self.opening_accumulated_depreciation = 0
 			self.number_of_depreciations_booked = 0
 			if not self.next_depreciation_date:
@@ -81,6 +81,9 @@
 			if cint(self.number_of_depreciations_booked) > cint(self.total_number_of_depreciations):
 				frappe.throw(_("Number of Depreciations Booked cannot be greater than Total Number of Depreciations"))
 
+		self.value_after_depreciation = (flt(self.gross_purchase_amount) -
+			flt(self.opening_accumulated_depreciation))
+
 		if self.next_depreciation_date and getdate(self.next_depreciation_date) < getdate(nowdate()):
 			frappe.msgprint(_("Next Depreciation Date is entered as past date"), title=_('Warning'), indicator='red')
 
@@ -106,12 +109,13 @@
 						n * cint(self.frequency_of_depreciation))
 
 					depreciation_amount = self.get_depreciation_amount(value_after_depreciation)
-					value_after_depreciation -= flt(depreciation_amount)
+					if depreciation_amount:
+						value_after_depreciation -= flt(depreciation_amount)
 
-					self.append("schedules", {
-						"schedule_date": schedule_date,
-						"depreciation_amount": depreciation_amount
-					})
+						self.append("schedules", {
+							"schedule_date": schedule_date,
+							"depreciation_amount": depreciation_amount
+						})
 
 	def set_accumulated_depreciation(self):
 		accumulated_depreciation = flt(self.opening_accumulated_depreciation)
diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py
index c72cb96..92a251e 100644
--- a/erpnext/assets/doctype/asset/depreciation.py
+++ b/erpnext/assets/doctype/asset/depreciation.py
@@ -151,13 +151,11 @@
 	asset.set_status()
 
 @frappe.whitelist()
-def get_gl_entries_on_asset_disposal(asset, is_sale=False):
+def get_gl_entries_on_asset_disposal(asset, selling_amount=0):
 	fixed_asset_account, accumulated_depr_account, depr_expense_account = get_depreciation_accounts(asset)
-	accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(asset.value_after_depreciation)
+	disposal_account, depreciation_cost_center = get_disposal_account_and_cost_center(asset.company)
 
-	expense_account, cost_center = get_disposal_account_and_cost_center(asset.company)
-	if is_sale:
-		expense_account = depr_expense_account
+	accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(asset.value_after_depreciation)
 
 	gl_entries = [
 		{
@@ -172,12 +170,14 @@
 		}
 	]
 
-	if flt(asset.value_after_depreciation):
+	profit_amount = flt(selling_amount) - flt(asset.value_after_depreciation)
+	if profit_amount:
+		debit_or_credit = "debit" if profit_amount < 0 else "credit"
 		gl_entries.append({
-			"account": expense_account,
-			"cost_center": cost_center,
-			"debit": flt(asset.value_after_depreciation),
-			"debit_in_account_currency": flt(asset.value_after_depreciation)
+			"account": disposal_account,
+			"cost_center": depreciation_cost_center,
+			debit_or_credit: abs(profit_amount),
+			debit_or_credit + "_in_account_currency": abs(profit_amount)
 		})
 
 	return gl_entries
diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py
index 107ffec..76c46cf 100644
--- a/erpnext/assets/doctype/asset/test_asset.py
+++ b/erpnext/assets/doctype/asset/test_asset.py
@@ -234,9 +234,8 @@
 
 		expected_gle = (
 			("_Test Accumulated Depreciations - _TC", 30000.0, 0.0),
-			("_Test Depreciations - _TC", 70000.0, 0.0),
 			("_Test Fixed Asset - _TC", 0.0, 100000.0),
-			("_Test Gain/Loss on Asset Disposal - _TC", 0.0, 25000.0),
+			("_Test Gain/Loss on Asset Disposal - _TC", 45000.0, 0.0),
 			("Debtors - _TC", 25000.0, 0.0)
 		)
 
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index e198c7e..c37a617 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -549,7 +549,7 @@
 					final_message = final_message + message1;
 				}
 
-				if (this.frm.doc.payment_schedule.length) {
+				if ((this.frm.doc.payment_schedule || []).length) {
 					message2 = "Payment Schedule Table";
 					if (message1.length !== 0) message2 = " and " + message2;
 					final_message = final_message + message2;
diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py
index 6c9e450..eaa82b3 100644
--- a/erpnext/selling/doctype/customer/customer.py
+++ b/erpnext/selling/doctype/customer/customer.py
@@ -146,7 +146,8 @@
 			frappe.throw(_("A Customer Group exists with same name please change the Customer name or rename the Customer Group"), frappe.NameError)
 
 	def validate_credit_limit_on_change(self):
-		if self.get("__islocal") or self.credit_limit == frappe.db.get_value("Customer", self.name, "credit_limit"):
+		if self.get("__islocal") or not self.credit_limit \
+			or self.credit_limit == frappe.db.get_value("Customer", self.name, "credit_limit"):
 			return
 
 		for company in frappe.get_all("Company"):