Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: manual depr entry not updating asset value [v13] #33890

Merged
merged 2 commits into from
Jan 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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