mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-26 16:34:46 +00:00
Merge pull request #55165 from frappe/mergify/bp/version-15-hotfix/pr-55130
perf: skip delink_original_entry during cancellation when Immutable Ledger is enabled (backport #55130)
This commit is contained in:
@@ -3,8 +3,9 @@
|
||||
|
||||
import frappe
|
||||
from frappe import qb
|
||||
from frappe.query_builder.functions import Count, Sum
|
||||
from frappe.tests.utils import FrappeTestCase, change_settings
|
||||
from frappe.utils import nowdate
|
||||
from frappe.utils import add_days, nowdate
|
||||
|
||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
|
||||
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
|
||||
@@ -94,6 +95,7 @@ class TestPaymentLedgerEntry(FrappeTestCase):
|
||||
posting_date = nowdate()
|
||||
|
||||
sinv = create_sales_invoice(
|
||||
posting_date=posting_date,
|
||||
qty=qty,
|
||||
rate=rate,
|
||||
company=self.company,
|
||||
@@ -535,3 +537,82 @@ class TestPaymentLedgerEntry(FrappeTestCase):
|
||||
# with references removed, deletion should be possible
|
||||
so.delete()
|
||||
self.assertRaises(frappe.DoesNotExistError, frappe.get_doc, so.doctype, so.name)
|
||||
|
||||
@change_settings(
|
||||
"Accounts Settings",
|
||||
{"enable_immutable_ledger": 1},
|
||||
)
|
||||
def test_reverse_entries_on_cancel_for_immutable_ledger(self):
|
||||
invoice_posting_date = add_days(nowdate(), -5)
|
||||
gle = qb.DocType("GL Entry")
|
||||
ple = qb.DocType("Payment Ledger Entry")
|
||||
|
||||
si = self.create_sales_invoice(qty=1, rate=100, posting_date=invoice_posting_date)
|
||||
|
||||
gles_before = (
|
||||
qb.from_(gle)
|
||||
.select(
|
||||
Count(gle.name),
|
||||
)
|
||||
.where((gle.voucher_type == si.doctype) & (gle.voucher_no == si.name) & (gle.is_cancelled == 0))
|
||||
.run()[0][0]
|
||||
)
|
||||
ples_before = (
|
||||
qb.from_(ple)
|
||||
.select(
|
||||
Count(ple.name),
|
||||
)
|
||||
.where((ple.voucher_type == si.doctype) & (ple.voucher_no == si.name) & (ple.delinked.eq(0)))
|
||||
.run()[0][0]
|
||||
)
|
||||
|
||||
si.cancel()
|
||||
|
||||
gles_after = (
|
||||
qb.from_(gle)
|
||||
.select(Count(gle.account))
|
||||
.where((gle.voucher_type == si.doctype) & (gle.voucher_no == si.name) & (gle.is_cancelled == 0))
|
||||
.run()[0][0]
|
||||
)
|
||||
self.assertEqual(gles_after, gles_before * 2)
|
||||
|
||||
ples_after = (
|
||||
qb.from_(ple)
|
||||
.select(
|
||||
Count(ple.name),
|
||||
)
|
||||
.where((ple.voucher_type == si.doctype) & (ple.voucher_no == si.name) & (ple.delinked.eq(0)))
|
||||
.run()[0][0]
|
||||
)
|
||||
self.assertEqual(ples_after, ples_before * 2)
|
||||
|
||||
# assert debit/credit are reversed
|
||||
gl_entries = (
|
||||
qb.from_(gle)
|
||||
.select(gle.account, Sum(gle.debit).as_("total_debit"), Sum(gle.credit).as_("total_credit"))
|
||||
.where((gle.voucher_type == si.doctype) & (gle.voucher_no == si.name) & (gle.is_cancelled == 0))
|
||||
.groupby(gle.account)
|
||||
.run(as_dict=True)
|
||||
)
|
||||
for gl in gl_entries:
|
||||
with self.subTest(gl=gl):
|
||||
self.assertEqual(gl.total_debit, gl.total_credit)
|
||||
|
||||
# assert amounts are reversed
|
||||
pl_entries = (
|
||||
qb.from_(ple)
|
||||
.select(ple.account, Sum(ple.amount).as_("total_amount"))
|
||||
.where((ple.voucher_type == si.doctype) & (ple.voucher_no == si.name) & (ple.delinked == 0))
|
||||
.groupby(ple.account)
|
||||
.run(as_dict=True)
|
||||
)
|
||||
for pl in pl_entries:
|
||||
with self.subTest(pl=pl):
|
||||
self.assertEqual(pl.total_amount, 0)
|
||||
|
||||
self.assertFalse(
|
||||
frappe.db.exists(
|
||||
"Payment Ledger Entry",
|
||||
{"voucher_type": si.doctype, "voucher_no": si.name, "delinked": 1},
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1934,8 +1934,9 @@ def create_payment_ledger_entry(
|
||||
ple = frappe.get_doc(entry)
|
||||
|
||||
if cancel:
|
||||
delink_original_entry(ple, partial_cancel=partial_cancel)
|
||||
if is_immutable_ledger_enabled():
|
||||
if not is_immutable_ledger_enabled():
|
||||
delink_original_entry(ple, partial_cancel=partial_cancel)
|
||||
else:
|
||||
ple.delinked = 0
|
||||
ple.posting_date = frappe.form_dict.get("posting_date") or getdate()
|
||||
|
||||
@@ -2027,6 +2028,7 @@ def delink_original_entry(pl_entry, partial_cancel=False):
|
||||
qb.update(ple)
|
||||
.set(ple.modified, now())
|
||||
.set(ple.modified_by, frappe.session.user)
|
||||
.set(ple.delinked, True)
|
||||
.where(
|
||||
(ple.company == pl_entry.company)
|
||||
& (ple.account_type == pl_entry.account_type)
|
||||
@@ -2043,9 +2045,6 @@ def delink_original_entry(pl_entry, partial_cancel=False):
|
||||
if partial_cancel:
|
||||
query = query.where(ple.voucher_detail_no == pl_entry.voucher_detail_no)
|
||||
|
||||
if not is_immutable_ledger_enabled():
|
||||
query = query.set(ple.delinked, True)
|
||||
|
||||
query.run()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user