Merge pull request #42761 from frappe/mergify/bp/version-15-hotfix/pr-42720

fix: incorrect 'against_voucher' for Pos return with 'Update Outstanding for Self' disabled. (backport #42720)
This commit is contained in:
ruthra kumar
2024-08-14 12:27:24 +05:30
committed by GitHub
4 changed files with 102 additions and 1 deletions

View File

@@ -1479,6 +1479,10 @@ class SalesInvoice(SellingController):
if skip_change_gl_entries and payment_mode.account == self.account_for_change_amount:
payment_mode.base_amount -= flt(self.change_amount)
against_voucher = self.name
if self.is_return and self.return_against and not self.update_outstanding_for_self:
against_voucher = self.return_against
if payment_mode.base_amount:
# POS, make payment entries
gl_entries.append(
@@ -1492,7 +1496,7 @@ class SalesInvoice(SellingController):
"credit_in_account_currency": payment_mode.base_amount
if self.party_account_currency == self.company_currency
else payment_mode.amount,
"against_voucher": self.name,
"against_voucher": against_voucher,
"against_voucher_type": self.doctype,
"cost_center": self.cost_center,
},

View File

@@ -5,6 +5,7 @@ import copy
import json
import frappe
from frappe import qb
from frappe.model.dynamic_links import get_dynamic_link_map
from frappe.tests.utils import FrappeTestCase, change_settings
from frappe.utils import add_days, flt, getdate, nowdate, today
@@ -3836,6 +3837,40 @@ class TestSalesInvoice(FrappeTestCase):
]
self.assertEqual(expected, actual)
def test_pos_returns_without_update_outstanding_for_self(self):
from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_sales_return
pos_profile = make_pos_profile()
pos_profile.payments = []
pos_profile.append("payments", {"default": 1, "mode_of_payment": "Cash"})
pos_profile.save()
pos = create_sales_invoice(qty=10, do_not_save=True)
pos.is_pos = 1
pos.pos_profile = pos_profile.name
pos.append(
"payments", {"mode_of_payment": "Bank Draft", "account": "_Test Bank - _TC", "amount": 500}
)
pos.append("payments", {"mode_of_payment": "Cash", "account": "Cash - _TC", "amount": 500})
pos.save().submit()
pos_return = make_sales_return(pos.name)
pos_return.update_outstanding_for_self = False
pos_return.save().submit()
gle = qb.DocType("GL Entry")
res = (
qb.from_(gle)
.select(gle.against_voucher)
.distinct()
.where(
gle.is_cancelled.eq(0) & gle.voucher_no.eq(pos_return.name) & gle.against_voucher.notnull()
)
.run(as_list=1)
)
self.assertEqual(len(res), 1)
self.assertEqual(res[0][0], pos_return.return_against)
def set_advance_flag(company, flag, default_account):
frappe.db.set_value(

View File

@@ -357,6 +357,7 @@ erpnext.patches.v14_0.create_accounting_dimensions_in_reconciliation_tool
erpnext.patches.v15_0.allow_on_submit_dimensions_for_repostable_doctypes
erpnext.patches.v14_0.update_flag_for_return_invoices #2024-03-22
erpnext.patches.v15_0.create_accounting_dimensions_in_payment_request
erpnext.patches.v14_0.update_pos_return_ledger_entries
# 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

View File

@@ -0,0 +1,61 @@
import frappe
from frappe import qb
def execute():
sinv = qb.DocType("Sales Invoice")
pos_returns_without_self = (
qb.from_(sinv)
.select(sinv.name)
.where(
sinv.docstatus.eq(1)
& sinv.is_pos.eq(1)
& sinv.is_return.eq(1)
& sinv.return_against.notnull()
& sinv.update_outstanding_for_self.eq(0)
)
.run()
)
if pos_returns_without_self:
pos_returns_without_self = [x[0] for x in pos_returns_without_self]
gle = qb.DocType("GL Entry")
gl_against_references = (
qb.from_(gle)
.select(gle.voucher_no, gle.against_voucher)
.where(
gle.voucher_no.isin(pos_returns_without_self)
& gle.against_voucher.notnull()
& gle.against_voucher.eq(gle.voucher_no)
& gle.is_cancelled.eq(0)
)
.run()
)
_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:
# 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()