From 0cf0ebf08b3a64da41addf0ccd9789bf4830eb8b Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Wed, 26 Sep 2018 15:24:49 +0530 Subject: [PATCH] [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 --- .../asset_depreciation_ledger.py | 92 ++++++++++++------- erpnext/assets/doctype/asset/asset.js | 22 +++++ erpnext/assets/doctype/asset/asset.py | 31 +++++++ erpnext/assets/doctype/asset/depreciation.py | 6 +- 4 files changed, 116 insertions(+), 35 deletions(-) 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 5497384233..0e2742d8b7 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 01577eba77..875df59681 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -67,11 +67,33 @@ frappe.ui.form.on('Asset', { 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 8bba0b6936..7fa5810d34 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -283,3 +283,34 @@ def get_item_details(item_code): }) 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 acd5892cd6..89d3808e6a 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):