Skip to content

Commit

Permalink
fix: manual depr entry not updating asset value [v13] (frappe#33890)
Browse files Browse the repository at this point in the history
fix: asset value for manual depr entries
  • Loading branch information
anandbaburajan authored Jan 31, 2023
1 parent 3425a3b commit f5efb20
Show file tree
Hide file tree
Showing 13 changed files with 290 additions and 93 deletions.
67 changes: 58 additions & 9 deletions erpnext/accounts/doctype/journal_entry/journal_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def on_submit(self):
self.check_credit_limit()
self.make_gl_entries()
self.update_advance_paid()
self.update_asset_value()
self.update_expense_claim()
self.update_inter_company_jv()
self.update_invoice_discounting()
Expand Down Expand Up @@ -235,6 +236,34 @@ def apply_tax_withholding(self):
for d in to_remove:
self.remove(d)

def update_asset_value(self):
if self.voucher_type != "Depreciation Entry":
return

processed_assets = []

for d in self.get("accounts"):
if (
d.reference_type == "Asset" and d.reference_name and d.reference_name not in processed_assets
):
processed_assets.append(d.reference_name)

asset = frappe.db.get_value(
"Asset", d.reference_name, ["calculate_depreciation", "value_after_depreciation"], as_dict=1
)

if asset.calculate_depreciation:
continue

depr_value = d.debit or d.credit

frappe.db.set_value(
"Asset",
d.reference_name,
"value_after_depreciation",
asset.value_after_depreciation - depr_value,
)

def update_inter_company_jv(self):
if (
self.voucher_type == "Inter Company Journal Entry"
Expand Down Expand Up @@ -293,19 +322,39 @@ def unlink_advance_entry_reference(self):
d.db_update()

def unlink_asset_reference(self):
if self.voucher_type != "Depreciation Entry":
return

processed_assets = []

for d in self.get("accounts"):
if d.reference_type == "Asset" and d.reference_name:
if (
d.reference_type == "Asset" and d.reference_name and d.reference_name not in processed_assets
):
processed_assets.append(d.reference_name)

asset = frappe.get_doc("Asset", d.reference_name)
for s in asset.get("schedules"):
if s.journal_entry == self.name:
s.db_set("journal_entry", None)

idx = cint(s.finance_book_id) or 1
finance_books = asset.get("finance_books")[idx - 1]
finance_books.value_after_depreciation += s.depreciation_amount
finance_books.db_update()
if asset.calculate_depreciation:
for s in asset.get("schedules"):
if s.journal_entry == self.name:
s.db_set("journal_entry", None)

idx = cint(s.finance_book_id) or 1
finance_books = asset.get("finance_books")[idx - 1]
finance_books.value_after_depreciation += s.depreciation_amount
finance_books.db_update()

asset.set_status()
asset.set_status()
else:
depr_value = d.debit or d.credit

frappe.db.set_value(
"Asset",
d.reference_name,
"value_after_depreciation",
asset.value_after_depreciation + depr_value,
)

def unlink_inter_company_jv(self):
if (
Expand Down
40 changes: 27 additions & 13 deletions erpnext/assets/doctype/asset/asset.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ frappe.ui.form.on('Asset', {
})
},

setup_chart: function(frm) {
setup_chart: async function(frm) {
if(frm.doc.finance_books.length > 1) {
return
}
Expand All @@ -219,20 +219,34 @@ frappe.ui.form.on('Asset', {
flt(frm.doc.opening_accumulated_depreciation));
}

$.each(frm.doc.schedules || [], function(i, v) {
x_intervals.push(v.schedule_date);
var asset_value = flt(frm.doc.gross_purchase_amount) - flt(v.accumulated_depreciation_amount);
if(v.journal_entry) {
last_depreciation_date = v.schedule_date;
asset_values.push(asset_value);
} else {
if (in_list(["Scrapped", "Sold"], frm.doc.status)) {
asset_values.push(null);
if(frm.doc.calculate_depreciation) {
$.each(frm.doc.schedules || [], function(i, v) {
x_intervals.push(v.schedule_date);
var asset_value = flt(frm.doc.gross_purchase_amount) - flt(v.accumulated_depreciation_amount);
if(v.journal_entry) {
last_depreciation_date = v.schedule_date;
asset_values.push(asset_value);
} else {
asset_values.push(asset_value)
if (in_list(["Scrapped", "Sold"], frm.doc.status)) {
asset_values.push(null);
} else {
asset_values.push(asset_value)
}
}
}
});
});
} else {
let depr_entries = (await frappe.call({
method: "get_manual_depreciation_entries",
doc: frm.doc,
})).message;

$.each(depr_entries || [], function(i, v) {
x_intervals.push(v.posting_date);
last_depreciation_date = v.posting_date;
let last_asset_value = asset_values[asset_values.length - 1]
asset_values.push(last_asset_value - v.value);
});
}

if(in_list(["Scrapped", "Sold"], frm.doc.status)) {
x_intervals.push(frm.doc.disposal_date);
Expand Down
8 changes: 7 additions & 1 deletion erpnext/assets/doctype/asset/asset.json
Original file line number Diff line number Diff line change
Expand Up @@ -504,9 +504,15 @@
"group": "Value",
"link_doctype": "Asset Value Adjustment",
"link_fieldname": "asset"
},
{
"group": "Journal Entry",
"link_doctype": "Journal Entry",
"link_fieldname": "reference_name",
"table_fieldname": "accounts"
}
],
"modified": "2023-01-17 00:28:37.789345",
"modified": "2023-01-31 01:03:09.467817",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset",
Expand Down
69 changes: 54 additions & 15 deletions erpnext/assets/doctype/asset/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,9 @@ def set_accumulated_depreciation(

if int(d.finance_book_id) not in finance_books:
accumulated_depreciation = flt(self.opening_accumulated_depreciation)
value_after_depreciation = flt(self.get_value_after_depreciation(d.finance_book_id))
value_after_depreciation = flt(
self.get("finance_books")[cint(d.finance_book_id) - 1].value_after_depreciation
)
finance_books.append(int(d.finance_book_id))

depreciation_amount = flt(d.depreciation_amount, d.precision("depreciation_amount"))
Expand All @@ -581,9 +583,6 @@ def set_accumulated_depreciation(
accumulated_depreciation, d.precision("accumulated_depreciation_amount")
)

def get_value_after_depreciation(self, idx):
return flt(self.get("finance_books")[cint(idx) - 1].value_after_depreciation)

def validate_expected_value_after_useful_life(self):
for row in self.get("finance_books"):
accumulated_depreciation_after_full_schedule = [
Expand Down Expand Up @@ -638,15 +637,20 @@ def cancel_movement_entries(self):
movement.cancel()

def delete_depreciation_entries(self):
for d in self.get("schedules"):
if d.journal_entry:
frappe.get_doc("Journal Entry", d.journal_entry).cancel()
d.db_set("journal_entry", None)

self.db_set(
"value_after_depreciation",
(flt(self.gross_purchase_amount) - flt(self.opening_accumulated_depreciation)),
)
if self.calculate_depreciation:
for d in self.get("schedules"):
if d.journal_entry:
frappe.get_doc("Journal Entry", d.journal_entry).cancel()
else:
depr_entries = self.get_manual_depreciation_entries()

for depr_entry in depr_entries or []:
frappe.get_doc("Journal Entry", depr_entry.name).cancel()

self.db_set(
"value_after_depreciation",
(flt(self.gross_purchase_amount) - flt(self.opening_accumulated_depreciation)),
)

def set_status(self, status=None):
"""Get and update status"""
Expand Down Expand Up @@ -677,6 +681,17 @@ def get_status(self):
status = "Cancelled"
return status

def get_value_after_depreciation(self, finance_book=None):
if not self.calculate_depreciation:
return self.value_after_depreciation

if not finance_book:
return self.get("finance_books")[0].value_after_depreciation

for row in self.get("finance_books"):
if finance_book == row.finance_book:
return row.value_after_depreciation

def get_default_finance_book_idx(self):
if not self.get("default_finance_book") and self.company:
self.default_finance_book = erpnext.get_default_finance_book(self.company)
Expand All @@ -686,6 +701,24 @@ def get_default_finance_book_idx(self):
if d.finance_book == self.default_finance_book:
return cint(d.idx) - 1

@frappe.whitelist()
def get_manual_depreciation_entries(self):
(_, _, depreciation_expense_account) = get_depreciation_accounts(self)

gle = frappe.qb.DocType("GL Entry")

records = (
frappe.qb.from_(gle)
.select(gle.voucher_no.as_("name"), gle.debit.as_("value"), gle.posting_date)
.where(gle.against_voucher == self.name)
.where(gle.account == depreciation_expense_account)
.where(gle.debit != 0)
.where(gle.is_cancelled == 0)
.orderby(gle.posting_date)
).run(as_dict=True)

return records

def validate_make_gl_entry(self):
purchase_document = self.get_purchase_document()
if not purchase_document:
Expand Down Expand Up @@ -850,7 +883,6 @@ def update_maintenance_status():


def make_post_gl_entry():

asset_categories = frappe.db.get_all("Asset Category", fields=["name", "enable_cwip_accounting"])

for asset_category in asset_categories:
Expand Down Expand Up @@ -1003,7 +1035,7 @@ def make_journal_entry(asset_name):
depreciation_expense_account,
) = get_depreciation_accounts(asset)

depreciation_cost_center, depreciation_series = frappe.db.get_value(
depreciation_cost_center, depreciation_series = frappe.get_cached_value(
"Company", asset.company, ["depreciation_cost_center", "series_for_depreciation_entry"]
)
depreciation_cost_center = asset.cost_center or depreciation_cost_center
Expand Down Expand Up @@ -1070,6 +1102,13 @@ def is_cwip_accounting_enabled(asset_category):
return cint(frappe.db.get_value("Asset Category", asset_category, "enable_cwip_accounting"))


@frappe.whitelist()
def get_asset_value_after_depreciation(asset_name, finance_book=None):
asset = frappe.get_doc("Asset", asset_name)

return asset.get_value_after_depreciation(finance_book)


def get_total_days(date, frequency):
period_start_date = add_months(date, cint(frequency) * -1)

Expand Down
14 changes: 2 additions & 12 deletions erpnext/assets/doctype/asset/depreciation.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,18 +469,8 @@ def get_asset_details(asset, finance_book=None):
disposal_account, depreciation_cost_center = get_disposal_account_and_cost_center(asset.company)
depreciation_cost_center = asset.cost_center or depreciation_cost_center

idx = 1
if finance_book:
for d in asset.finance_books:
if d.finance_book == finance_book:
idx = d.idx
break

value_after_depreciation = (
asset.finance_books[idx - 1].value_after_depreciation
if asset.calculate_depreciation
else asset.value_after_depreciation
)
value_after_depreciation = asset.get_value_after_depreciation(finance_book)

accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(value_after_depreciation)

return (
Expand Down
31 changes: 31 additions & 0 deletions erpnext/assets/doctype/asset/test_asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
nowdate,
)

from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
from erpnext.assets.doctype.asset.asset import make_sales_invoice, update_maintenance_status
from erpnext.assets.doctype.asset.depreciation import (
Expand Down Expand Up @@ -1410,6 +1411,36 @@ def test_depreciation_on_final_day_of_the_month(self):
for i, schedule in enumerate(asset.schedules):
self.assertEqual(getdate(expected_dates[i]), getdate(schedule.schedule_date))

def test_manual_depreciation_for_existing_asset(self):
asset = create_asset(
item_code="Macbook Pro",
is_existing_asset=1,
purchase_date="2020-01-30",
available_for_use_date="2020-01-30",
submit=1,
)

self.assertEqual(asset.status, "Submitted")
self.assertEqual(asset.get("value_after_depreciation"), 100000)

jv = make_journal_entry(
"_Test Depreciations - _TC", "_Test Accumulated Depreciations - _TC", 100, save=False
)
for d in jv.accounts:
d.reference_type = "Asset"
d.reference_name = asset.name
jv.voucher_type = "Depreciation Entry"
jv.insert()
jv.submit()

asset.reload()
self.assertEqual(asset.get("value_after_depreciation"), 99900)

jv.cancel()

asset.reload()
self.assertEqual(asset.get("value_after_depreciation"), 100000)


def create_asset_data():
if not frappe.db.exists("Asset Category", "Computers"):
Expand Down
13 changes: 5 additions & 8 deletions erpnext/assets/doctype/asset_repair/test_asset_repair.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import frappe
from frappe.utils import flt, nowdate

from erpnext.assets.doctype.asset.asset import get_asset_value_after_depreciation
from erpnext.assets.doctype.asset.test_asset import (
create_asset,
create_asset_data,
Expand Down Expand Up @@ -105,20 +106,20 @@ def test_serialized_item_consumption(self):

def test_increase_in_asset_value_due_to_stock_consumption(self):
asset = create_asset(calculate_depreciation=1, submit=1)
initial_asset_value = get_asset_value(asset)
initial_asset_value = get_asset_value_after_depreciation(asset.name)
asset_repair = create_asset_repair(asset=asset, stock_consumption=1, submit=1)
asset.reload()

increase_in_asset_value = get_asset_value(asset) - initial_asset_value
increase_in_asset_value = get_asset_value_after_depreciation(asset.name) - initial_asset_value
self.assertEqual(asset_repair.stock_items[0].total_value, increase_in_asset_value)

def test_increase_in_asset_value_due_to_repair_cost_capitalisation(self):
asset = create_asset(calculate_depreciation=1, submit=1)
initial_asset_value = get_asset_value(asset)
initial_asset_value = get_asset_value_after_depreciation(asset.name)
asset_repair = create_asset_repair(asset=asset, capitalize_repair_cost=1, submit=1)
asset.reload()

increase_in_asset_value = get_asset_value(asset) - initial_asset_value
increase_in_asset_value = get_asset_value_after_depreciation(asset.name) - initial_asset_value
self.assertEqual(asset_repair.repair_cost, increase_in_asset_value)

def test_purchase_invoice(self):
Expand All @@ -143,10 +144,6 @@ def test_increase_in_asset_life(self):
)


def get_asset_value(asset):
return asset.finance_books[0].value_after_depreciation


def num_of_depreciations(asset):
return asset.finance_books[0].total_number_of_depreciations

Expand Down
Loading

0 comments on commit f5efb20

Please sign in to comment.