fix: deferred accounting entries on accounts frozen (#35978)

* fix: accounts frozen entries in deferred accounting

* test: accounts frozen date in deferred accounting

* fix: reset account settings after running test

* fix: resolve conflicts

* fix: modify expected gle when deferred accounting is disabled through JE

* fix: change posting date when accounts not frozen
diff --git a/erpnext/accounts/deferred_revenue.py b/erpnext/accounts/deferred_revenue.py
index 45e04ee..fb49ef3 100644
--- a/erpnext/accounts/deferred_revenue.py
+++ b/erpnext/accounts/deferred_revenue.py
@@ -136,7 +136,7 @@
 		send_mail(deferred_process)
 
 
-def get_booking_dates(doc, item, posting_date=None):
+def get_booking_dates(doc, item, posting_date=None, prev_posting_date=None):
 	if not posting_date:
 		posting_date = add_days(today(), -1)
 
@@ -146,39 +146,42 @@
 		"deferred_revenue_account" if doc.doctype == "Sales Invoice" else "deferred_expense_account"
 	)
 
-	prev_gl_entry = frappe.db.sql(
-		"""
-		select name, posting_date from `tabGL Entry` where company=%s and account=%s and
-		voucher_type=%s and voucher_no=%s and voucher_detail_no=%s
-		and is_cancelled = 0
-		order by posting_date desc limit 1
-	""",
-		(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name),
-		as_dict=True,
-	)
+	if not prev_posting_date:
+		prev_gl_entry = frappe.db.sql(
+			"""
+			select name, posting_date from `tabGL Entry` where company=%s and account=%s and
+			voucher_type=%s and voucher_no=%s and voucher_detail_no=%s
+			and is_cancelled = 0
+			order by posting_date desc limit 1
+		""",
+			(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name),
+			as_dict=True,
+		)
 
-	prev_gl_via_je = frappe.db.sql(
-		"""
-		SELECT p.name, p.posting_date FROM `tabJournal Entry` p, `tabJournal Entry Account` c
-		WHERE p.name = c.parent and p.company=%s and c.account=%s
-		and c.reference_type=%s and c.reference_name=%s
-		and c.reference_detail_no=%s and c.docstatus < 2 order by posting_date desc limit 1
-	""",
-		(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name),
-		as_dict=True,
-	)
+		prev_gl_via_je = frappe.db.sql(
+			"""
+			SELECT p.name, p.posting_date FROM `tabJournal Entry` p, `tabJournal Entry Account` c
+			WHERE p.name = c.parent and p.company=%s and c.account=%s
+			and c.reference_type=%s and c.reference_name=%s
+			and c.reference_detail_no=%s and c.docstatus < 2 order by posting_date desc limit 1
+		""",
+			(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name),
+			as_dict=True,
+		)
 
-	if prev_gl_via_je:
-		if (not prev_gl_entry) or (
-			prev_gl_entry and prev_gl_entry[0].posting_date < prev_gl_via_je[0].posting_date
-		):
-			prev_gl_entry = prev_gl_via_je
+		if prev_gl_via_je:
+			if (not prev_gl_entry) or (
+				prev_gl_entry and prev_gl_entry[0].posting_date < prev_gl_via_je[0].posting_date
+			):
+				prev_gl_entry = prev_gl_via_je
 
-	if prev_gl_entry:
-		start_date = getdate(add_days(prev_gl_entry[0].posting_date, 1))
+		if prev_gl_entry:
+			start_date = getdate(add_days(prev_gl_entry[0].posting_date, 1))
+		else:
+			start_date = item.service_start_date
+
 	else:
-		start_date = item.service_start_date
-
+		start_date = getdate(add_days(prev_posting_date, 1))
 	end_date = get_last_day(start_date)
 	if end_date >= item.service_end_date:
 		end_date = item.service_end_date
@@ -341,9 +344,15 @@
 	accounts_frozen_upto = frappe.get_cached_value("Accounts Settings", "None", "acc_frozen_upto")
 
 	def _book_deferred_revenue_or_expense(
-		item, via_journal_entry, submit_journal_entry, book_deferred_entries_based_on
+		item,
+		via_journal_entry,
+		submit_journal_entry,
+		book_deferred_entries_based_on,
+		prev_posting_date=None,
 	):
-		start_date, end_date, last_gl_entry = get_booking_dates(doc, item, posting_date=posting_date)
+		start_date, end_date, last_gl_entry = get_booking_dates(
+			doc, item, posting_date=posting_date, prev_posting_date=prev_posting_date
+		)
 		if not (start_date and end_date):
 			return
 
@@ -377,9 +386,12 @@
 		if not amount:
 			return
 
+		gl_posting_date = end_date
+		prev_posting_date = None
 		# check if books nor frozen till endate:
 		if accounts_frozen_upto and getdate(end_date) <= getdate(accounts_frozen_upto):
-			end_date = get_last_day(add_days(accounts_frozen_upto, 1))
+			gl_posting_date = get_last_day(add_days(accounts_frozen_upto, 1))
+			prev_posting_date = end_date
 
 		if via_journal_entry:
 			book_revenue_via_journal_entry(
@@ -388,7 +400,7 @@
 				debit_account,
 				amount,
 				base_amount,
-				end_date,
+				gl_posting_date,
 				project,
 				account_currency,
 				item.cost_center,
@@ -404,7 +416,7 @@
 				against,
 				amount,
 				base_amount,
-				end_date,
+				gl_posting_date,
 				project,
 				account_currency,
 				item.cost_center,
@@ -418,7 +430,11 @@
 
 		if getdate(end_date) < getdate(posting_date) and not last_gl_entry:
 			_book_deferred_revenue_or_expense(
-				item, via_journal_entry, submit_journal_entry, book_deferred_entries_based_on
+				item,
+				via_journal_entry,
+				submit_journal_entry,
+				book_deferred_entries_based_on,
+				prev_posting_date,
 			)
 
 	via_journal_entry = cint(
diff --git a/erpnext/accounts/doctype/process_deferred_accounting/test_process_deferred_accounting.py b/erpnext/accounts/doctype/process_deferred_accounting/test_process_deferred_accounting.py
index 83646c9..263621d 100644
--- a/erpnext/accounts/doctype/process_deferred_accounting/test_process_deferred_accounting.py
+++ b/erpnext/accounts/doctype/process_deferred_accounting/test_process_deferred_accounting.py
@@ -16,8 +16,10 @@
 class TestProcessDeferredAccounting(unittest.TestCase):
 	def test_creation_of_ledger_entry_on_submit(self):
 		"""test creation of gl entries on submission of document"""
+		change_acc_settings(acc_frozen_upto="2023-05-31", book_deferred_entries_based_on="Months")
+
 		deferred_account = create_account(
-			account_name="Deferred Revenue",
+			account_name="Deferred Revenue for Accounts Frozen",
 			parent_account="Current Liabilities - _TC",
 			company="_Test Company",
 		)
@@ -29,21 +31,21 @@
 		item.save()
 
 		si = create_sales_invoice(
-			item=item.name, update_stock=0, posting_date="2019-01-10", do_not_submit=True
+			item=item.name, rate=3000, update_stock=0, posting_date="2023-07-01", do_not_submit=True
 		)
 		si.items[0].enable_deferred_revenue = 1
-		si.items[0].service_start_date = "2019-01-10"
-		si.items[0].service_end_date = "2019-03-15"
+		si.items[0].service_start_date = "2023-05-01"
+		si.items[0].service_end_date = "2023-07-31"
 		si.items[0].deferred_revenue_account = deferred_account
 		si.save()
 		si.submit()
 
-		process_deferred_accounting = frappe.get_doc(
+		process_deferred_accounting = doc = frappe.get_doc(
 			dict(
 				doctype="Process Deferred Accounting",
-				posting_date="2019-01-01",
-				start_date="2019-01-01",
-				end_date="2019-01-31",
+				posting_date="2023-07-01",
+				start_date="2023-05-01",
+				end_date="2023-06-30",
 				type="Income",
 			)
 		)
@@ -52,11 +54,16 @@
 		process_deferred_accounting.submit()
 
 		expected_gle = [
-			[deferred_account, 33.85, 0.0, "2019-01-31"],
-			["Sales - _TC", 0.0, 33.85, "2019-01-31"],
+			["Debtors - _TC", 3000, 0.0, "2023-07-01"],
+			[deferred_account, 0.0, 3000, "2023-07-01"],
+			["Sales - _TC", 0.0, 1000, "2023-06-30"],
+			[deferred_account, 1000, 0.0, "2023-06-30"],
+			["Sales - _TC", 0.0, 1000, "2023-06-30"],
+			[deferred_account, 1000, 0.0, "2023-06-30"],
 		]
 
-		check_gl_entries(self, si.name, expected_gle, "2019-01-31")
+		check_gl_entries(self, si.name, expected_gle, "2023-07-01")
+		change_acc_settings()
 
 	def test_pda_submission_and_cancellation(self):
 		pda = frappe.get_doc(
@@ -70,3 +77,10 @@
 		)
 		pda.submit()
 		pda.cancel()
+
+
+def change_acc_settings(acc_frozen_upto="", book_deferred_entries_based_on="Days"):
+	acc_settings = frappe.get_doc("Accounts Settings", "Accounts Settings")
+	acc_settings.acc_frozen_upto = acc_frozen_upto
+	acc_settings.book_deferred_entries_based_on = book_deferred_entries_based_on
+	acc_settings.save()