diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 7bef6bb9ee1..8daa13d6165 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -1226,88 +1226,71 @@ class PaymentEntry(AccountsController): ) dr_or_cr = "credit" if self.payment_type == "Receive" else "debit" - if self.book_advance_payments_in_separate_party_account: + + for d in self.get("references"): + # re-defining dr_or_cr for every reference in order to avoid the last value affecting calculation of reverse + dr_or_cr = "credit" if self.payment_type == "Receive" else "debit" + cost_center = self.cost_center + if d.reference_doctype == "Sales Invoice" and not cost_center: + cost_center = frappe.db.get_value(d.reference_doctype, d.reference_name, "cost_center") + gle = party_gl_dict.copy() - if self.payment_type == "Receive": - amount = self.base_paid_amount - else: - amount = self.base_received_amount + allocated_amount_in_company_currency = self.calculate_base_allocated_amount_for_reference(d) + reverse_dr_or_cr = 0 + + if d.reference_doctype in ["Sales Invoice", "Purchase Invoice"]: + is_return = frappe.db.get_value(d.reference_doctype, d.reference_name, "is_return") + payable_party_types = get_party_types_from_account_type("Payable") + receivable_party_types = get_party_types_from_account_type("Receivable") + if ( + is_return + and self.party_type in receivable_party_types + and (self.payment_type == "Pay") + ): + reverse_dr_or_cr = 1 + elif ( + is_return + and self.party_type in payable_party_types + and (self.payment_type == "Receive") + ): + reverse_dr_or_cr = 1 + + if is_return and not reverse_dr_or_cr: + dr_or_cr = "debit" if dr_or_cr == "credit" else "credit" - exchange_rate = self.get_exchange_rate() - amount_in_account_currency = amount * exchange_rate gle.update( { - dr_or_cr: amount, - dr_or_cr + "_in_account_currency": amount_in_account_currency, - "against_voucher_type": "Payment Entry", - "against_voucher": self.name, - "cost_center": self.cost_center, + dr_or_cr: abs(allocated_amount_in_company_currency), + dr_or_cr + "_in_account_currency": abs(d.allocated_amount), + "against_voucher_type": d.reference_doctype, + "against_voucher": d.reference_name, + "cost_center": cost_center, } ) gl_entries.append(gle) - else: - for d in self.get("references"): - # re-defining dr_or_cr for every reference in order to avoid the last value affecting calculation of reverse - dr_or_cr = "credit" if self.payment_type == "Receive" else "debit" - cost_center = self.cost_center - if d.reference_doctype == "Sales Invoice" and not cost_center: - cost_center = frappe.db.get_value( - d.reference_doctype, d.reference_name, "cost_center" - ) - gle = party_gl_dict.copy() + if self.unallocated_amount: + dr_or_cr = "credit" if self.payment_type == "Receive" else "debit" + exchange_rate = self.get_exchange_rate() + base_unallocated_amount = self.unallocated_amount * exchange_rate - allocated_amount_in_company_currency = self.calculate_base_allocated_amount_for_reference( - d - ) - reverse_dr_or_cr = 0 - - if d.reference_doctype in ["Sales Invoice", "Purchase Invoice"]: - is_return = frappe.db.get_value(d.reference_doctype, d.reference_name, "is_return") - payable_party_types = get_party_types_from_account_type("Payable") - receivable_party_types = get_party_types_from_account_type("Receivable") - if ( - is_return - and self.party_type in receivable_party_types - and (self.payment_type == "Pay") - ): - reverse_dr_or_cr = 1 - elif ( - is_return - and self.party_type in payable_party_types - and (self.payment_type == "Receive") - ): - reverse_dr_or_cr = 1 - - if is_return and not reverse_dr_or_cr: - dr_or_cr = "debit" if dr_or_cr == "credit" else "credit" + gle = party_gl_dict.copy() + gle.update( + { + dr_or_cr + "_in_account_currency": self.unallocated_amount, + dr_or_cr: base_unallocated_amount, + } + ) + if self.book_advance_payments_in_separate_party_account: gle.update( { - dr_or_cr: abs(allocated_amount_in_company_currency), - dr_or_cr + "_in_account_currency": abs(d.allocated_amount), - "against_voucher_type": d.reference_doctype, - "against_voucher": d.reference_name, - "cost_center": cost_center, + "against_voucher_type": "Payment Entry", + "against_voucher": self.name, } ) - gl_entries.append(gle) - - if self.unallocated_amount: - dr_or_cr = "credit" if self.payment_type == "Receive" else "debit" - exchange_rate = self.get_exchange_rate() - base_unallocated_amount = self.unallocated_amount * exchange_rate - - gle = party_gl_dict.copy() - gle.update( - { - dr_or_cr + "_in_account_currency": self.unallocated_amount, - dr_or_cr: base_unallocated_amount, - } - ) - - gl_entries.append(gle) + gl_entries.append(gle) def make_advance_gl_entries( self, entry: object | dict = None, cancel: bool = 0, update_outstanding: str = "Yes" @@ -1322,7 +1305,7 @@ class PaymentEntry(AccountsController): def add_advance_gl_entries(self, gl_entries: list, entry: object | dict | None): """ - If 'entry' is passed, GL enties only for that reference is added. + If 'entry' is passed, GL entries only for that reference is added. """ if self.book_advance_payments_in_separate_party_account: references = [x for x in self.get("references")] @@ -1334,8 +1317,6 @@ class PaymentEntry(AccountsController): "Sales Invoice", "Purchase Invoice", "Journal Entry", - "Sales Order", - "Purchase Order", "Payment Entry", ): self.add_advance_gl_for_reference(gl_entries, ref) diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py index 4310604498d..bcf3ccbfe46 100644 --- a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py @@ -1477,6 +1477,68 @@ class TestPaymentEntry(FrappeTestCase): self.check_gl_entries() self.check_pl_entries() + def test_advance_as_liability_against_order(self): + from erpnext.buying.doctype.purchase_order.purchase_order import ( + make_purchase_invoice as _make_purchase_invoice, + ) + from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order + + company = "_Test Company" + + advance_account = create_account( + parent_account="Current Liabilities - _TC", + account_name="Advances Paid", + company=company, + account_type="Liability", + ) + + frappe.db.set_value( + "Company", + company, + { + "book_advance_payments_in_separate_party_account": 1, + "default_advance_paid_account": advance_account, + }, + ) + + po = create_purchase_order(supplier="_Test Supplier") + pe = get_payment_entry("Purchase Order", po.name, bank_account="Cash - _TC") + pe.save().submit() + + pre_reconciliation_gle = [ + {"account": "Cash - _TC", "debit": 0.0, "credit": 5000.0}, + {"account": advance_account, "debit": 5000.0, "credit": 0.0}, + ] + + self.voucher_no = pe.name + self.expected_gle = pre_reconciliation_gle + self.check_gl_entries() + + # Make Purchase Invoice against the order + pi = _make_purchase_invoice(po.name) + pi.append( + "advances", + { + "reference_type": pe.doctype, + "reference_name": pe.name, + "reference_row": pe.references[0].name, + "advance_amount": 5000, + "allocated_amount": 5000, + }, + ) + pi.save().submit() + + # # assert General and Payment Ledger entries post partial reconciliation + self.expected_gle = [ + {"account": pi.credit_to, "debit": 5000.0, "credit": 0.0}, + {"account": "Cash - _TC", "debit": 0.0, "credit": 5000.0}, + {"account": advance_account, "debit": 5000.0, "credit": 0.0}, + {"account": advance_account, "debit": 0.0, "credit": 5000.0}, + ] + + self.voucher_no = pe.name + self.check_gl_entries() + def check_pl_entries(self): ple = frappe.qb.DocType("Payment Ledger Entry") pl_entries = ( diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py index 15b7fa1143a..c7e79fec4c0 100644 --- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py @@ -772,12 +772,7 @@ class TestPurchaseOrder(FrappeTestCase): } ).insert() else: - account = frappe.db.get_value( - "Account", - filters={"account_name": account_name, "company": company}, - fieldname="name", - pluck=True, - ) + account = frappe.get_doc("Account", {"account_name": account_name, "company": company}) return account @@ -808,22 +803,6 @@ class TestPurchaseOrder(FrappeTestCase): from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_invoice - pi = make_purchase_invoice(po_doc.name) - pi.append( - "advances", - { - "reference_type": pe.doctype, - "reference_name": pe.name, - "reference_row": pe.references[0].name, - "advance_amount": 5000, - "allocated_amount": 5000, - }, - ) - pi.save().submit() - pe.reload() - po_doc.reload() - self.assertEqual(po_doc.advance_paid, 0) - company_doc.book_advance_payments_in_separate_party_account = False company_doc.save()