From 5d978c27290fa521aa59dc1c42c254924d5d1608 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 26 Mar 2024 17:04:48 +0530 Subject: [PATCH 01/13] feat: ledger health doctype (cherry picked from commit 9ed74dd8cc8911f25af31a21dfec1b5185b4b49a) --- .../doctype/ledger_health/__init__.py | 0 .../doctype/ledger_health/ledger_health.js | 8 +++ .../doctype/ledger_health/ledger_health.json | 55 +++++++++++++++++++ .../doctype/ledger_health/ledger_health.py | 23 ++++++++ .../ledger_health/test_ledger_health.py | 9 +++ 5 files changed, 95 insertions(+) create mode 100644 erpnext/accounts/doctype/ledger_health/__init__.py create mode 100644 erpnext/accounts/doctype/ledger_health/ledger_health.js create mode 100644 erpnext/accounts/doctype/ledger_health/ledger_health.json create mode 100644 erpnext/accounts/doctype/ledger_health/ledger_health.py create mode 100644 erpnext/accounts/doctype/ledger_health/test_ledger_health.py diff --git a/erpnext/accounts/doctype/ledger_health/__init__.py b/erpnext/accounts/doctype/ledger_health/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/ledger_health/ledger_health.js b/erpnext/accounts/doctype/ledger_health/ledger_health.js new file mode 100644 index 00000000000..e207daef511 --- /dev/null +++ b/erpnext/accounts/doctype/ledger_health/ledger_health.js @@ -0,0 +1,8 @@ +// Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("Ledger Health", { +// refresh(frm) { + +// }, +// }); diff --git a/erpnext/accounts/doctype/ledger_health/ledger_health.json b/erpnext/accounts/doctype/ledger_health/ledger_health.json new file mode 100644 index 00000000000..b7dfdec937e --- /dev/null +++ b/erpnext/accounts/doctype/ledger_health/ledger_health.json @@ -0,0 +1,55 @@ +{ + "actions": [], + "autoname": "autoincrement", + "creation": "2024-03-26 17:01:47.443986", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "voucher_type", + "voucher_no", + "debit_credit_mismatch" + ], + "fields": [ + { + "fieldname": "voucher_type", + "fieldtype": "Data", + "label": "Voucher Type" + }, + { + "fieldname": "voucher_no", + "fieldtype": "Data", + "label": "Voucher No" + }, + { + "default": "0", + "fieldname": "debit_credit_mismatch", + "fieldtype": "Check", + "label": "Debit-Credit mismatch" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2024-03-26 17:53:04.985881", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Ledger Health", + "naming_rule": "Autoincrement", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/ledger_health/ledger_health.py b/erpnext/accounts/doctype/ledger_health/ledger_health.py new file mode 100644 index 00000000000..f2fe23560fe --- /dev/null +++ b/erpnext/accounts/doctype/ledger_health/ledger_health.py @@ -0,0 +1,23 @@ +# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class LedgerHealth(Document): + # begin: auto-generated types + # This code is auto-generated. Do not modify anything in this block. + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + debit_credit_mismatch: DF.Check + name: DF.Int | None + voucher_no: DF.Data | None + voucher_type: DF.Data | None + # end: auto-generated types + + pass diff --git a/erpnext/accounts/doctype/ledger_health/test_ledger_health.py b/erpnext/accounts/doctype/ledger_health/test_ledger_health.py new file mode 100644 index 00000000000..ca647c99be9 --- /dev/null +++ b/erpnext/accounts/doctype/ledger_health/test_ledger_health.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestLedgerHealth(FrappeTestCase): + pass From b8bcae925273e13aa68676f72d8fdfa4474f1f43 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 26 Mar 2024 17:57:04 +0530 Subject: [PATCH 02/13] refactor: date on which vouchers was reported (cherry picked from commit 402ffc6d27374b413af6b95d9b715acc82d34a20) --- .../accounts/doctype/ledger_health/ledger_health.json | 10 ++++++++-- .../accounts/doctype/ledger_health/ledger_health.py | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/ledger_health/ledger_health.json b/erpnext/accounts/doctype/ledger_health/ledger_health.json index b7dfdec937e..2bb1ccb48a8 100644 --- a/erpnext/accounts/doctype/ledger_health/ledger_health.json +++ b/erpnext/accounts/doctype/ledger_health/ledger_health.json @@ -7,7 +7,8 @@ "field_order": [ "voucher_type", "voucher_no", - "debit_credit_mismatch" + "debit_credit_mismatch", + "checked_on" ], "fields": [ { @@ -25,11 +26,16 @@ "fieldname": "debit_credit_mismatch", "fieldtype": "Check", "label": "Debit-Credit mismatch" + }, + { + "fieldname": "checked_on", + "fieldtype": "Datetime", + "label": "Checked On" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2024-03-26 17:53:04.985881", + "modified": "2024-03-26 17:54:47.662290", "modified_by": "Administrator", "module": "Accounts", "name": "Ledger Health", diff --git a/erpnext/accounts/doctype/ledger_health/ledger_health.py b/erpnext/accounts/doctype/ledger_health/ledger_health.py index f2fe23560fe..f4a3af10f58 100644 --- a/erpnext/accounts/doctype/ledger_health/ledger_health.py +++ b/erpnext/accounts/doctype/ledger_health/ledger_health.py @@ -14,6 +14,7 @@ class LedgerHealth(Document): if TYPE_CHECKING: from frappe.types import DF + checked_on: DF.Datetime | None debit_credit_mismatch: DF.Check name: DF.Int | None voucher_no: DF.Data | None From 6bf997ee96db26486d2ea4532f20096e5cd942ae Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 26 Mar 2024 20:00:48 +0530 Subject: [PATCH 03/13] refactor: flag for general and payment ledger mismatch (cherry picked from commit d620b9eae8899c62302531e671f5d8c47d06672b) --- .../accounts/doctype/ledger_health/ledger_health.json | 11 +++++++++-- .../accounts/doctype/ledger_health/ledger_health.py | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/ledger_health/ledger_health.json b/erpnext/accounts/doctype/ledger_health/ledger_health.json index 2bb1ccb48a8..e17f4e8f2d7 100644 --- a/erpnext/accounts/doctype/ledger_health/ledger_health.json +++ b/erpnext/accounts/doctype/ledger_health/ledger_health.json @@ -7,8 +7,9 @@ "field_order": [ "voucher_type", "voucher_no", + "checked_on", "debit_credit_mismatch", - "checked_on" + "general_and_payment_ledger_mismatch" ], "fields": [ { @@ -31,11 +32,17 @@ "fieldname": "checked_on", "fieldtype": "Datetime", "label": "Checked On" + }, + { + "default": "0", + "fieldname": "general_and_payment_ledger_mismatch", + "fieldtype": "Check", + "label": "General and Payment Ledger mismatch" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2024-03-26 17:54:47.662290", + "modified": "2024-03-26 19:59:41.180161", "modified_by": "Administrator", "module": "Accounts", "name": "Ledger Health", diff --git a/erpnext/accounts/doctype/ledger_health/ledger_health.py b/erpnext/accounts/doctype/ledger_health/ledger_health.py index f4a3af10f58..590ff80cc11 100644 --- a/erpnext/accounts/doctype/ledger_health/ledger_health.py +++ b/erpnext/accounts/doctype/ledger_health/ledger_health.py @@ -16,6 +16,7 @@ class LedgerHealth(Document): checked_on: DF.Datetime | None debit_credit_mismatch: DF.Check + general_and_payment_ledger_mismatch: DF.Check name: DF.Int | None voucher_no: DF.Data | None voucher_type: DF.Data | None From 0f927f99a4a0d50c18ca19021614e31616bfe835 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 26 Mar 2024 17:57:43 +0530 Subject: [PATCH 04/13] refactor: barebones method to run checks (cherry picked from commit 8c8d9be8105918b86b80c0488557f94bc82ecebd) --- erpnext/accounts/utils.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 2e614753de5..497be117a4b 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -13,11 +13,13 @@ from frappe.query_builder import AliasedQuery, Criterion, Table from frappe.query_builder.functions import Sum from frappe.query_builder.utils import DocType from frappe.utils import ( + add_days, cint, create_batch, cstr, flt, formatdate, + get_datetime, get_number_format_info, getdate, now, @@ -2097,3 +2099,40 @@ def create_gain_loss_journal( def get_party_types_from_account_type(account_type): return frappe.db.get_all("Party Type", {"account_type": account_type}, pluck="name") + + +def run_ledger_health_checks(): + # run for last 1 month + period_end = getdate() + period_start = add_days(period_end, -100) + + run_date = get_datetime() + + # Debit-Credit mismatch report + voucher_wise = frappe.get_doc("Report", "Voucher-wise Balance") + + # todo: company and dates should be configurable + filters = {"company": "நுண்ணறி", "from_date": period_start, "to_date": period_end} + + res = voucher_wise.execute_script_report(filters=filters) + for x in res[1]: + doc = frappe.new_doc("Ledger Health") + doc.voucher_type = x.voucher_type + doc.voucher_no = x.voucher_no + doc.debit_credit_mismatch = True + doc.checked_on = run_date + doc.save() + + # General Ledger and Payment Ledger discrepancy + gl_pl_comparison = frappe.get_doc("Report", "General and Payment Ledger Comparison") + # todo: company and dates should be configurable + filters = {"company": "நுண்ணறி", "period_start_date": period_start, "period_end_date": period_end} + res = gl_pl_comparison.execute_script_report(filters=filters) + + for x in res[1]: + doc = frappe.new_doc("Ledger Health") + doc.voucher_type = x.voucher_type + doc.voucher_no = x.voucher_no + doc.general_and_payment_ledger_mismatch = True + doc.checked_on = run_date + doc.save() From 9fbb4f676b6b32f35584c2599e110a6b74e84196 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 27 Mar 2024 09:41:43 +0530 Subject: [PATCH 05/13] chore: settings page for health monitor (cherry picked from commit b2fb7843d1b441ccfad7e84e5828e581f8967930) --- .../doctype/ledger_health_monitor/__init__.py | 0 .../ledger_health_monitor.js | 8 +++ .../ledger_health_monitor.json | 70 +++++++++++++++++++ .../ledger_health_monitor.py | 23 ++++++ .../test_ledger_health_monitor.py | 9 +++ 5 files changed, 110 insertions(+) create mode 100644 erpnext/accounts/doctype/ledger_health_monitor/__init__.py create mode 100644 erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.js create mode 100644 erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.json create mode 100644 erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.py create mode 100644 erpnext/accounts/doctype/ledger_health_monitor/test_ledger_health_monitor.py diff --git a/erpnext/accounts/doctype/ledger_health_monitor/__init__.py b/erpnext/accounts/doctype/ledger_health_monitor/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.js b/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.js new file mode 100644 index 00000000000..cf112760f8c --- /dev/null +++ b/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.js @@ -0,0 +1,8 @@ +// Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +// frappe.ui.form.on("Ledger Health Monitor", { +// refresh(frm) { + +// }, +// }); diff --git a/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.json b/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.json new file mode 100644 index 00000000000..9a916484925 --- /dev/null +++ b/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.json @@ -0,0 +1,70 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2024-03-27 09:38:07.427997", + "doctype": "DocType", + "engine": "InnoDB", + "field_order": [ + "enable_health_monitor", + "monitor_section", + "monitor_for_last_x_days", + "debit_credit_mismatch", + "general_and_payment_ledger_mismatch" + ], + "fields": [ + { + "default": "0", + "fieldname": "enable_health_monitor", + "fieldtype": "Check", + "label": "Enable Health Monitor" + }, + { + "fieldname": "monitor_section", + "fieldtype": "Section Break", + "label": "Monitor" + }, + { + "default": "0", + "fieldname": "debit_credit_mismatch", + "fieldtype": "Check", + "label": "Debit-Credit Mismatch" + }, + { + "default": "0", + "fieldname": "general_and_payment_ledger_mismatch", + "fieldtype": "Check", + "label": "Discrepancy between General and Payment Ledger" + }, + { + "default": "60", + "fieldname": "monitor_for_last_x_days", + "fieldtype": "Int", + "in_list_view": 1, + "label": "Monitor for Last 'X' days", + "reqd": 1 + } + ], + "index_web_pages_for_search": 1, + "issingle": 1, + "links": [], + "modified": "2024-03-27 09:53:00.674708", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Ledger Health Monitor", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.py b/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.py new file mode 100644 index 00000000000..c6a33790ee9 --- /dev/null +++ b/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.py @@ -0,0 +1,23 @@ +# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class LedgerHealthMonitor(Document): + # begin: auto-generated types + # This code is auto-generated. Do not modify anything in this block. + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + debit_credit_mismatch: DF.Check + enable_health_monitor: DF.Check + general_and_payment_ledger_mismatch: DF.Check + monitor_for_last_x_days: DF.Int + # end: auto-generated types + + pass diff --git a/erpnext/accounts/doctype/ledger_health_monitor/test_ledger_health_monitor.py b/erpnext/accounts/doctype/ledger_health_monitor/test_ledger_health_monitor.py new file mode 100644 index 00000000000..e0ba4435b82 --- /dev/null +++ b/erpnext/accounts/doctype/ledger_health_monitor/test_ledger_health_monitor.py @@ -0,0 +1,9 @@ +# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +# import frappe +from frappe.tests.utils import FrappeTestCase + + +class TestLedgerHealthMonitor(FrappeTestCase): + pass From 9bae5e37cde854b794b45b94c47ab027017a8bfa Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 27 Mar 2024 10:01:03 +0530 Subject: [PATCH 06/13] refactor: control monitoring through settings page (cherry picked from commit a42482ce352432a56425434181b738145eb736f4) --- erpnext/accounts/utils.py | 62 +++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 497be117a4b..e80f937181a 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -2102,37 +2102,41 @@ def get_party_types_from_account_type(account_type): def run_ledger_health_checks(): - # run for last 1 month - period_end = getdate() - period_start = add_days(period_end, -100) + health_monitor_settings = frappe.get_doc("Ledger Health Monitor") + if health_monitor_settings.enable_health_monitor: + period_end = getdate() + period_start = add_days(period_end, -abs(health_monitor_settings.monitor_for_last_x_days)) - run_date = get_datetime() + run_date = get_datetime() - # Debit-Credit mismatch report - voucher_wise = frappe.get_doc("Report", "Voucher-wise Balance") + # Debit-Credit mismatch report + if health_monitor_settings.debit_credit_mismatch: + voucher_wise = frappe.get_doc("Report", "Voucher-wise Balance") + filters = {"company": "நுண்ணறி", "from_date": period_start, "to_date": period_end} - # todo: company and dates should be configurable - filters = {"company": "நுண்ணறி", "from_date": period_start, "to_date": period_end} + res = voucher_wise.execute_script_report(filters=filters) + for x in res[1]: + doc = frappe.new_doc("Ledger Health") + doc.voucher_type = x.voucher_type + doc.voucher_no = x.voucher_no + doc.debit_credit_mismatch = True + doc.checked_on = run_date + doc.save() - res = voucher_wise.execute_script_report(filters=filters) - for x in res[1]: - doc = frappe.new_doc("Ledger Health") - doc.voucher_type = x.voucher_type - doc.voucher_no = x.voucher_no - doc.debit_credit_mismatch = True - doc.checked_on = run_date - doc.save() + # General Ledger and Payment Ledger discrepancy + if health_monitor_settings.general_and_payment_ledger_mismatch: + gl_pl_comparison = frappe.get_doc("Report", "General and Payment Ledger Comparison") + filters = { + "company": "நுண்ணறி", + "period_start_date": period_start, + "period_end_date": period_end, + } + res = gl_pl_comparison.execute_script_report(filters=filters) - # General Ledger and Payment Ledger discrepancy - gl_pl_comparison = frappe.get_doc("Report", "General and Payment Ledger Comparison") - # todo: company and dates should be configurable - filters = {"company": "நுண்ணறி", "period_start_date": period_start, "period_end_date": period_end} - res = gl_pl_comparison.execute_script_report(filters=filters) - - for x in res[1]: - doc = frappe.new_doc("Ledger Health") - doc.voucher_type = x.voucher_type - doc.voucher_no = x.voucher_no - doc.general_and_payment_ledger_mismatch = True - doc.checked_on = run_date - doc.save() + for x in res[1]: + doc = frappe.new_doc("Ledger Health") + doc.voucher_type = x.voucher_type + doc.voucher_no = x.voucher_no + doc.general_and_payment_ledger_mismatch = True + doc.checked_on = run_date + doc.save() From 522cfd0c9a0d30bbac56e68916a17e8bc31870d4 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 27 Mar 2024 10:07:48 +0530 Subject: [PATCH 07/13] refactor: make health check configurable for companies (cherry picked from commit 704925549b4e044ee8b55f8322e4216e25c3764b) --- .../ledger_health_monitor.json | 18 +++++++++-- .../ledger_health_monitor.py | 5 +++ .../ledger_health_monitor_company/__init__.py | 0 .../ledger_health_monitor_company.json | 32 +++++++++++++++++++ .../ledger_health_monitor_company.py | 23 +++++++++++++ 5 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 erpnext/accounts/doctype/ledger_health_monitor_company/__init__.py create mode 100644 erpnext/accounts/doctype/ledger_health_monitor_company/ledger_health_monitor_company.json create mode 100644 erpnext/accounts/doctype/ledger_health_monitor_company/ledger_health_monitor_company.py diff --git a/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.json b/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.json index 9a916484925..4c1c8f80ac9 100644 --- a/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.json +++ b/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.json @@ -9,7 +9,9 @@ "monitor_section", "monitor_for_last_x_days", "debit_credit_mismatch", - "general_and_payment_ledger_mismatch" + "general_and_payment_ledger_mismatch", + "section_break_xdsp", + "companies" ], "fields": [ { @@ -21,7 +23,7 @@ { "fieldname": "monitor_section", "fieldtype": "Section Break", - "label": "Monitor" + "label": "Configuration" }, { "default": "0", @@ -42,12 +44,22 @@ "in_list_view": 1, "label": "Monitor for Last 'X' days", "reqd": 1 + }, + { + "fieldname": "section_break_xdsp", + "fieldtype": "Section Break", + "label": "Companies" + }, + { + "fieldname": "companies", + "fieldtype": "Table", + "options": "Ledger Health Monitor Company" } ], "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2024-03-27 09:53:00.674708", + "modified": "2024-03-27 10:07:28.601546", "modified_by": "Administrator", "module": "Accounts", "name": "Ledger Health Monitor", diff --git a/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.py b/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.py index c6a33790ee9..9f7c569d6d1 100644 --- a/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.py +++ b/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.py @@ -14,6 +14,11 @@ class LedgerHealthMonitor(Document): if TYPE_CHECKING: from frappe.types import DF + from erpnext.accounts.doctype.ledger_health_monitor_company.ledger_health_monitor_company import ( + LedgerHealthMonitorCompany, + ) + + companies: DF.Table[LedgerHealthMonitorCompany] debit_credit_mismatch: DF.Check enable_health_monitor: DF.Check general_and_payment_ledger_mismatch: DF.Check diff --git a/erpnext/accounts/doctype/ledger_health_monitor_company/__init__.py b/erpnext/accounts/doctype/ledger_health_monitor_company/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/ledger_health_monitor_company/ledger_health_monitor_company.json b/erpnext/accounts/doctype/ledger_health_monitor_company/ledger_health_monitor_company.json new file mode 100644 index 00000000000..87fa3e32801 --- /dev/null +++ b/erpnext/accounts/doctype/ledger_health_monitor_company/ledger_health_monitor_company.json @@ -0,0 +1,32 @@ +{ + "actions": [], + "allow_rename": 1, + "creation": "2024-03-27 10:04:45.727054", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "company" + ], + "fields": [ + { + "fieldname": "company", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Company", + "options": "Company" + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2024-03-27 10:06:22.806155", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Ledger Health Monitor Company", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "states": [] +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/ledger_health_monitor_company/ledger_health_monitor_company.py b/erpnext/accounts/doctype/ledger_health_monitor_company/ledger_health_monitor_company.py new file mode 100644 index 00000000000..5890410090d --- /dev/null +++ b/erpnext/accounts/doctype/ledger_health_monitor_company/ledger_health_monitor_company.py @@ -0,0 +1,23 @@ +# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + + +class LedgerHealthMonitorCompany(Document): + # begin: auto-generated types + # This code is auto-generated. Do not modify anything in this block. + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + company: DF.Link | None + parent: DF.Data + parentfield: DF.Data + parenttype: DF.Data + # end: auto-generated types + + pass From bf0cfae9c9abde76193aeaa16b1e4889c10ccbd4 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 27 Mar 2024 10:10:55 +0530 Subject: [PATCH 08/13] refactor: only run checks on specified companies (cherry picked from commit 00eeacd06af69a5c65b90c629d7497d8b1357751) --- erpnext/accounts/utils.py | 52 +++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index e80f937181a..a2102b17f80 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -2111,32 +2111,32 @@ def run_ledger_health_checks(): # Debit-Credit mismatch report if health_monitor_settings.debit_credit_mismatch: - voucher_wise = frappe.get_doc("Report", "Voucher-wise Balance") - filters = {"company": "நுண்ணறி", "from_date": period_start, "to_date": period_end} - - res = voucher_wise.execute_script_report(filters=filters) - for x in res[1]: - doc = frappe.new_doc("Ledger Health") - doc.voucher_type = x.voucher_type - doc.voucher_no = x.voucher_no - doc.debit_credit_mismatch = True - doc.checked_on = run_date - doc.save() + for x in health_monitor_settings.companies: + filters = {"company": x.company, "from_date": period_start, "to_date": period_end} + voucher_wise = frappe.get_doc("Report", "Voucher-wise Balance") + res = voucher_wise.execute_script_report(filters=filters) + for x in res[1]: + doc = frappe.new_doc("Ledger Health") + doc.voucher_type = x.voucher_type + doc.voucher_no = x.voucher_no + doc.debit_credit_mismatch = True + doc.checked_on = run_date + doc.save() # General Ledger and Payment Ledger discrepancy if health_monitor_settings.general_and_payment_ledger_mismatch: - gl_pl_comparison = frappe.get_doc("Report", "General and Payment Ledger Comparison") - filters = { - "company": "நுண்ணறி", - "period_start_date": period_start, - "period_end_date": period_end, - } - res = gl_pl_comparison.execute_script_report(filters=filters) - - for x in res[1]: - doc = frappe.new_doc("Ledger Health") - doc.voucher_type = x.voucher_type - doc.voucher_no = x.voucher_no - doc.general_and_payment_ledger_mismatch = True - doc.checked_on = run_date - doc.save() + for x in health_monitor_settings.companies: + filters = { + "company": x.company, + "period_start_date": period_start, + "period_end_date": period_end, + } + gl_pl_comparison = frappe.get_doc("Report", "General and Payment Ledger Comparison") + res = gl_pl_comparison.execute_script_report(filters=filters) + for x in res[1]: + doc = frappe.new_doc("Ledger Health") + doc.voucher_type = x.voucher_type + doc.voucher_no = x.voucher_no + doc.general_and_payment_ledger_mismatch = True + doc.checked_on = run_date + doc.save() From a331eadf297e0d1ae6c0e2fe469160965ac43177 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 27 Mar 2024 10:14:29 +0530 Subject: [PATCH 09/13] chore: permission and UI changes (cherry picked from commit 1a43ed763b85ffbe500d53eac600737457e7fa17) --- .../ledger_health_monitor.json | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.json b/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.json index 4c1c8f80ac9..6e688333e3f 100644 --- a/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.json +++ b/erpnext/accounts/doctype/ledger_health_monitor/ledger_health_monitor.json @@ -56,10 +56,11 @@ "options": "Ledger Health Monitor Company" } ], + "hide_toolbar": 1, "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2024-03-27 10:07:28.601546", + "modified": "2024-03-27 10:14:16.511681", "modified_by": "Administrator", "module": "Accounts", "name": "Ledger Health Monitor", @@ -74,9 +75,30 @@ "role": "System Manager", "share": 1, "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "Accounts Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "Accounts User", + "share": 1, + "write": 1 } ], "sort_field": "modified", "sort_order": "DESC", - "states": [] + "states": [], + "track_changes": 1 } \ No newline at end of file From 9834e3ab7feb85d0825a61f35060d5e78a260ce3 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 27 Mar 2024 10:33:54 +0530 Subject: [PATCH 10/13] chore: schedule job to run daily (cherry picked from commit f96cf111ed0681254a1b9f4fe11d80e84368079d) --- erpnext/hooks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 9c7d0dd698b..c01b6e1954f 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -445,6 +445,7 @@ scheduler_events = { "erpnext.buying.doctype.supplier_quotation.supplier_quotation.set_expired_status", "erpnext.accounts.doctype.process_statement_of_accounts.process_statement_of_accounts.send_auto_email", "erpnext.accounts.utils.auto_create_exchange_rate_revaluation_daily", + "erpnext.accounts.utils.run_ledger_health_checks", ], "weekly": [ "erpnext.accounts.utils.auto_create_exchange_rate_revaluation_weekly", From 711a6eaaafcad8470320c8938dfb31fcf05ccc25 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 9 Apr 2024 09:35:53 +0530 Subject: [PATCH 11/13] test: ledger monitoring function (cherry picked from commit 4776d660b535a19940b71b5d646d36792261fcb7) --- .../ledger_health/test_ledger_health.py | 106 +++++++++++++++++- 1 file changed, 103 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/ledger_health/test_ledger_health.py b/erpnext/accounts/doctype/ledger_health/test_ledger_health.py index ca647c99be9..daad855abf0 100644 --- a/erpnext/accounts/doctype/ledger_health/test_ledger_health.py +++ b/erpnext/accounts/doctype/ledger_health/test_ledger_health.py @@ -1,9 +1,109 @@ # Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and Contributors # See license.txt -# import frappe +import frappe +from frappe import qb from frappe.tests.utils import FrappeTestCase +from frappe.utils import nowdate + +from erpnext.accounts.test.accounts_mixin import AccountsTestMixin +from erpnext.accounts.utils import run_ledger_health_checks -class TestLedgerHealth(FrappeTestCase): - pass +class TestLedgerHealth(AccountsTestMixin, FrappeTestCase): + def setUp(self): + self.create_company() + self.create_customer() + self.configure_monitoring_tool() + self.clear_old_entries() + + def tearDown(self): + frappe.db.rollback() + + def configure_monitoring_tool(self): + monitor_settings = frappe.get_doc("Ledger Health Monitor") + monitor_settings.enable_health_monitor = True + monitor_settings.enable_for_last_x_days = 60 + monitor_settings.debit_credit_mismatch = True + monitor_settings.general_and_payment_ledger_mismatch = True + exists = [x for x in monitor_settings.companies if x.company == self.company] + if not exists: + monitor_settings.append("companies", {"company": self.company}) + monitor_settings.save() + + def clear_old_entries(self): + super(TestLedgerHealth, self).clear_old_entries() + lh = qb.DocType("Ledger Health") + qb.from_(lh).delete().run() + + def create_journal(self): + je = frappe.new_doc("Journal Entry") + je.company = self.company + je.voucher_type = "Journal Entry" + je.posting_date = nowdate() + je.append( + "accounts", + { + "account": self.debit_to, + "party_type": "Customer", + "party": self.customer, + "debit_in_account_currency": 10000, + }, + ) + je.append("accounts", {"account": self.income_account, "credit_in_account_currency": 10000}) + je.save().submit() + self.je = je + + def test_debit_credit_mismatch(self): + self.create_journal() + + # manually cause debit-credit mismatch + gle = frappe.db.get_all( + "GL Entry", filters={"voucher_no": self.je.name, "account": self.income_account} + )[0] + frappe.db.set_value("GL Entry", gle.name, "credit", 8000) + + run_ledger_health_checks() + expected = { + "voucher_type": self.je.doctype, + "voucher_no": self.je.name, + "debit_credit_mismatch": True, + "general_and_payment_ledger_mismatch": False, + } + actual = frappe.db.get_all( + "Ledger Health", + fields=[ + "voucher_type", + "voucher_no", + "debit_credit_mismatch", + "general_and_payment_ledger_mismatch", + ], + ) + self.assertEqual(len(actual), 1) + self.assertEqual(expected, actual[0]) + + def test_gl_and_pl_mismatch(self): + self.create_journal() + + # manually cause GL and PL discrepancy + ple = frappe.db.get_all("Payment Ledger Entry", filters={"voucher_no": self.je.name})[0] + frappe.db.set_value("Payment Ledger Entry", ple.name, "amount", 11000) + + run_ledger_health_checks() + expected = { + "voucher_type": self.je.doctype, + "voucher_no": self.je.name, + "debit_credit_mismatch": False, + "general_and_payment_ledger_mismatch": True, + } + actual = frappe.db.get_all( + "Ledger Health", + fields=[ + "voucher_type", + "voucher_no", + "debit_credit_mismatch", + "general_and_payment_ledger_mismatch", + ], + ) + self.assertEqual(len(actual), 1) + self.assertEqual(expected, actual[0]) From d8f627a9d7e31daa9aa6a9de4b6ed767bb3629cb Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 9 Apr 2024 11:18:53 +0530 Subject: [PATCH 12/13] chore: make ledger health doctype read_only (cherry picked from commit dc79213bb372c0171f6f4d9bab92b91eb5d7314a) --- erpnext/accounts/doctype/ledger_health/ledger_health.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/ledger_health/ledger_health.json b/erpnext/accounts/doctype/ledger_health/ledger_health.json index e17f4e8f2d7..fb2da3d2564 100644 --- a/erpnext/accounts/doctype/ledger_health/ledger_health.json +++ b/erpnext/accounts/doctype/ledger_health/ledger_health.json @@ -40,9 +40,10 @@ "label": "General and Payment Ledger mismatch" } ], + "in_create": 1, "index_web_pages_for_search": 1, "links": [], - "modified": "2024-03-26 19:59:41.180161", + "modified": "2024-04-09 11:16:07.044484", "modified_by": "Administrator", "module": "Accounts", "name": "Ledger Health", @@ -62,6 +63,7 @@ "write": 1 } ], + "read_only": 1, "sort_field": "modified", "sort_order": "DESC", "states": [] From b22784878f5b90c194bfb69c4d6fd89da566ad04 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 9 Apr 2024 17:35:15 +0530 Subject: [PATCH 13/13] chore: use super() instead of super(__class__, self) (cherry picked from commit 24d37d22a3d5bb52a5b7ee2e0157bc400c50b323) --- erpnext/accounts/doctype/ledger_health/test_ledger_health.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/ledger_health/test_ledger_health.py b/erpnext/accounts/doctype/ledger_health/test_ledger_health.py index daad855abf0..d35b39d9ea1 100644 --- a/erpnext/accounts/doctype/ledger_health/test_ledger_health.py +++ b/erpnext/accounts/doctype/ledger_health/test_ledger_health.py @@ -32,7 +32,7 @@ class TestLedgerHealth(AccountsTestMixin, FrappeTestCase): monitor_settings.save() def clear_old_entries(self): - super(TestLedgerHealth, self).clear_old_entries() + super().clear_old_entries() lh = qb.DocType("Ledger Health") qb.from_(lh).delete().run()