diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.js b/erpnext/accounts/doctype/accounts_settings/accounts_settings.js index 5b9a52e8f8b..4f59085db0a 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.js +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.js @@ -3,4 +3,23 @@ frappe.ui.form.on("Accounts Settings", { refresh: function (frm) {}, + enable_immutable_ledger: function (frm) { + if (!frm.doc.enable_immutable_ledger) { + return; + } + + let msg = __("Enabling this will change the way how cancelled transactions are handled."); + msg += " "; + msg += __("Please enable only if the understand the effects of enabling this."); + msg += "
"; + msg += "Do you still want to enable immutable ledger?"; + + frappe.confirm( + msg, + () => {}, + () => { + frm.set_value("enable_immutable_ledger", 0); + } + ); + }, }); diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json index 23782f74f72..de8260b2a3d 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -12,6 +12,7 @@ "unlink_advance_payment_on_cancelation_of_order", "column_break_13", "delete_linked_ledger_entries", + "enable_immutable_ledger", "invoicing_features_section", "check_supplier_invoice_uniqueness", "automatically_fetch_payment_terms", @@ -454,6 +455,13 @@ "fieldname": "remarks_section", "fieldtype": "Section Break", "label": "Remarks Column Length" + }, + { + "default": "0", + "description": "On enabling this cancellation entries will be posted on the actual cancellation date and reports will consider cancelled entries as well", + "fieldname": "enable_immutable_ledger", + "fieldtype": "Check", + "label": "Enable Immutable Ledger" } ], "icon": "icon-cog", @@ -461,7 +469,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2024-03-27 13:05:57.568638", + "modified": "2024-05-11 23:19:44.673975", "modified_by": "Administrator", "module": "Accounts", "name": "Accounts Settings", diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py index 07d1a65265b..34f0f24047b 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.py +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.py @@ -39,6 +39,7 @@ class AccountsSettings(Document): determine_address_tax_category_from: DF.Literal["Billing Address", "Shipping Address"] enable_common_party_accounting: DF.Check enable_fuzzy_matching: DF.Check + enable_immutable_ledger: DF.Check enable_party_matching: DF.Check frozen_accounts_modifier: DF.Link | None general_ledger_remarks_length: DF.Int diff --git a/erpnext/accounts/general_ledger.py b/erpnext/accounts/general_ledger.py index 700d777f251..716939011ca 100644 --- a/erpnext/accounts/general_ledger.py +++ b/erpnext/accounts/general_ledger.py @@ -8,6 +8,7 @@ import frappe from frappe import _ from frappe.model.meta import get_field_precision from frappe.utils import cint, flt, formatdate, getdate, now +from frappe.utils.dashboard import cache_source import erpnext from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import ( @@ -574,6 +575,8 @@ def make_reverse_gl_entries( and make reverse gl entries by swapping debit and credit """ + immutable_ledger_enabled = is_immutable_ledger_enabled() + if not gl_entries: gl_entry = frappe.qb.DocType("GL Entry") gl_entries = ( @@ -605,7 +608,6 @@ def make_reverse_gl_entries( for x in gl_entries: query = ( frappe.qb.update(gle) - .set(gle.is_cancelled, True) .set(gle.modified, now()) .set(gle.modified_by, frappe.session.user) .where( @@ -620,9 +622,14 @@ def make_reverse_gl_entries( & (gle.voucher_detail_no == x.voucher_detail_no) ) ) + + if not immutable_ledger_enabled: + query = query.set(gle.is_cancelled, True) + query.run() else: - set_as_cancel(gl_entries[0]["voucher_type"], gl_entries[0]["voucher_no"]) + if not immutable_ledger_enabled: + set_as_cancel(gl_entries[0]["voucher_type"], gl_entries[0]["voucher_no"]) for entry in gl_entries: new_gle = copy.deepcopy(entry) @@ -641,6 +648,10 @@ def make_reverse_gl_entries( new_gle["remarks"] = "On cancellation of " + new_gle["voucher_no"] new_gle["is_cancelled"] = 1 + if immutable_ledger_enabled: + new_gle["is_cancelled"] = 0 + new_gle["posting_date"] = frappe.form_dict.get("posting_date") or getdate() + if new_gle["debit"] or new_gle["credit"]: make_entry(new_gle, adv_adj, "Yes") @@ -733,3 +744,7 @@ def validate_allowed_dimensions(gl_entry, dimension_filter_map): ), InvalidAccountDimensionError, ) + + +def is_immutable_ledger_enabled(): + return frappe.db.get_single_value("Accounts Settings", "enable_immutable_ledger")