From 71767994a77349797af70676b1ff42bdc902bc2b Mon Sep 17 00:00:00 2001 From: anandbaburajan Date: Fri, 24 Feb 2023 16:38:39 +0530 Subject: [PATCH 1/5] fix: manual depr schedule (cherry picked from commit 971c0720e52b5120ab3497f3fc5bd5964b0deff7) --- erpnext/assets/doctype/asset/asset.js | 18 +++++++++++------- erpnext/assets/doctype/asset/asset.py | 15 +++++++++------ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js index ccd8d8171a8..4def1ccc72d 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -519,19 +519,23 @@ frappe.ui.form.on('Depreciation Schedule', { }, depreciation_amount: function(frm, cdt, cdn) { - erpnext.asset.set_accumulated_depreciation(frm); + erpnext.asset.set_accumulated_depreciation(frm, locals[cdt][cdn].finance_book_id); } -}) +}); -erpnext.asset.set_accumulated_depreciation = function(frm) { - if(frm.doc.depreciation_method != "Manual") return; +erpnext.asset.set_accumulated_depreciation = function(frm, finance_book_id) { + var depreciation_method = frm.doc.finance_books[Number(finance_book_id) - 1].depreciation_method; + + if(depreciation_method != "Manual") return; var accumulated_depreciation = flt(frm.doc.opening_accumulated_depreciation); + $.each(frm.doc.schedules || [], function(i, row) { - accumulated_depreciation += flt(row.depreciation_amount); - frappe.model.set_value(row.doctype, row.name, - "accumulated_depreciation_amount", accumulated_depreciation); + if (row.finance_book_id === finance_book_id) { + accumulated_depreciation += flt(row.depreciation_amount); + frappe.model.set_value(row.doctype, row.name, "accumulated_depreciation_amount", accumulated_depreciation); + }; }) }; diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 2bd30c6cbd4..fd34f071dcb 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -84,8 +84,11 @@ class Asset(AccountsController): if self.calculate_depreciation: self.value_after_depreciation = 0 self.set_depreciation_rate() - self.make_depreciation_schedule(date_of_disposal) - self.set_accumulated_depreciation(date_of_disposal, date_of_return) + if not ( + self.get("schedules") and "Manual" in [d.depreciation_method for d in self.finance_books] + ): + self.make_depreciation_schedule(date_of_disposal) + self.set_accumulated_depreciation(date_of_disposal, date_of_return) else: self.finance_books = [] self.value_after_depreciation = flt(self.gross_purchase_amount) - flt( @@ -225,9 +228,7 @@ class Asset(AccountsController): ) def make_depreciation_schedule(self, date_of_disposal): - if "Manual" not in [d.depreciation_method for d in self.finance_books] and not self.get( - "schedules" - ): + if not self.get("schedules"): self.schedules = [] if not self.available_for_use_date: @@ -546,7 +547,9 @@ class Asset(AccountsController): self, date_of_disposal=None, date_of_return=None, ignore_booked_entry=False ): straight_line_idx = [ - d.idx for d in self.get("schedules") if d.depreciation_method == "Straight Line" + d.idx + for d in self.get("schedules") + if d.depreciation_method == "Straight Line" or d.depreciation_method == "Manual" ] finance_books = [] From 4a557b47d7a4f892a652f561b763e52b32149cd7 Mon Sep 17 00:00:00 2001 From: anandbaburajan Date: Fri, 24 Feb 2023 20:34:36 +0530 Subject: [PATCH 2/5] chore: handle change in opening_accumulated_depreciation properly (cherry picked from commit b0d670a51da32ebafef0a9eef39083bd2d8fdf43) --- erpnext/assets/doctype/asset/asset.js | 4 ---- erpnext/assets/doctype/asset/asset.py | 5 ++++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js index 4def1ccc72d..6d0b77abcd7 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -296,10 +296,6 @@ frappe.ui.form.on('Asset', { // frm.toggle_reqd("next_depreciation_date", (!frm.doc.is_existing_asset && frm.doc.calculate_depreciation)); }, - opening_accumulated_depreciation: function(frm) { - erpnext.asset.set_accumulated_depreciation(frm); - }, - make_schedules_editable: function(frm) { if (frm.doc.finance_books) { var is_editable = frm.doc.finance_books.filter(d => d.depreciation_method == "Manual").length > 0 diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index fd34f071dcb..59ed2f6d54a 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -85,7 +85,10 @@ class Asset(AccountsController): self.value_after_depreciation = 0 self.set_depreciation_rate() if not ( - self.get("schedules") and "Manual" in [d.depreciation_method for d in self.finance_books] + self.get("schedules") + and "Manual" in [d.depreciation_method for d in self.finance_books] + and self.get_doc_before_save().opening_accumulated_depreciation + == self.opening_accumulated_depreciation ): self.make_depreciation_schedule(date_of_disposal) self.set_accumulated_depreciation(date_of_disposal, date_of_return) From 304e6bb9963649f5e0802c63771a6e6b295aea54 Mon Sep 17 00:00:00 2001 From: anandbaburajan Date: Sat, 25 Feb 2023 14:43:24 +0530 Subject: [PATCH 3/5] fix: incorrect acc depr amount if multiple FBs with straight line or manual method (cherry picked from commit dda6baea3ed18546ce8493ad8ccc519f280d5b29) --- erpnext/assets/doctype/asset/asset.py | 52 +++++++++++++++++++++------ 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 59ed2f6d54a..b2d1c7349bb 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -84,12 +84,7 @@ class Asset(AccountsController): if self.calculate_depreciation: self.value_after_depreciation = 0 self.set_depreciation_rate() - if not ( - self.get("schedules") - and "Manual" in [d.depreciation_method for d in self.finance_books] - and self.get_doc_before_save().opening_accumulated_depreciation - == self.opening_accumulated_depreciation - ): + if self.should_prepare_depreciation_schedule(): self.make_depreciation_schedule(date_of_disposal) self.set_accumulated_depreciation(date_of_disposal, date_of_return) else: @@ -98,6 +93,39 @@ class Asset(AccountsController): self.opening_accumulated_depreciation ) + def should_prepare_depreciation_schedule(self): + if not self.get("schedules"): + return True + + old_asset_doc = self.get_doc_before_save() + + if ( + old_asset_doc.gross_purchase_amount != self.gross_purchase_amount + or old_asset_doc.opening_accumulated_depreciation != self.opening_accumulated_depreciation + or old_asset_doc.number_of_depreciations_booked != self.number_of_depreciations_booked + ): + return True + + manual_fb_idx = -1 + for d in self.finance_books: + if d.depreciation_method == "Manual": + manual_fb_idx = d.idx + + if ( + manual_fb_idx == -1 + or old_asset_doc.finance_books[manual_fb_idx - 1].total_number_of_depreciations + != self.finance_books[manual_fb_idx - 1].total_number_of_depreciations + or old_asset_doc.finance_books[manual_fb_idx - 1].frequency_of_depreciation + != self.finance_books[manual_fb_idx - 1].frequency_of_depreciation + or old_asset_doc.finance_books[manual_fb_idx - 1].depreciation_start_date + != getdate(self.finance_books[manual_fb_idx - 1].depreciation_start_date) + or old_asset_doc.finance_books[manual_fb_idx - 1].expected_value_after_useful_life + != self.finance_books[manual_fb_idx - 1].expected_value_after_useful_life + ): + return True + + return False + def validate_item(self): item = frappe.get_cached_value( "Item", self.item_code, ["is_fixed_asset", "is_stock_item", "disabled"], as_dict=1 @@ -549,11 +577,7 @@ class Asset(AccountsController): def set_accumulated_depreciation( self, date_of_disposal=None, date_of_return=None, ignore_booked_entry=False ): - straight_line_idx = [ - d.idx - for d in self.get("schedules") - if d.depreciation_method == "Straight Line" or d.depreciation_method == "Manual" - ] + straight_line_idx = [] finance_books = [] for i, d in enumerate(self.get("schedules")): @@ -561,6 +585,12 @@ class Asset(AccountsController): continue if int(d.finance_book_id) not in finance_books: + straight_line_idx = [ + s.idx + for s in self.get("schedules") + if s.finance_book_id == d.finance_book_id + and (s.depreciation_method == "Straight Line" or s.depreciation_method == "Manual") + ] accumulated_depreciation = flt(self.opening_accumulated_depreciation) value_after_depreciation = flt( self.get("finance_books")[cint(d.finance_book_id) - 1].value_after_depreciation From 9a607b9bd072b3496e865ec188581dc016dca899 Mon Sep 17 00:00:00 2001 From: anandbaburajan Date: Sat, 25 Feb 2023 21:17:18 +0530 Subject: [PATCH 4/5] chore: should prepare schedule if not draft (cherry picked from commit 75386e3653657ec26d444b73e3032cbf51f123c3) --- erpnext/assets/doctype/asset/asset.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index b2d1c7349bb..15c20a59a88 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -99,6 +99,9 @@ class Asset(AccountsController): old_asset_doc = self.get_doc_before_save() + if not old_asset_doc: + return True + if ( old_asset_doc.gross_purchase_amount != self.gross_purchase_amount or old_asset_doc.opening_accumulated_depreciation != self.opening_accumulated_depreciation From 9942a9d40a300661a4c3c2f5fe0756c4715f7e9d Mon Sep 17 00:00:00 2001 From: anandbaburajan Date: Sun, 26 Feb 2023 15:03:16 +0530 Subject: [PATCH 5/5] chore: refactor long if conditions (cherry picked from commit d56ca011fef658c4030e3c326bc5658c86100716) --- erpnext/assets/doctype/asset/asset.py | 30 +++++++++++++++------------ 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.py b/erpnext/assets/doctype/asset/asset.py index 15c20a59a88..d44e2ec0c5d 100644 --- a/erpnext/assets/doctype/asset/asset.py +++ b/erpnext/assets/doctype/asset/asset.py @@ -102,29 +102,33 @@ class Asset(AccountsController): if not old_asset_doc: return True - if ( + have_asset_details_been_modified = ( old_asset_doc.gross_purchase_amount != self.gross_purchase_amount or old_asset_doc.opening_accumulated_depreciation != self.opening_accumulated_depreciation or old_asset_doc.number_of_depreciations_booked != self.number_of_depreciations_booked - ): + ) + + if have_asset_details_been_modified: return True manual_fb_idx = -1 for d in self.finance_books: if d.depreciation_method == "Manual": - manual_fb_idx = d.idx + manual_fb_idx = d.idx - 1 - if ( + no_manual_depr_or_have_manual_depr_details_been_modified = ( manual_fb_idx == -1 - or old_asset_doc.finance_books[manual_fb_idx - 1].total_number_of_depreciations - != self.finance_books[manual_fb_idx - 1].total_number_of_depreciations - or old_asset_doc.finance_books[manual_fb_idx - 1].frequency_of_depreciation - != self.finance_books[manual_fb_idx - 1].frequency_of_depreciation - or old_asset_doc.finance_books[manual_fb_idx - 1].depreciation_start_date - != getdate(self.finance_books[manual_fb_idx - 1].depreciation_start_date) - or old_asset_doc.finance_books[manual_fb_idx - 1].expected_value_after_useful_life - != self.finance_books[manual_fb_idx - 1].expected_value_after_useful_life - ): + or old_asset_doc.finance_books[manual_fb_idx].total_number_of_depreciations + != self.finance_books[manual_fb_idx].total_number_of_depreciations + or old_asset_doc.finance_books[manual_fb_idx].frequency_of_depreciation + != self.finance_books[manual_fb_idx].frequency_of_depreciation + or old_asset_doc.finance_books[manual_fb_idx].depreciation_start_date + != getdate(self.finance_books[manual_fb_idx].depreciation_start_date) + or old_asset_doc.finance_books[manual_fb_idx].expected_value_after_useful_life + != self.finance_books[manual_fb_idx].expected_value_after_useful_life + ) + + if no_manual_depr_or_have_manual_depr_details_been_modified: return True return False