Skip to content

Commit

Permalink
Merge pull request #42795 from frappe/mergify/bp/version-14/pr-42791
Browse files Browse the repository at this point in the history
fix(patch): Use sql to update 'against_voucher' rather than reposting (backport #42791)
  • Loading branch information
ruthra-kumar authored Aug 16, 2024
2 parents 2796aa8 + 3b02f80 commit bd2f408
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 24 deletions.
2 changes: 1 addition & 1 deletion erpnext/patches.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.create_accounting_dimensions_in_reconciliation_tool
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
erpnext.patches.v14_0.migrate_gl_to_payment_ledger
erpnext.stock.doctype.delivery_note.patches.drop_unused_return_against_index # 2023-12-20
Expand Down
112 changes: 89 additions & 23 deletions erpnext/patches/v14_0/update_pos_return_ledger_entries.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,64 @@
import frappe
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")
pos_returns_without_self = (
qb.from_(sinv)
Expand Down Expand Up @@ -32,30 +88,40 @@ def execute():
.run()
)

_vouchers = list(set([x[0] for x in gl_against_references]))
invoice_return_against = (
if gl_against_references:
_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)
.select(sinv.name, sinv.return_against)
.where(sinv.name.isin(_vouchers) & sinv.return_against.notnull())
.orderby(sinv.name)
.run()
.select(sinv.return_against, sinv.debit_to, sinv.customer)
.where(sinv.name.isin(affected_pos_returns))
.run(as_dict=True)
)

valid_references = set(invoice_return_against)
actual_references = set(gl_against_references)
for x in pos_with_accounts:
update_voucher_outstanding("Sales Invoice", x.return_against, x.debit_to, "Customer", x.customer)

invalid_references = actual_references.difference(valid_references)

if invalid_references:
# Repost Accounting Ledger
pos_for_reposting = (
qb.from_(sinv)
.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()
def execute():
affected_pos_returns = get_pos_returns_with_invalid_against_ref()
fix_incorrect_against_voucher_ref(affected_pos_returns)
update_outstanding_for_affected(affected_pos_returns)

0 comments on commit bd2f408

Please sign in to comment.