refactor: asset value adjustment

This commit is contained in:
Nabin Hait
2024-12-23 18:24:10 +05:30
committed by Khushi Rawat
parent c567a08470
commit 44e45b55d4
6 changed files with 119 additions and 157 deletions

View File

@@ -196,7 +196,6 @@ class JournalEntry(AccountsController):
self.update_asset_value()
self.update_inter_company_jv()
self.update_invoice_discounting()
self.update_booked_depreciation()
def on_update_after_submit(self):
# Flag will be set on Reconciliation
@@ -232,7 +231,6 @@ class JournalEntry(AccountsController):
self.unlink_inter_company_jv()
self.unlink_asset_adjustment_entry()
self.update_invoice_discounting()
self.update_booked_depreciation(1)
def get_title(self):
return self.pay_to_recd_from or self.accounts[0].account
@@ -405,6 +403,7 @@ class JournalEntry(AccountsController):
asset.db_set("value_after_depreciation", asset.value_after_depreciation - d.debit)
asset.set_status()
asset.set_total_booked_depreciations()
def update_inter_company_jv(self):
if self.voucher_type == "Inter Company Journal Entry" and self.inter_company_journal_entry_reference:
@@ -459,25 +458,6 @@ class JournalEntry(AccountsController):
if status:
inv_disc_doc.set_status(status=status)
def update_booked_depreciation(self, cancel=0):
for d in self.get("accounts"):
if (
self.voucher_type == "Depreciation Entry"
and d.reference_type == "Asset"
and d.reference_name
and frappe.get_cached_value("Account", d.account, "root_type") == "Expense"
and d.debit
):
asset = frappe.get_doc("Asset", d.reference_name)
for fb_row in asset.get("finance_books"):
if fb_row.finance_book == self.finance_book:
if cancel:
fb_row.total_number_of_booked_depreciations -= 1
else:
fb_row.total_number_of_booked_depreciations += 1
fb_row.db_update()
break
def unlink_advance_entry_reference(self):
for d in self.get("accounts"):
if d.is_advance == "Yes" and d.reference_type in ("Sales Invoice", "Purchase Invoice"):
@@ -530,6 +510,7 @@ class JournalEntry(AccountsController):
else:
asset.db_set("value_after_depreciation", asset.value_after_depreciation + d.debit)
asset.set_status()
asset.set_total_booked_depreciations()
elif self.voucher_type == "Journal Entry" and d.reference_type == "Asset" and d.reference_name:
journal_entry_for_scrap = frappe.db.get_value(
"Asset", d.reference_name, "journal_entry_for_scrap"

View File

@@ -130,8 +130,6 @@ class Asset(AccountsController):
self.set_missing_values()
self.validate_gross_and_purchase_amount()
self.validate_finance_books()
self.validate_expected_value_after_useful_life()
self.set_total_booked_depreciations()
self.total_asset_cost = self.gross_purchase_amount
self.status = self.get_status()
@@ -178,6 +176,8 @@ class Asset(AccountsController):
def on_update(self):
self.create_asset_depreciation_schedule()
self.validate_expected_value_after_useful_life()
self.set_total_booked_depreciations()
def on_submit(self):
self.validate_in_use_date()

View File

@@ -351,11 +351,11 @@ class AssetDepreciationSchedule(Document):
return has_wdv_or_dd_non_yearly_pro_rata
def get_number_of_pending_months(self, asset_doc, row, start):
print(row.total_number_of_depreciations)
total_months = cint(row.total_number_of_depreciations) * cint(row.frequency_of_depreciation) + cint(
row.increase_in_asset_life
)
depr_booked_for_months = 0
last_depr_date = None
if start > 0:
last_depr_date = self.depreciation_schedule[start - 1].schedule_date
elif asset_doc.opening_number_of_booked_depreciations > 0:
@@ -363,7 +363,7 @@ class AssetDepreciationSchedule(Document):
if last_depr_date:
depr_booked_for_months = date_diff(last_depr_date, asset_doc.available_for_use_date) / (365 / 12)
print(total_months, depr_booked_for_months)
return total_months - depr_booked_for_months
def has_fiscal_year_changed(self, row, row_no):
@@ -516,7 +516,7 @@ class AssetDepreciationSchedule(Document):
return depreciation_amount, skip_row
def validate_depreciation_amount_for_low_value_assets(self, asset_doc, row, depreciation_amount):
""" "
"""
If gross purchase amount is too low, then depreciation amount
can come zero sometimes based on the frequency and number of depreciations.
"""
@@ -553,42 +553,23 @@ class AssetDepreciationSchedule(Document):
row,
date_of_disposal=None,
date_of_return=None,
ignore_booked_entry=False,
):
straight_line_idx = [
d.idx
for d in self.get("depreciation_schedule")
if self.depreciation_method == "Straight Line" or self.depreciation_method == "Manual"
]
accumulated_depreciation = None
accumulated_depreciation = flt(self.opening_accumulated_depreciation)
value_after_depreciation = flt(row.value_after_depreciation)
for i, d in enumerate(self.get("depreciation_schedule")):
if ignore_booked_entry and d.journal_entry:
if d.journal_entry:
accumulated_depreciation = d.accumulated_depreciation_amount
continue
if not accumulated_depreciation:
if i > 0 and (
asset_doc.flags.decrease_in_asset_value_due_to_value_adjustment
or asset_doc.flags.increase_in_asset_value_due_to_repair
):
accumulated_depreciation = self.get("depreciation_schedule")[
i - 1
].accumulated_depreciation_amount
else:
accumulated_depreciation = flt(
self.opening_accumulated_depreciation,
asset_doc.precision("opening_accumulated_depreciation"),
)
value_after_depreciation -= flt(d.depreciation_amount)
value_after_depreciation = flt(value_after_depreciation, d.precision("depreciation_amount"))
value_after_depreciation = flt(
value_after_depreciation - flt(d.depreciation_amount), d.precision("depreciation_amount")
)
# for the last row, if depreciation method = Straight Line
if (
straight_line_idx
and i == max(straight_line_idx) - 1
self.depreciation_method in ("Straight Line", "Manual")
and i == len(self.get("depreciation_schedule")) - 1
and not date_of_disposal
and not date_of_return
and not row.shift_based
@@ -757,7 +738,6 @@ def make_new_active_asset_depr_schedules_and_cancel_current_ones(
date_of_disposal=None,
date_of_return=None,
value_after_depreciation=None,
ignore_booked_entry=False,
difference_amount=None,
):
for row in asset_doc.get("finance_books"):
@@ -773,6 +753,7 @@ def make_new_active_asset_depr_schedules_and_cancel_current_ones(
)
new_asset_depr_schedule_doc = frappe.copy_doc(current_asset_depr_schedule_doc)
if asset_doc.flags.decrease_in_asset_value_due_to_value_adjustment and not value_after_depreciation:
value_after_depreciation = row.value_after_depreciation - difference_amount
@@ -790,7 +771,7 @@ def make_new_active_asset_depr_schedules_and_cancel_current_ones(
asset_doc, row, date_of_disposal, value_after_depreciation=value_after_depreciation
)
new_asset_depr_schedule_doc.set_accumulated_depreciation(
asset_doc, row, date_of_disposal, date_of_return, ignore_booked_entry
asset_doc, row, date_of_disposal, date_of_return
)
new_asset_depr_schedule_doc.notes = notes

View File

@@ -27,7 +27,7 @@
"column_break_ajbh",
"column_break_hkem",
"repair_cost",
"asset_depreciation_details_section",
"accounting_dimensions_section",
"cost_center",
"column_break_14",
"project",
@@ -185,12 +185,6 @@
"label": "Total Repair Cost",
"read_only": 1
},
{
"depends_on": "capitalize_repair_cost",
"fieldname": "asset_depreciation_details_section",
"fieldtype": "Section Break",
"label": "Asset Depreciation Details"
},
{
"depends_on": "capitalize_repair_cost",
"fieldname": "increase_in_asset_life",
@@ -253,12 +247,18 @@
{
"fieldname": "column_break_xebe",
"fieldtype": "Column Break"
},
{
"depends_on": "capitalize_repair_cost",
"fieldname": "accounting_dimensions_section",
"fieldtype": "Section Break",
"label": "Accounting Dimensions"
}
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2024-12-20 13:10:31.540666",
"modified": "2024-12-23 18:08:35.159964",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset Repair",

View File

@@ -148,15 +148,12 @@ class AssetRepair(AccountsController):
self.decrease_stock_quantity()
if self.get("capitalize_repair_cost"):
self.asset_doc.flags.ignore_validate_update_after_submit = True
self.update_asset_value()
self.make_gl_entries()
self.set_increase_in_asset_life()
depreciation_note = self.get_depreciation_note()
make_new_active_asset_depr_schedules_and_cancel_current_ones(
self.asset_doc, depreciation_note, ignore_booked_entry=True
)
make_new_active_asset_depr_schedules_and_cancel_current_ones(self.asset_doc, depreciation_note)
self.add_asset_activity()
def on_cancel(self):
@@ -164,16 +161,13 @@ class AssetRepair(AccountsController):
if self.get("capitalize_repair_cost"):
self.asset_doc.flags.increase_in_asset_value_due_to_repair = True
self.asset_doc.flags.ignore_validate_update_after_submit = True
self.update_asset_value()
self.make_gl_entries(cancel=True)
self.set_increase_in_asset_life()
depreciation_note = self.get_depreciation_note()
make_new_active_asset_depr_schedules_and_cancel_current_ones(
self.asset_doc, depreciation_note, ignore_booked_entry=True
)
make_new_active_asset_depr_schedules_and_cancel_current_ones(self.asset_doc, depreciation_note)
self.add_asset_activity()
def after_delete(self):
@@ -184,16 +178,16 @@ class AssetRepair(AccountsController):
frappe.throw(_("Please update Repair Status."))
def update_asset_value(self):
if self.docstaus == 2:
self.total_repair_cost *= -1
total_repair_cost = self.total_repair_cost if self.docstatus == 1 else -1 * self.total_repair_cost
self.asset_doc.total_asset_cost += flt(self.total_repair_cost)
self.asset_doc.additional_asset_cost += flt(self.total_repair_cost)
self.asset_doc.total_asset_cost += flt(total_repair_cost)
self.asset_doc.additional_asset_cost += flt(total_repair_cost)
if self.asset_doc.calculate_depreciation:
for row in self.asset_doc.finance_books:
row.value_after_depreciation += flt(self.total_repair_cost)
row.value_after_depreciation += flt(total_repair_cost)
self.asset_doc.flags.ignore_validate_update_after_submit = True
self.asset_doc.save()
def get_total_value_of_stock_consumed(self):
@@ -377,9 +371,8 @@ class AssetRepair(AccountsController):
def add_asset_activity(self, subject=None):
if not subject:
subject = _("Asset updated due to Asset Repair {0} {1}.").format(
get_link_to_form(
self.doctype, self.name, "submission" if self.docstatus == 1 else "cancellation"
),
get_link_to_form(self.doctype, self.name),
"submission" if self.docstatus == 1 else "cancellation",
)
add_asset_activity(self.asset, subject)

View File

@@ -5,7 +5,7 @@
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import flt, formatdate, get_link_to_form, getdate
from frappe.utils import cstr, flt, formatdate, get_link_to_form, getdate
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_checks_for_pl_and_bs_accounts,
@@ -46,10 +46,26 @@ class AssetValueAdjustment(Document):
self.set_current_asset_value()
self.set_difference_amount()
def validate_date(self):
asset_purchase_date = frappe.db.get_value("Asset", self.asset, "purchase_date")
if getdate(self.date) < getdate(asset_purchase_date):
frappe.throw(
_("Asset Value Adjustment cannot be posted before Asset's purchase date <b>{0}</b>.").format(
formatdate(asset_purchase_date)
),
title=_("Incorrect Date"),
)
def set_difference_amount(self):
self.difference_amount = flt(self.new_asset_value - self.current_asset_value)
def set_current_asset_value(self):
if not self.current_asset_value and self.asset:
self.current_asset_value = get_asset_value_after_depreciation(self.asset, self.finance_book)
def on_submit(self):
self.make_depreciation_entry()
self.set_value_after_depreciation()
self.update_asset(self.new_asset_value)
self.update_asset()
add_asset_activity(
self.asset,
_("Asset's value adjusted after submission of Asset Value Adjustment {0}").format(
@@ -67,26 +83,6 @@ class AssetValueAdjustment(Document):
),
)
def validate_date(self):
asset_purchase_date = frappe.db.get_value("Asset", self.asset, "purchase_date")
if getdate(self.date) < getdate(asset_purchase_date):
frappe.throw(
_("Asset Value Adjustment cannot be posted before Asset's purchase date <b>{0}</b>.").format(
formatdate(asset_purchase_date)
),
title=_("Incorrect Date"),
)
def set_difference_amount(self):
self.difference_amount = flt(self.new_asset_value - self.current_asset_value)
def set_value_after_depreciation(self):
frappe.db.set_value("Asset", self.asset, "value_after_depreciation", self.new_asset_value)
def set_current_asset_value(self):
if not self.current_asset_value and self.asset:
self.current_asset_value = get_asset_value_after_depreciation(self.asset, self.finance_book)
def make_depreciation_entry(self):
asset = frappe.get_doc("Asset", self.asset)
(
@@ -114,46 +110,15 @@ class AssetValueAdjustment(Document):
}
if self.difference_amount < 0:
credit_entry = {
"account": fixed_asset_account,
"credit_in_account_currency": -self.difference_amount,
**entry_template,
}
debit_entry = {
"account": self.difference_account,
"debit_in_account_currency": -self.difference_amount,
**entry_template,
}
credit_entry, debit_entry = self.get_entry_for_asset_value_decrease(
fixed_asset_account, entry_template
)
elif self.difference_amount > 0:
credit_entry = {
"account": self.difference_account,
"credit_in_account_currency": self.difference_amount,
**entry_template,
}
debit_entry = {
"account": fixed_asset_account,
"debit_in_account_currency": self.difference_amount,
**entry_template,
}
credit_entry, debit_entry = self.get_entry_for_asset_value_increase(
fixed_asset_account, entry_template
)
accounting_dimensions = get_checks_for_pl_and_bs_accounts()
for dimension in accounting_dimensions:
if dimension.get("mandatory_for_bs"):
credit_entry.update(
{
dimension["fieldname"]: self.get(dimension["fieldname"])
or dimension.get("default_dimension")
}
)
if dimension.get("mandatory_for_pl"):
debit_entry.update(
{
dimension["fieldname"]: self.get(dimension["fieldname"])
or dimension.get("default_dimension")
}
)
self.update_accounting_dimensions(credit_entry, debit_entry)
je.append("accounts", credit_entry)
je.append("accounts", debit_entry)
@@ -163,40 +128,82 @@ class AssetValueAdjustment(Document):
self.db_set("journal_entry", je.name)
def update_asset(self, asset_value=None):
def get_entry_for_asset_value_decrease(self, fixed_asset_account, entry_template):
credit_entry = {
"account": fixed_asset_account,
"credit_in_account_currency": -self.difference_amount,
**entry_template,
}
debit_entry = {
"account": self.difference_account,
"debit_in_account_currency": -self.difference_amount,
**entry_template,
}
return credit_entry, debit_entry
def get_entry_for_asset_value_increase(self, fixed_asset_account, entry_template):
credit_entry = {
"account": self.difference_account,
"credit_in_account_currency": self.difference_amount,
**entry_template,
}
debit_entry = {
"account": fixed_asset_account,
"debit_in_account_currency": self.difference_amount,
**entry_template,
}
return credit_entry, debit_entry
def update_accounting_dimensions(self, credit_entry, debit_entry):
accounting_dimensions = get_checks_for_pl_and_bs_accounts()
for dimension in accounting_dimensions:
dimension_value = self.get(dimension["fieldname"]) or dimension.get("default_dimension")
if dimension.get("mandatory_for_bs"):
credit_entry.update({dimension["fieldname"]: dimension_value})
if dimension.get("mandatory_for_pl"):
debit_entry.update({dimension["fieldname"]: dimension_value})
def update_asset(self):
asset = self.update_asset_value_after_depreciation()
note = self.get_adjustment_note()
make_new_active_asset_depr_schedules_and_cancel_current_ones(asset, note)
def update_asset_value_after_depreciation(self):
difference_amount = self.difference_amount if self.docstatus == 1 else -1 * self.difference_amount
asset = frappe.get_doc("Asset", self.asset)
if not asset.calculate_depreciation:
asset.value_after_depreciation = asset_value
asset.save()
return
asset.value_after_depreciation += flt(difference_amount)
asset.db_update()
else:
for row in asset.finance_books:
if cstr(row.finance_book) == cstr(self.finance_book):
row.value_after_depreciation += flt(difference_amount)
row.db_update()
asset.flags.decrease_in_asset_value_due_to_value_adjustment = True
return asset
def get_adjustment_note(self):
if self.docstatus == 1:
notes = _(
"This schedule was created when Asset {0} was adjusted through Asset Value Adjustment {1}."
).format(
get_link_to_form("Asset", asset.name),
get_link_to_form("Asset", self.asset),
get_link_to_form(self.get("doctype"), self.get("name")),
)
elif self.docstatus == 2:
notes = _(
"This schedule was created when Asset {0}'s Asset Value Adjustment {1} was cancelled."
).format(
get_link_to_form("Asset", asset.name),
get_link_to_form("Asset", self.asset),
get_link_to_form(self.get("doctype"), self.get("name")),
)
make_new_active_asset_depr_schedules_and_cancel_current_ones(
asset,
notes,
value_after_depreciation=asset_value,
ignore_booked_entry=True,
difference_amount=self.difference_amount,
)
asset.flags.ignore_validate_update_after_submit = True
asset.save()
return notes
@frappe.whitelist()