[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):