From b661f5758a8fe2ea2bf63289c9b3201d44abbc1b Mon Sep 17 00:00:00 2001 From: anandbaburajan Date: Thu, 8 Dec 2022 01:00:57 +0530 Subject: [PATCH 1/3] fix: handle_post_depr_entries_fail, show error alert and send email --- erpnext/assets/doctype/asset/asset.js | 17 +++++ erpnext/assets/doctype/asset/asset.json | 13 +++- erpnext/assets/doctype/asset/depreciation.py | 68 ++++++++++++++++++-- 3 files changed, 93 insertions(+), 5 deletions(-) diff --git a/erpnext/assets/doctype/asset/asset.js b/erpnext/assets/doctype/asset/asset.js index 7e542197407..7791b117444 100644 --- a/erpnext/assets/doctype/asset/asset.js +++ b/erpnext/assets/doctype/asset/asset.js @@ -136,6 +136,10 @@ frappe.ui.form.on('Asset', { }, __("Manage")); } + if (frm.doc.depr_entry_posting_status === "Failed") { + frm.trigger("set_depr_posting_failure_alert"); + } + frm.trigger("setup_chart"); } @@ -146,6 +150,19 @@ frappe.ui.form.on('Asset', { } }, + set_depr_posting_failure_alert: function (frm) { + const alert = ` +
+
+ + Failed to post depreciation entries + +
+
`; + + frm.dashboard.set_headline_alert(alert); + }, + toggle_reference_doc: function(frm) { if (frm.doc.purchase_receipt && frm.doc.purchase_invoice && frm.doc.docstatus === 1) { frm.set_df_property('purchase_invoice', 'read_only', 1); diff --git a/erpnext/assets/doctype/asset/asset.json b/erpnext/assets/doctype/asset/asset.json index f0505ff9835..8b6af47b049 100644 --- a/erpnext/assets/doctype/asset/asset.json +++ b/erpnext/assets/doctype/asset/asset.json @@ -70,6 +70,7 @@ "column_break_51", "purchase_receipt_amount", "default_finance_book", + "depr_entry_posting_status", "amended_from" ], "fields": [ @@ -488,6 +489,16 @@ "fieldtype": "Int", "label": "Asset Quantity", "read_only_depends_on": "eval:!doc.is_existing_asset" + }, + { + "fieldname": "depr_entry_posting_status", + "fieldtype": "Select", + "hidden": 1, + "label": "Depreciation Entry Posting Status", + "no_copy": 1, + "options": "\nSuccessful\nFailed", + "print_hide": 1, + "read_only": 1 } ], "idx": 72, @@ -510,7 +521,7 @@ "link_fieldname": "asset" } ], - "modified": "2022-07-20 10:15:12.887372", + "modified": "2022-12-05 16:21:30.024060", "modified_by": "Administrator", "module": "Assets", "name": "Asset", diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py index 97941706aa8..4da2b42a1a0 100644 --- a/erpnext/assets/doctype/asset/depreciation.py +++ b/erpnext/assets/doctype/asset/depreciation.py @@ -5,6 +5,9 @@ import frappe from frappe import _ from frappe.utils import add_months, cint, flt, getdate, nowdate, today +from frappe.utils.user import get_users_with_role +from frappe.utils.data import get_link_to_form + from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import ( get_checks_for_pl_and_bs_accounts, @@ -12,7 +15,7 @@ from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import ( from erpnext.accounts.doctype.journal_entry.journal_entry import make_reverse_journal_entry -def post_depreciation_entries(date=None, commit=True): +def post_depreciation_entries(date=None): # Return if automatic booking of asset depreciation is disabled if not cint( frappe.db.get_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically") @@ -21,10 +24,22 @@ def post_depreciation_entries(date=None, commit=True): if not date: date = today() - for asset in get_depreciable_assets(date): - make_depreciation_entry(asset, date) - if commit: + + failed_asset_names = [] + + for asset_name in get_depreciable_assets(date): + try: + make_depreciation_entry(asset_name, date) frappe.db.commit() + except Exception as e: + frappe.db.rollback() + failed_asset_names.append(asset_name) + + if failed_asset_names: + mark_asset_depr_entry_posting_status_as_failed(failed_asset_names) + notify_depr_entry_posting_error_to_account_managers(failed_asset_names) + + frappe.db.commit() def get_depreciable_assets(date): @@ -123,6 +138,10 @@ def make_depreciation_entry(asset_name, date=None): finance_books.value_after_depreciation -= d.depreciation_amount finance_books.db_update() + asset.flags.ignore_validate_update_after_submit = True + asset.depr_entry_posting_status = "Successful" + asset.save() + asset.set_status() return asset @@ -186,6 +205,47 @@ def get_credit_and_debit_accounts(accumulated_depreciation_account, depreciation return credit_account, debit_account +def mark_asset_depr_entry_posting_status_as_failed(failed_asset_names): + for asset_name in failed_asset_names: + asset = frappe.get_doc("Asset", asset_name) + asset.flags.ignore_validate_update_after_submit = True + asset.depr_entry_posting_status = "Failed" + asset.save() + + +def notify_depr_entry_posting_error_to_account_managers(failed_asset_names): + recipients = get_users_with_role("Accounts Manager") + + if not recipients: + recipients = get_users_with_role("System Manager") + + subject = _("Error while posting depreciation entries") + + asset_links = get_comma_separated_asset_links(failed_asset_names) + + message = ( + _("Hi,") + + "
" + +_( + "The following assets have failed to post depreciation entries: {0}" + ).format(asset_links) + + "." + ) + + frappe.sendmail(recipients=recipients, subject=subject, message=message) + + +def get_comma_separated_asset_links(asset_names): + asset_links = [] + + for asset_name in asset_names: + asset_links.append(get_link_to_form("Asset", asset_name)) + + asset_links = ", ".join(asset_links) + + return asset_links + + @frappe.whitelist() def scrap_asset(asset_name): asset = frappe.get_doc("Asset", asset_name) From bb66b64b943e394c105b73100dd1466ee743affe Mon Sep 17 00:00:00 2001 From: anandbaburajan Date: Thu, 8 Dec 2022 01:35:10 +0530 Subject: [PATCH 2/3] chore: styling --- erpnext/assets/doctype/asset/depreciation.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py index 4da2b42a1a0..19796692352 100644 --- a/erpnext/assets/doctype/asset/depreciation.py +++ b/erpnext/assets/doctype/asset/depreciation.py @@ -5,9 +5,8 @@ import frappe from frappe import _ from frappe.utils import add_months, cint, flt, getdate, nowdate, today -from frappe.utils.user import get_users_with_role from frappe.utils.data import get_link_to_form - +from frappe.utils.user import get_users_with_role from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import ( get_checks_for_pl_and_bs_accounts, @@ -226,9 +225,7 @@ def notify_depr_entry_posting_error_to_account_managers(failed_asset_names): message = ( _("Hi,") + "
" - +_( - "The following assets have failed to post depreciation entries: {0}" - ).format(asset_links) + + _("The following assets have failed to post depreciation entries: {0}").format(asset_links) + "." ) From 4fbf65dd57d0c695dc816269c84f509ee559957a Mon Sep 17 00:00:00 2001 From: anandbaburajan Date: Thu, 8 Dec 2022 21:04:08 +0530 Subject: [PATCH 3/3] chore: use frappe.db.set_value instead of asset.save --- erpnext/assets/doctype/asset/depreciation.py | 17 ++++++----------- erpnext/assets/doctype/asset/test_asset.py | 1 + 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/erpnext/assets/doctype/asset/depreciation.py b/erpnext/assets/doctype/asset/depreciation.py index 19796692352..c6daccc9728 100644 --- a/erpnext/assets/doctype/asset/depreciation.py +++ b/erpnext/assets/doctype/asset/depreciation.py @@ -35,8 +35,8 @@ def post_depreciation_entries(date=None): failed_asset_names.append(asset_name) if failed_asset_names: - mark_asset_depr_entry_posting_status_as_failed(failed_asset_names) - notify_depr_entry_posting_error_to_account_managers(failed_asset_names) + set_depr_entry_posting_status_for_failed_assets(failed_asset_names) + notify_depr_entry_posting_error(failed_asset_names) frappe.db.commit() @@ -137,9 +137,7 @@ def make_depreciation_entry(asset_name, date=None): finance_books.value_after_depreciation -= d.depreciation_amount finance_books.db_update() - asset.flags.ignore_validate_update_after_submit = True - asset.depr_entry_posting_status = "Successful" - asset.save() + frappe.db.set_value("Asset", asset_name, "depr_entry_posting_status", "Successful") asset.set_status() @@ -204,15 +202,12 @@ def get_credit_and_debit_accounts(accumulated_depreciation_account, depreciation return credit_account, debit_account -def mark_asset_depr_entry_posting_status_as_failed(failed_asset_names): +def set_depr_entry_posting_status_for_failed_assets(failed_asset_names): for asset_name in failed_asset_names: - asset = frappe.get_doc("Asset", asset_name) - asset.flags.ignore_validate_update_after_submit = True - asset.depr_entry_posting_status = "Failed" - asset.save() + frappe.db.set_value("Asset", asset_name, "depr_entry_posting_status", "Failed") -def notify_depr_entry_posting_error_to_account_managers(failed_asset_names): +def notify_depr_entry_posting_error(failed_asset_names): recipients = get_users_with_role("Accounts Manager") if not recipients: diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py index baed310adb9..5a31ca0e2d7 100644 --- a/erpnext/assets/doctype/asset/test_asset.py +++ b/erpnext/assets/doctype/asset/test_asset.py @@ -1478,6 +1478,7 @@ def create_asset(**args): "asset_owner": args.asset_owner or "Company", "is_existing_asset": args.is_existing_asset or 1, "asset_quantity": args.get("asset_quantity") or 1, + "depr_entry_posting_status": args.depr_entry_posting_status or "", } )