Skip to content

Commit

Permalink
fix: incorrect depr schedule and posting dates on selling of existing…
Browse files Browse the repository at this point in the history
… assets [v13] (#35404)

fix: calc depr amount properly on selling of existing assets and fix incorrect posting dates
  • Loading branch information
anandbaburajan committed May 24, 2023
1 parent 1e1dddf commit 20d3381
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 12 deletions.
4 changes: 2 additions & 2 deletions erpnext/accounts/doctype/sales_invoice/sales_invoice.py
Expand Up @@ -1107,7 +1107,7 @@ def make_item_gl_entries(self, gl_entries):

if self.is_return:
fixed_asset_gl_entries = get_gl_entries_on_asset_regain(
asset, item.base_net_amount, item.finance_book
asset, item.base_net_amount, item.finance_book, self.posting_date
)
asset.db_set("disposal_date", None)

Expand All @@ -1122,7 +1122,7 @@ def make_item_gl_entries(self, gl_entries):
asset.reload()

fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(
asset, item.base_net_amount, item.finance_book
asset, item.base_net_amount, item.finance_book, self.posting_date
)
asset.db_set("disposal_date", self.posting_date)

Expand Down
11 changes: 7 additions & 4 deletions erpnext/assets/doctype/asset/asset.py
Expand Up @@ -345,7 +345,7 @@ def make_depreciation_schedule(self, date_of_disposal):

# if asset is being sold
if date_of_disposal:
from_date = self.get_from_date(finance_book.finance_book)
from_date = self.get_from_date_for_disposal(finance_book)
depreciation_amount, days, months = self.get_pro_rata_amt(
finance_book,
depreciation_amount,
Expand Down Expand Up @@ -490,16 +490,19 @@ def sort_depreciation_schedule(self):
for idx, s in enumerate(self.schedules, 1):
s.idx = idx

def get_from_date(self, finance_book):
def get_from_date_for_disposal(self, finance_book):
if not self.get("schedules"):
return self.available_for_use_date
return add_months(
getdate(self.available_for_use_date),
(self.number_of_depreciations_booked * finance_book.frequency_of_depreciation),
)

if len(self.finance_books) == 1:
return self.schedules[-1].schedule_date

from_date = ""
for schedule in self.get("schedules"):
if schedule.finance_book == finance_book:
if schedule.finance_book == finance_book.finance_book:
from_date = schedule.schedule_date

if from_date:
Expand Down
32 changes: 26 additions & 6 deletions erpnext/assets/doctype/asset/depreciation.py
Expand Up @@ -279,7 +279,7 @@ def scrap_asset(asset_name):
je.company = asset.company
je.remark = "Scrap Entry for asset {0}".format(asset_name)

for entry in get_gl_entries_on_asset_disposal(asset):
for entry in get_gl_entries_on_asset_disposal(asset, date):
entry.update({"reference_type": "Asset", "reference_name": asset_name})
je.append("accounts", entry)

Expand Down Expand Up @@ -403,7 +403,10 @@ def disposal_happens_in_the_future(posting_date_of_disposal):
return False


def get_gl_entries_on_asset_regain(asset, selling_amount=0, finance_book=None):
def get_gl_entries_on_asset_regain(asset, selling_amount=0, finance_book=None, date=None):
if not date:
date = getdate()

(
fixed_asset_account,
asset,
Expand All @@ -420,23 +423,30 @@ def get_gl_entries_on_asset_regain(asset, selling_amount=0, finance_book=None):
"debit_in_account_currency": asset.gross_purchase_amount,
"debit": asset.gross_purchase_amount,
"cost_center": depreciation_cost_center,
"posting_date": date,
},
{
"account": accumulated_depr_account,
"credit_in_account_currency": accumulated_depr_amount,
"credit": accumulated_depr_amount,
"cost_center": depreciation_cost_center,
"posting_date": date,
},
]

profit_amount = abs(flt(value_after_depreciation)) - abs(flt(selling_amount))
if profit_amount:
get_profit_gl_entries(profit_amount, gl_entries, disposal_account, depreciation_cost_center)
get_profit_gl_entries(
profit_amount, gl_entries, disposal_account, depreciation_cost_center, date
)

return gl_entries


def get_gl_entries_on_asset_disposal(asset, selling_amount=0, finance_book=None):
def get_gl_entries_on_asset_disposal(asset, selling_amount=0, finance_book=None, date=None):
if not date:
date = getdate()

(
fixed_asset_account,
asset,
Expand All @@ -453,18 +463,22 @@ def get_gl_entries_on_asset_disposal(asset, selling_amount=0, finance_book=None)
"credit_in_account_currency": asset.gross_purchase_amount,
"credit": asset.gross_purchase_amount,
"cost_center": depreciation_cost_center,
"posting_date": date,
},
{
"account": accumulated_depr_account,
"debit_in_account_currency": accumulated_depr_amount,
"debit": accumulated_depr_amount,
"cost_center": depreciation_cost_center,
"posting_date": date,
},
]

profit_amount = flt(selling_amount) - flt(value_after_depreciation)
if profit_amount:
get_profit_gl_entries(profit_amount, gl_entries, disposal_account, depreciation_cost_center)
get_profit_gl_entries(
profit_amount, gl_entries, disposal_account, depreciation_cost_center, date
)

return gl_entries

Expand All @@ -491,14 +505,20 @@ def get_asset_details(asset, finance_book=None):
)


def get_profit_gl_entries(profit_amount, gl_entries, disposal_account, depreciation_cost_center):
def get_profit_gl_entries(
profit_amount, gl_entries, disposal_account, depreciation_cost_center, date=None
):
if not date:
date = getdate()

debit_or_credit = "debit" if profit_amount < 0 else "credit"
gl_entries.append(
{
"account": disposal_account,
"cost_center": depreciation_cost_center,
debit_or_credit: abs(profit_amount),
debit_or_credit + "_in_account_currency": abs(profit_amount),
"posting_date": date,
}
)

Expand Down
73 changes: 73 additions & 0 deletions erpnext/assets/doctype/asset/test_asset.py
Expand Up @@ -298,6 +298,79 @@ def test_gle_made_by_asset_sale(self):
si.cancel()
self.assertEqual(frappe.db.get_value("Asset", asset.name, "status"), "Partially Depreciated")

def test_gle_made_by_asset_sale_for_existing_asset(self):
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice

asset = create_asset(
calculate_depreciation=1,
available_for_use_date="2020-04-01",
purchase_date="2020-04-01",
expected_value_after_useful_life=0,
total_number_of_depreciations=5,
number_of_depreciations_booked=2,
frequency_of_depreciation=12,
depreciation_start_date="2023-03-31",
opening_accumulated_depreciation=24000,
gross_purchase_amount=60000,
submit=1,
)

expected_depr_values = [
["2023-03-31", 12000, 36000],
["2024-03-31", 12000, 48000],
["2025-03-31", 12000, 60000],
]

for i, schedule in enumerate(asset.schedules):
self.assertEqual(getdate(expected_depr_values[i][0]), schedule.schedule_date)
self.assertEqual(expected_depr_values[i][1], schedule.depreciation_amount)
self.assertEqual(expected_depr_values[i][2], schedule.accumulated_depreciation_amount)

post_depreciation_entries(date="2023-03-31")

si = create_sales_invoice(
item_code="Macbook Pro", asset=asset.name, qty=1, rate=40000, posting_date=getdate("2023-05-23")
)
asset.load_from_db()

self.assertEqual(frappe.db.get_value("Asset", asset.name, "status"), "Sold")

expected_values = [["2023-03-31", 12000, 36000], ["2023-05-23", 1742.47, 37742.47]]

for i, schedule in enumerate(asset.schedules):
self.assertEqual(getdate(expected_values[i][0]), schedule.schedule_date)
self.assertEqual(expected_values[i][1], schedule.depreciation_amount)
self.assertEqual(expected_values[i][2], schedule.accumulated_depreciation_amount)
self.assertTrue(schedule.journal_entry)

expected_gle = (
(
"_Test Accumulated Depreciations - _TC",
37742.47,
0.0,
),
(
"_Test Fixed Asset - _TC",
0.0,
60000.0,
),
(
"_Test Gain/Loss on Asset Disposal - _TC",
0.0,
17742.47,
),
("Debtors - _TC", 40000.0, 0.0),
)

gle = frappe.db.sql(
"""select account, debit, credit from `tabGL Entry`
where voucher_type='Sales Invoice' and voucher_no = %s
order by account""",
si.name,
)

self.assertSequenceEqual(gle, expected_gle)

def test_asset_with_maintenance_required_status_after_sale(self):
asset = create_asset(
calculate_depreciation=1,
Expand Down

0 comments on commit 20d3381

Please sign in to comment.