Merge pull request #42793 from frappe/mergify/bp/version-14-hotfix/pr-42791
fix(patch): Use sql to update 'against_voucher' rather than reposting (backport #42791)
This commit is contained in:
@@ -357,7 +357,7 @@ erpnext.patches.v14_0.clear_reconciliation_values_from_singles
|
|||||||
erpnext.patches.v14_0.update_total_asset_cost_field
|
erpnext.patches.v14_0.update_total_asset_cost_field
|
||||||
erpnext.patches.v14_0.create_accounting_dimensions_in_reconciliation_tool
|
erpnext.patches.v14_0.create_accounting_dimensions_in_reconciliation_tool
|
||||||
erpnext.patches.v14_0.update_flag_for_return_invoices #2024-03-22
|
erpnext.patches.v14_0.update_flag_for_return_invoices #2024-03-22
|
||||||
erpnext.patches.v14_0.update_pos_return_ledger_entries
|
erpnext.patches.v14_0.update_pos_return_ledger_entries #2024-08-16
|
||||||
# below migration patch should always run last
|
# below migration patch should always run last
|
||||||
erpnext.patches.v14_0.migrate_gl_to_payment_ledger
|
erpnext.patches.v14_0.migrate_gl_to_payment_ledger
|
||||||
erpnext.stock.doctype.delivery_note.patches.drop_unused_return_against_index # 2023-12-20
|
erpnext.stock.doctype.delivery_note.patches.drop_unused_return_against_index # 2023-12-20
|
||||||
|
|||||||
@@ -1,8 +1,64 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import qb
|
from frappe import qb
|
||||||
|
|
||||||
|
from erpnext.accounts.utils import update_voucher_outstanding
|
||||||
|
|
||||||
def execute():
|
|
||||||
|
def get_valid_against_voucher_ref(pos_returns):
|
||||||
|
sinv = qb.DocType("Sales Invoice")
|
||||||
|
res = (
|
||||||
|
qb.from_(sinv)
|
||||||
|
.select(sinv.name, sinv.return_against)
|
||||||
|
.where(sinv.name.isin(pos_returns) & sinv.return_against.notnull())
|
||||||
|
.orderby(sinv.name)
|
||||||
|
.run(as_dict=True)
|
||||||
|
)
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def build_dict_of_valid_against_reference(pos_returns):
|
||||||
|
_against_ref_dict = frappe._dict()
|
||||||
|
res = get_valid_against_voucher_ref(pos_returns)
|
||||||
|
for x in res:
|
||||||
|
_against_ref_dict[x.name] = x.return_against
|
||||||
|
return _against_ref_dict
|
||||||
|
|
||||||
|
|
||||||
|
def fix_incorrect_against_voucher_ref(affected_pos_returns):
|
||||||
|
if affected_pos_returns:
|
||||||
|
valid_against_voucher_dict = build_dict_of_valid_against_reference(affected_pos_returns)
|
||||||
|
|
||||||
|
gle = qb.DocType("GL Entry")
|
||||||
|
gles_with_invalid_against = (
|
||||||
|
qb.from_(gle)
|
||||||
|
.select(gle.name, gle.voucher_no)
|
||||||
|
.where(
|
||||||
|
gle.voucher_no.isin(affected_pos_returns)
|
||||||
|
& gle.against_voucher.notnull()
|
||||||
|
& gle.against_voucher.eq(gle.voucher_no)
|
||||||
|
& gle.is_cancelled.eq(0)
|
||||||
|
)
|
||||||
|
.run(as_dict=True)
|
||||||
|
)
|
||||||
|
# Update GL
|
||||||
|
if gles_with_invalid_against:
|
||||||
|
for gl in gles_with_invalid_against:
|
||||||
|
frappe.db.set_value(
|
||||||
|
"GL Entry",
|
||||||
|
gl.name,
|
||||||
|
"against_voucher",
|
||||||
|
valid_against_voucher_dict[gl.voucher_no],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Update Payment Ledger
|
||||||
|
ple = qb.DocType("Payment Ledger Entry")
|
||||||
|
for x in affected_pos_returns:
|
||||||
|
qb.update(ple).set(ple.against_voucher_no, valid_against_voucher_dict[x]).where(
|
||||||
|
ple.voucher_no.eq(x) & ple.delinked.eq(0)
|
||||||
|
).run()
|
||||||
|
|
||||||
|
|
||||||
|
def get_pos_returns_with_invalid_against_ref():
|
||||||
sinv = qb.DocType("Sales Invoice")
|
sinv = qb.DocType("Sales Invoice")
|
||||||
pos_returns_without_self = (
|
pos_returns_without_self = (
|
||||||
qb.from_(sinv)
|
qb.from_(sinv)
|
||||||
@@ -32,30 +88,40 @@ def execute():
|
|||||||
.run()
|
.run()
|
||||||
)
|
)
|
||||||
|
|
||||||
_vouchers = list(set([x[0] for x in gl_against_references]))
|
if gl_against_references:
|
||||||
invoice_return_against = (
|
_vouchers = list(set([x[0] for x in gl_against_references]))
|
||||||
|
invoice_return_against = (
|
||||||
|
qb.from_(sinv)
|
||||||
|
.select(sinv.name, sinv.return_against)
|
||||||
|
.where(sinv.name.isin(_vouchers) & sinv.return_against.notnull())
|
||||||
|
.orderby(sinv.name)
|
||||||
|
.run()
|
||||||
|
)
|
||||||
|
|
||||||
|
valid_references = set(invoice_return_against)
|
||||||
|
actual_references = set(gl_against_references)
|
||||||
|
|
||||||
|
invalid_references = actual_references.difference(valid_references)
|
||||||
|
if invalid_references:
|
||||||
|
return [x[0] for x in invalid_references]
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def update_outstanding_for_affected(affected_pos_returns):
|
||||||
|
if affected_pos_returns:
|
||||||
|
sinv = qb.DocType("Sales Invoice")
|
||||||
|
pos_with_accounts = (
|
||||||
qb.from_(sinv)
|
qb.from_(sinv)
|
||||||
.select(sinv.name, sinv.return_against)
|
.select(sinv.return_against, sinv.debit_to, sinv.customer)
|
||||||
.where(sinv.name.isin(_vouchers) & sinv.return_against.notnull())
|
.where(sinv.name.isin(affected_pos_returns))
|
||||||
.orderby(sinv.name)
|
.run(as_dict=True)
|
||||||
.run()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
valid_references = set(invoice_return_against)
|
for x in pos_with_accounts:
|
||||||
actual_references = set(gl_against_references)
|
update_voucher_outstanding("Sales Invoice", x.return_against, x.debit_to, "Customer", x.customer)
|
||||||
|
|
||||||
invalid_references = actual_references.difference(valid_references)
|
|
||||||
|
|
||||||
if invalid_references:
|
def execute():
|
||||||
# Repost Accounting Ledger
|
affected_pos_returns = get_pos_returns_with_invalid_against_ref()
|
||||||
pos_for_reposting = (
|
fix_incorrect_against_voucher_ref(affected_pos_returns)
|
||||||
qb.from_(sinv)
|
update_outstanding_for_affected(affected_pos_returns)
|
||||||
.select(sinv.company, sinv.name)
|
|
||||||
.where(sinv.name.isin([x[0] for x in invalid_references]))
|
|
||||||
.run(as_dict=True)
|
|
||||||
)
|
|
||||||
for x in pos_for_reposting:
|
|
||||||
ral = frappe.new_doc("Repost Accounting Ledger")
|
|
||||||
ral.company = x.company
|
|
||||||
ral.append("vouchers", {"voucher_type": "Sales Invoice", "voucher_no": x.name})
|
|
||||||
ral.save().submit()
|
|
||||||
|
|||||||
Reference in New Issue
Block a user