From bec1f972b36c33b76317fd286370834f71504797 Mon Sep 17 00:00:00 2001 From: rs-rethik Date: Fri, 20 Dec 2024 12:07:20 +0530 Subject: [PATCH 1/7] feat: add difference_posting_date field (cherry picked from commit 225e56cbcae5c30172b52aa2e6cbc04a5ec01d43) # Conflicts: # erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json # erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json --- .../purchase_invoice_advance.json | 18 +++++++++++++++--- .../purchase_invoice_advance.py | 1 + .../sales_invoice_advance.json | 18 +++++++++++++++--- .../sales_invoice_advance.py | 1 + 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json b/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json index 4db531eac90..5cb780b3e6f 100644 --- a/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json +++ b/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json @@ -14,7 +14,8 @@ "advance_amount", "allocated_amount", "exchange_gain_loss", - "ref_exchange_rate" + "ref_exchange_rate", + "difference_posting_date" ], "fields": [ { @@ -30,7 +31,7 @@ "width": "180px" }, { - "columns": 3, + "columns": 2, "fieldname": "reference_name", "fieldtype": "Dynamic Link", "in_list_view": 1, @@ -40,7 +41,7 @@ "read_only": 1 }, { - "columns": 3, + "columns": 2, "fieldname": "remarks", "fieldtype": "Text", "in_list_view": 1, @@ -111,13 +112,24 @@ "label": "Reference Exchange Rate", "non_negative": 1, "read_only": 1 + }, + { + "columns": 2, + "fieldname": "difference_posting_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "Difference Posting Date" } ], "idx": 1, "index_web_pages_for_search": 1, "istable": 1, "links": [], +<<<<<<< HEAD "modified": "2023-06-23 21:13:18.013816", +======= + "modified": "2024-12-20 12:04:46.729972", +>>>>>>> 225e56cbca (feat: add difference_posting_date field) "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice Advance", diff --git a/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.py b/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.py index bbd3009224a..a3fabbdc322 100644 --- a/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.py +++ b/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.py @@ -16,6 +16,7 @@ class PurchaseInvoiceAdvance(Document): advance_amount: DF.Currency allocated_amount: DF.Currency + difference_posting_date: DF.Date | None exchange_gain_loss: DF.Currency parent: DF.Data parentfield: DF.Data diff --git a/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json b/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json index 0ae85d90004..151d493ed09 100644 --- a/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json +++ b/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json @@ -14,7 +14,8 @@ "advance_amount", "allocated_amount", "exchange_gain_loss", - "ref_exchange_rate" + "ref_exchange_rate", + "difference_posting_date" ], "fields": [ { @@ -30,7 +31,7 @@ "width": "250px" }, { - "columns": 3, + "columns": 2, "fieldname": "reference_name", "fieldtype": "Dynamic Link", "in_list_view": 1, @@ -41,7 +42,7 @@ "read_only": 1 }, { - "columns": 3, + "columns": 2, "fieldname": "remarks", "fieldtype": "Text", "in_list_view": 1, @@ -112,13 +113,24 @@ "label": "Reference Exchange Rate", "non_negative": 1, "read_only": 1 + }, + { + "columns": 2, + "fieldname": "difference_posting_date", + "fieldtype": "Date", + "in_list_view": 1, + "label": "Difference Posting Date" } ], "idx": 1, "index_web_pages_for_search": 1, "istable": 1, "links": [], +<<<<<<< HEAD "modified": "2023-06-23 21:12:57.557731", +======= + "modified": "2024-12-20 11:58:28.962370", +>>>>>>> 225e56cbca (feat: add difference_posting_date field) "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice Advance", diff --git a/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.py b/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.py index 5eeedb25f29..1d115c5c507 100644 --- a/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.py +++ b/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.py @@ -16,6 +16,7 @@ class SalesInvoiceAdvance(Document): advance_amount: DF.Currency allocated_amount: DF.Currency + difference_posting_date: DF.Date | None exchange_gain_loss: DF.Currency parent: DF.Data parentfield: DF.Data From 7498cdf644960525f09b07cc829a09f704a22b4b Mon Sep 17 00:00:00 2001 From: rs-rethik Date: Fri, 20 Dec 2024 12:10:08 +0530 Subject: [PATCH 2/7] feat: use difference_posting_date for journal entry posting_date (cherry picked from commit ff1d040a6e1aa80c3b93835395db31a222dd5568) --- erpnext/controllers/accounts_controller.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 6932a4b47d9..b15788d8fcc 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -1204,6 +1204,7 @@ class AccountsController(TransactionBase): "advance_amount": flt(d.amount), "allocated_amount": allocated_amount, "ref_exchange_rate": flt(d.exchange_rate), # exchange_rate of advance entry + "difference_posting_date": self.posting_date, } if d.get("paid_from"): advance_row["account"] = d.paid_from @@ -1509,7 +1510,6 @@ class AccountsController(TransactionBase): gain_loss_account = frappe.get_cached_value( "Company", self.company, "exchange_gain_loss_account" ) - je = create_gain_loss_journal( self.company, args.get("difference_posting_date") if args else self.posting_date, @@ -1595,6 +1595,7 @@ class AccountsController(TransactionBase): "Company", self.company, "exchange_gain_loss_account" ), "exchange_gain_loss": flt(d.get("exchange_gain_loss")), + "difference_posting_date": d.get("difference_posting_date"), } ) lst.append(args) From 4884849f23c8a27661a540c0cb2c7c26d588aa08 Mon Sep 17 00:00:00 2001 From: rs-rethik Date: Fri, 20 Dec 2024 12:13:35 +0530 Subject: [PATCH 3/7] test: add unit test to validate journal entry posting date (cherry picked from commit c14a2d73bf10fd910e319bc62c2d8e117cce73f1) --- .../tests/test_accounts_controller.py | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/erpnext/controllers/tests/test_accounts_controller.py b/erpnext/controllers/tests/test_accounts_controller.py index 289a955f980..069eae55315 100644 --- a/erpnext/controllers/tests/test_accounts_controller.py +++ b/erpnext/controllers/tests/test_accounts_controller.py @@ -2,6 +2,8 @@ # For license information, please see license.txt +from datetime import datetime + import frappe from frappe import qb from frappe.query_builder.functions import Sum @@ -1979,3 +1981,94 @@ class TestAccountsController(FrappeTestCase): self.assertEqual(len(exc_je_for_adv), 0) self.remove_advance_accounts_from_party_master() + + def test_difference_posting_date_in_pi_and_si(self): + self.setup_advance_accounts_in_party_master() + + # create payment entry for customer + adv = self.create_payment_entry(amount=1, source_exc_rate=83) + adv.save() + self.assertEqual(adv.paid_from, self.advance_received_usd) + adv.submit() + + # create sales invoice with advance received + si = self.create_sales_invoice(qty=1, conversion_rate=80, rate=1, do_not_submit=True) + si.debit_to = self.debtors_usd + si.append( + "advances", + { + "reference_type": "Payment Entry", + "reference_name": "ACC-PAY-2024-00001", + "remarks": "Amount INR 1 received from _Test MC Customer USD\nTransaction reference no Test001 dated 2024-12-19", + "advance_amount": 1.0, + "allocated_amount": 1.0, + "exchange_gain_loss": 3.0, + "ref_exchange_rate": 83.0, + "difference_posting_date": add_days(nowdate(), -2), + }, + ) + si.save().submit() + + # exc Gain/Loss journal should've been creatad + exc_je_for_si = self.get_journals_for(si.doctype, si.name) + exc_je_for_adv = self.get_journals_for(adv.doctype, adv.name) + self.assertEqual(len(exc_je_for_si), 1) + self.assertEqual(len(exc_je_for_adv), 1) + self.assertEqual(exc_je_for_si, exc_je_for_adv) + + # check jv created with difference_posting_date in sales invoice + jv = frappe.get_doc("Journal Entry", exc_je_for_si[0].parent) + sales_invoice = frappe.get_doc("Sales Invoice", si.name) + self.assertEqual(sales_invoice.advances[0].difference_posting_date, jv.posting_date) + + # create payment entry for supplier + usd_amount = 1 + inr_amount = 85 + exc_rate = 85 + adv = create_payment_entry( + company=self.company, + payment_type="Pay", + party_type="Supplier", + party=self.supplier, + paid_from=self.cash, + paid_to=self.advance_paid_usd, + paid_amount=inr_amount, + ) + adv.source_exchange_rate = 1 + adv.target_exchange_rate = exc_rate + adv.received_amount = usd_amount + adv.paid_amount = exc_rate * usd_amount + adv.posting_date = nowdate() + adv.save() + self.assertEqual(adv.paid_to, self.advance_paid_usd) + adv.submit() + + # create purchase invoice with advance paid + pi = self.create_purchase_invoice(qty=1, conversion_rate=80, rate=1, do_not_submit=True) + pi.append( + "advances", + { + "reference_type": "Payment Entry", + "reference_name": "ACC-PAY-2024-00002", + "remarks": "Amount INR 1 paid to _Test MC Supplier USD\nTransaction reference no Test001 dated 2024-12-20", + "advance_amount": 1.0, + "allocated_amount": 1.0, + "exchange_gain_loss": 5.0, + "ref_exchange_rate": 85.0, + "difference_posting_date": add_days(nowdate(), -2), + }, + ) + pi.save().submit() + self.assertEqual(pi.credit_to, self.creditors_usd) + + # exc Gain/Loss journal should've been creatad + exc_je_for_pi = self.get_journals_for(pi.doctype, pi.name) + exc_je_for_adv = self.get_journals_for(adv.doctype, adv.name) + self.assertEqual(len(exc_je_for_pi), 1) + self.assertEqual(len(exc_je_for_adv), 1) + self.assertEqual(exc_je_for_pi, exc_je_for_adv) + + # check jv created with difference_posting_date in purchase invoice + journal_voucher = frappe.get_doc("Journal Entry", exc_je_for_pi[0].parent) + purchase_invoice = frappe.get_doc("Purchase Invoice", pi.name) + self.assertEqual(purchase_invoice.advances[0].difference_posting_date, journal_voucher.posting_date) From 13123a04121258e27b6692a03c6004cd244c7b35 Mon Sep 17 00:00:00 2001 From: rs-rethik Date: Fri, 20 Dec 2024 12:42:47 +0530 Subject: [PATCH 4/7] refactor: convert sql query to query builder (cherry picked from commit 2d58e845e633943bae2d481f66d200b16ab91bdf) --- erpnext/controllers/accounts_controller.py | 34 +++++++++++----------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index b15788d8fcc..e5b5887e3ed 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -379,13 +379,14 @@ class AccountsController(TransactionBase): == 1 ) ).run() - frappe.db.sql( - "delete from `tabGL Entry` where voucher_type=%s and voucher_no=%s", (self.doctype, self.name) - ) - frappe.db.sql( - "delete from `tabStock Ledger Entry` where voucher_type=%s and voucher_no=%s", - (self.doctype, self.name), - ) + gle = frappe.qb.DocType("GL Entry") + frappe.qb.from_(gle).delete().where( + (gle.voucher_type == self.doctype) & (gle.voucher_no == self.name) + ).run() + sle = frappe.qb.DocType("Stock Ledger Entry") + frappe.qb.from_(gle).delete().where( + (sle.voucher_type == self.doctype) & (sle.voucher_no == self.name) + ).run() def remove_serial_and_batch_bundle(self): bundles = frappe.get_all( @@ -1150,11 +1151,12 @@ class AccountsController(TransactionBase): def clear_unallocated_advances(self, childtype, parentfield): self.set(parentfield, self.get(parentfield, {"allocated_amount": ["not in", [0, None, ""]]})) - frappe.db.sql( - """delete from `tab{}` where parentfield={} and parent = {} - and allocated_amount = 0""".format(childtype, "%s", "%s"), - (parentfield, self.name), - ) + doctype = frappe.qb.DocType(childtype) + frappe.qb.from_(doctype).delete().where( + (doctype.parentfield == parentfield) + & (doctype.parent == self.name) + & (doctype.allocated_amount == 0) + ).run() @frappe.whitelist() def apply_shipping_rule(self): @@ -2129,11 +2131,9 @@ class AccountsController(TransactionBase): for adv in self.advances: consider_for_total_advance = True if adv.reference_name == linked_doc_name: - frappe.db.sql( - f"""delete from `tab{self.doctype} Advance` - where name = %s""", - adv.name, - ) + doctype = frappe.qb.DocType(self.doctype + " Advance") + frappe.qb.from_(doctype).delete().where(doctype.name == adv.name).run() + consider_for_total_advance = False if consider_for_total_advance: From 3ab4acfafaa79295b6c56d9c6a03ccfe78f2e9c0 Mon Sep 17 00:00:00 2001 From: rs-rethik Date: Fri, 20 Dec 2024 14:00:54 +0530 Subject: [PATCH 5/7] fix: update query (cherry picked from commit 854e37c05c454ad2d93ec0f4a70600f2ca7d5eec) --- erpnext/controllers/accounts_controller.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index e5b5887e3ed..20b5885bfdc 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -384,7 +384,7 @@ class AccountsController(TransactionBase): (gle.voucher_type == self.doctype) & (gle.voucher_no == self.name) ).run() sle = frappe.qb.DocType("Stock Ledger Entry") - frappe.qb.from_(gle).delete().where( + frappe.qb.from_(sle).delete().where( (sle.voucher_type == self.doctype) & (sle.voucher_no == self.name) ).run() From cf4068d1a384a6c43c5d9e08e1cfdce7a9519cdd Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 23 Dec 2024 14:10:44 +0530 Subject: [PATCH 6/7] chore: resolve conflicts --- .../purchase_invoice_advance/purchase_invoice_advance.json | 4 ---- .../doctype/sales_invoice_advance/sales_invoice_advance.json | 4 ---- 2 files changed, 8 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json b/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json index 5cb780b3e6f..4d0579ebc7e 100644 --- a/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json +++ b/erpnext/accounts/doctype/purchase_invoice_advance/purchase_invoice_advance.json @@ -125,11 +125,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], -<<<<<<< HEAD - "modified": "2023-06-23 21:13:18.013816", -======= "modified": "2024-12-20 12:04:46.729972", ->>>>>>> 225e56cbca (feat: add difference_posting_date field) "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice Advance", diff --git a/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json b/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json index 151d493ed09..1246d04d3d6 100644 --- a/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json +++ b/erpnext/accounts/doctype/sales_invoice_advance/sales_invoice_advance.json @@ -126,11 +126,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], -<<<<<<< HEAD - "modified": "2023-06-23 21:12:57.557731", -======= "modified": "2024-12-20 11:58:28.962370", ->>>>>>> 225e56cbca (feat: add difference_posting_date field) "modified_by": "Administrator", "module": "Accounts", "name": "Sales Invoice Advance", From 33fc987d95283f76dea8dc77e4fa7856a1b4f485 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 23 Dec 2024 14:49:42 +0530 Subject: [PATCH 7/7] refactor(test): remove hardcoded names --- erpnext/controllers/tests/test_accounts_controller.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/erpnext/controllers/tests/test_accounts_controller.py b/erpnext/controllers/tests/test_accounts_controller.py index 069eae55315..e557a6b2d79 100644 --- a/erpnext/controllers/tests/test_accounts_controller.py +++ b/erpnext/controllers/tests/test_accounts_controller.py @@ -1990,6 +1990,7 @@ class TestAccountsController(FrappeTestCase): adv.save() self.assertEqual(adv.paid_from, self.advance_received_usd) adv.submit() + adv.reload() # create sales invoice with advance received si = self.create_sales_invoice(qty=1, conversion_rate=80, rate=1, do_not_submit=True) @@ -1997,8 +1998,8 @@ class TestAccountsController(FrappeTestCase): si.append( "advances", { - "reference_type": "Payment Entry", - "reference_name": "ACC-PAY-2024-00001", + "reference_type": adv.doctype, + "reference_name": adv.name, "remarks": "Amount INR 1 received from _Test MC Customer USD\nTransaction reference no Test001 dated 2024-12-19", "advance_amount": 1.0, "allocated_amount": 1.0, @@ -2048,8 +2049,8 @@ class TestAccountsController(FrappeTestCase): pi.append( "advances", { - "reference_type": "Payment Entry", - "reference_name": "ACC-PAY-2024-00002", + "reference_type": adv.doctype, + "reference_name": adv.name, "remarks": "Amount INR 1 paid to _Test MC Supplier USD\nTransaction reference no Test001 dated 2024-12-20", "advance_amount": 1.0, "allocated_amount": 1.0,