diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index a3047c9339d..ea7583e6218 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -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"
diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py
index de3fb10324d..a65246ee820 100644
--- a/erpnext/assets/doctype/asset/asset.py
+++ b/erpnext/assets/doctype/asset/asset.py
@@ -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()
diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py
index bf2f3fad049..4566f52b20a 100644
--- a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py
+++ b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py
@@ -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
diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.json b/erpnext/assets/doctype/asset_repair/asset_repair.json
index b74292a093e..54a067063b2 100644
--- a/erpnext/assets/doctype/asset_repair/asset_repair.json
+++ b/erpnext/assets/doctype/asset_repair/asset_repair.json
@@ -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",
diff --git a/erpnext/assets/doctype/asset_repair/asset_repair.py b/erpnext/assets/doctype/asset_repair/asset_repair.py
index 8a179ea5b68..8b541163179 100644
--- a/erpnext/assets/doctype/asset_repair/asset_repair.py
+++ b/erpnext/assets/doctype/asset_repair/asset_repair.py
@@ -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)
diff --git a/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py b/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
index 6766b827f7f..07817d8e6ad 100644
--- a/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
+++ b/erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
@@ -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 {0}.").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 {0}.").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()