From 2cd9b28e5bbf376a8d57f61486e37f1fe88d068a Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 12 Aug 2024 11:29:39 +0530 Subject: [PATCH 1/5] fix: ledger entries for pos return with update outstanding for self --- erpnext/accounts/doctype/sales_invoice/sales_invoice.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 4482831f60e..cc64fd059b6 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -1485,6 +1485,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( @@ -1498,7 +1502,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, }, From 487d0a55f551a9b92ad662eed9ba94521e97766e Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 12 Aug 2024 13:15:57 +0530 Subject: [PATCH 2/5] fix: patch to fix incorrect against_voucher references in ledger --- .../v15_0/update_pos_return_ledger_entries.py | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 erpnext/patches/v15_0/update_pos_return_ledger_entries.py diff --git a/erpnext/patches/v15_0/update_pos_return_ledger_entries.py b/erpnext/patches/v15_0/update_pos_return_ledger_entries.py new file mode 100644 index 00000000000..60e867d1bcb --- /dev/null +++ b/erpnext/patches/v15_0/update_pos_return_ledger_entries.py @@ -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() From 4dc0d3a003720f6bd1f6d87e5a3540d4a03a2fa9 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 12 Aug 2024 13:58:04 +0530 Subject: [PATCH 3/5] refactor: update patches.txt --- erpnext/patches.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 0268e155957..3d6f19539cb 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -359,6 +359,7 @@ erpnext.patches.v15_0.allow_on_submit_dimensions_for_repostable_doctypes erpnext.patches.v14_0.create_accounting_dimensions_in_reconciliation_tool erpnext.patches.v14_0.update_flag_for_return_invoices #2024-03-22 erpnext.patches.v15_0.create_accounting_dimensions_in_payment_request +erpnext.patches.v15_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 From 3fb08583218fe9890ab2703292a327fea047ee97 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 14 Aug 2024 11:32:26 +0530 Subject: [PATCH 4/5] test: against_voucher for pos_returns without updating for self --- .../sales_invoice/test_sales_invoice.py | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index ca3091fb79a..e94b27b0545 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -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 @@ -3849,6 +3850,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( From da2286802a1216bffe3a7d832340124eb091be4b Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Wed, 14 Aug 2024 11:35:05 +0530 Subject: [PATCH 5/5] refactor: move patch to v14 and update patches.txt --- erpnext/patches.txt | 2 +- .../{v15_0 => v14_0}/update_pos_return_ledger_entries.py | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename erpnext/patches/{v15_0 => v14_0}/update_pos_return_ledger_entries.py (100%) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 3d6f19539cb..c29344c81b0 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -359,7 +359,7 @@ erpnext.patches.v15_0.allow_on_submit_dimensions_for_repostable_doctypes erpnext.patches.v14_0.create_accounting_dimensions_in_reconciliation_tool erpnext.patches.v14_0.update_flag_for_return_invoices #2024-03-22 erpnext.patches.v15_0.create_accounting_dimensions_in_payment_request -erpnext.patches.v15_0.update_pos_return_ledger_entries +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 diff --git a/erpnext/patches/v15_0/update_pos_return_ledger_entries.py b/erpnext/patches/v14_0/update_pos_return_ledger_entries.py similarity index 100% rename from erpnext/patches/v15_0/update_pos_return_ledger_entries.py rename to erpnext/patches/v14_0/update_pos_return_ledger_entries.py