[Refactored] Asset Depreciation Ledger report based on GL entries (#15415)

* [Refactored] Asset Depreciation Ledger report is based on GL entries

* Provision to make manual JV from the asset if Calculate Depreciation is disabled
diff --git a/erpnext/accounts/report/asset_depreciation_ledger/asset_depreciation_ledger.py b/erpnext/accounts/report/asset_depreciation_ledger/asset_depreciation_ledger.py
index 5497384..0e2742d 100644
--- a/erpnext/accounts/report/asset_depreciation_ledger/asset_depreciation_ledger.py
+++ b/erpnext/accounts/report/asset_depreciation_ledger/asset_depreciation_ledger.py
@@ -3,47 +3,75 @@
 
 from __future__ import unicode_literals
 import frappe
+from frappe.utils import flt
 from frappe import _
 
 def execute(filters=None):
 	columns, data = get_columns(), get_data(filters)
 	return columns, data
-	
+
 def get_data(filters):
-	data = frappe.db.sql("""
-		select 
-			a.name as asset, a.asset_category, a.status, 
-			a.depreciation_method, a.purchase_date, a.gross_purchase_amount,
-			ds.schedule_date as depreciation_date, ds.depreciation_amount, 
-			ds.accumulated_depreciation_amount, 
-			(a.gross_purchase_amount - ds.accumulated_depreciation_amount) as amount_after_depreciation,
-			ds.journal_entry as depreciation_entry
-		from
-			`tabAsset` a, `tabDepreciation Schedule` ds
-		where
-			a.name = ds.parent
-			and a.docstatus=1
-			and ifnull(ds.journal_entry, '') != ''
-			and ds.schedule_date between %(from_date)s and %(to_date)s
-			and a.company = %(company)s
-			{conditions}
-		order by
-			a.name asc, ds.schedule_date asc
-	""".format(conditions=get_filter_conditions(filters)), filters, as_dict=1)
-		
-	return data
-	
-def get_filter_conditions(filters):
-	conditions = ""
-	
+	data = []
+	depreciation_accounts = frappe.db.sql_list(""" select name from tabAccount
+		where ifnull(account_type, '') = 'Depreciation' """)
+
+	filters_data = [["company", "=", filters.get('company')],
+		["posting_date", ">=", filters.get('from_date')],
+		["posting_date", "<=", filters.get('to_date')],
+		["against_voucher_type", "=", "Asset"],
+		["account", "in", depreciation_accounts]]
+
 	if filters.get("asset"):
-		conditions += " and a.name = %(asset)s"
-	
+		filters_data.append(["against_voucher", "=", filters.get("asset")])
+
 	if filters.get("asset_category"):
-		conditions += " and a.asset_category = %(asset_category)s"
-		
-	return conditions
+		assets = frappe.db.sql_list("""select name from tabAsset
+			where asset_category = %s and docstatus=1""", filters.get("asset_category"))
+
+		filters_data.append(["against_voucher", "in", assets])
+
+	gl_entries = frappe.get_all('GL Entry',
+		filters= filters_data,
+		fields = ["against_voucher", "debit_in_account_currency as debit", "voucher_no", "posting_date"],
+		order_by= "against_voucher, posting_date")
+
+	if not gl_entries:
+		return data
+
+	assets = [d.against_voucher for d in gl_entries]
+	assets_details = get_assets_details(assets)
 	
+	for d in gl_entries:
+		asset_data = assets_details.get(d.against_voucher)
+		if not asset_data.get("accumulated_depreciation_amount"):
+			asset_data.accumulated_depreciation_amount = d.debit
+		else:
+			asset_data.accumulated_depreciation_amount += d.debit
+
+		row = frappe._dict(asset_data)
+		row.update({
+			"depreciation_amount": d.debit,
+			"depreciation_date": d.posting_date,
+			"amount_after_depreciation": (flt(row.gross_purchase_amount) -
+				flt(row.accumulated_depreciation_amount)),
+			"depreciation_entry": d.voucher_no
+		})
+
+		data.append(row)
+
+	return data
+
+def get_assets_details(assets):
+	assets_details = {}
+
+	fields = ["name as asset", "gross_purchase_amount",
+		"asset_category", "status", "depreciation_method", "purchase_date"]
+
+	for d in frappe.get_all("Asset", fields = fields, filters = {'name': ('in', assets)}):
+		assets_details.setdefault(d.asset, d)
+
+	return assets_details
+
 def get_columns():
 	return [
 		{
diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js
index 01577eb..875df59 100644
--- a/erpnext/assets/doctype/asset/asset.js
+++ b/erpnext/assets/doctype/asset/asset.js
@@ -67,11 +67,33 @@
 					frm.trigger("create_asset_maintenance");
 				}, __("Make"));
 			}
+
+			if (!frm.doc.calculate_depreciation) {
+				frm.add_custom_button(__("Depreciation Entry"), function() {
+					frm.trigger("make_journal_entry");
+				}, __("Make"));
+			}
+
 			frm.page.set_inner_btn_group_as_primary(__("Make"));
 			frm.trigger("setup_chart");
 		}
 	},
 
+	make_journal_entry: function(frm) {
+		frappe.call({
+			method: "erpnext.assets.doctype.asset.asset.make_journal_entry",
+			args: {
+				asset_name: frm.doc.name
+			},
+			callback: function(r) {
+				if (r.message) {
+					var doclist = frappe.model.sync(r.message);
+					frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
+				}
+			}
+		})
+	},
+
 	setup_chart: function(frm) {
 		var x_intervals = [frm.doc.purchase_date];
 		var asset_values = [frm.doc.gross_purchase_amount];
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index 8bba0b6..7fa5810 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -283,3 +283,34 @@
 	})
 
 	return ret
+
+@frappe.whitelist()
+def make_journal_entry(asset_name):
+	asset = frappe.get_doc("Asset", asset_name)
+	fixed_asset_account, accumulated_depreciation_account, depreciation_expense_account = \
+		get_depreciation_accounts(asset)
+
+	depreciation_cost_center, depreciation_series = frappe.db.get_value("Company", asset.company,
+		["depreciation_cost_center", "series_for_depreciation_entry"])
+	depreciation_cost_center = asset.cost_center or depreciation_cost_center
+
+	je = frappe.new_doc("Journal Entry")
+	je.voucher_type = "Depreciation Entry"
+	je.naming_series = depreciation_series
+	je.company = asset.company
+	je.remark = "Depreciation Entry against asset {0}".format(asset_name)
+
+	je.append("accounts", {
+		"account": depreciation_expense_account,
+		"reference_type": "Asset",
+		"reference_name": asset.name,
+		"cost_center": depreciation_cost_center
+	})
+
+	je.append("accounts", {
+		"account": accumulated_depreciation_account,
+		"reference_type": "Asset",
+		"reference_name": asset.name
+	})
+
+	return je
\ No newline at end of file
diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py
index acd5892..89d3808 100644
--- a/erpnext/assets/doctype/asset/depreciation.py
+++ b/erpnext/assets/doctype/asset/depreciation.py
@@ -5,13 +5,13 @@
 from __future__ import unicode_literals
 import frappe
 from frappe import _
-from frappe.utils import flt, today, getdate
+from frappe.utils import flt, today, getdate, cint
 
 def post_depreciation_entries(date=None):
 	# Return if automatic booking of asset depreciation is disabled
-	if not frappe.db.get_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically"):
+	if not cint(frappe.db.get_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically")):
 		return
-		
+
 	if not date:
 		date = today()
 	for asset in get_depreciable_assets(date):