Merge pull request #35330 from ruthra-kumar/cr_note_posts_gl_for_itself
refactor: cr/dr note should be standalone even when created from another invoice
diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
index 8f9f7ce..c8bf664 100644
--- a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
+++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py
@@ -702,7 +702,50 @@
pe2.submit()
# create return entry against si1
- create_sales_invoice(is_return=1, return_against=si1.name, qty=-1)
+ cr_note = create_sales_invoice(is_return=1, return_against=si1.name, qty=-1)
+ si1_outstanding = frappe.db.get_value("Sales Invoice", si1.name, "outstanding_amount")
+
+ # create JE(credit note) manually against si1 and cr_note
+ je = frappe.get_doc(
+ {
+ "doctype": "Journal Entry",
+ "company": si1.company,
+ "voucher_type": "Credit Note",
+ "posting_date": nowdate(),
+ }
+ )
+ je.append(
+ "accounts",
+ {
+ "account": si1.debit_to,
+ "party_type": "Customer",
+ "party": si1.customer,
+ "debit": 0,
+ "credit": 100,
+ "debit_in_account_currency": 0,
+ "credit_in_account_currency": 100,
+ "reference_type": si1.doctype,
+ "reference_name": si1.name,
+ "cost_center": si1.items[0].cost_center,
+ },
+ )
+ je.append(
+ "accounts",
+ {
+ "account": cr_note.debit_to,
+ "party_type": "Customer",
+ "party": cr_note.customer,
+ "debit": 100,
+ "credit": 0,
+ "debit_in_account_currency": 100,
+ "credit_in_account_currency": 0,
+ "reference_type": cr_note.doctype,
+ "reference_name": cr_note.name,
+ "cost_center": cr_note.items[0].cost_center,
+ },
+ )
+ je.save().submit()
+
si1_outstanding = frappe.db.get_value("Sales Invoice", si1.name, "outstanding_amount")
self.assertEqual(si1_outstanding, -100)
diff --git a/erpnext/accounts/doctype/payment_ledger_entry/test_payment_ledger_entry.py b/erpnext/accounts/doctype/payment_ledger_entry/test_payment_ledger_entry.py
index fc6dbba..ce9579e 100644
--- a/erpnext/accounts/doctype/payment_ledger_entry/test_payment_ledger_entry.py
+++ b/erpnext/accounts/doctype/payment_ledger_entry/test_payment_ledger_entry.py
@@ -294,7 +294,7 @@
cr_note1.return_against = si3.name
cr_note1 = cr_note1.save().submit()
- pl_entries = (
+ pl_entries_si3 = (
qb.from_(ple)
.select(
ple.voucher_type,
@@ -309,7 +309,24 @@
.run(as_dict=True)
)
- expected_values = [
+ pl_entries_cr_note1 = (
+ qb.from_(ple)
+ .select(
+ ple.voucher_type,
+ ple.voucher_no,
+ ple.against_voucher_type,
+ ple.against_voucher_no,
+ ple.amount,
+ ple.delinked,
+ )
+ .where(
+ (ple.against_voucher_type == cr_note1.doctype) & (ple.against_voucher_no == cr_note1.name)
+ )
+ .orderby(ple.creation)
+ .run(as_dict=True)
+ )
+
+ expected_values_for_si3 = [
{
"voucher_type": si3.doctype,
"voucher_no": si3.name,
@@ -317,18 +334,21 @@
"against_voucher_no": si3.name,
"amount": amount,
"delinked": 0,
- },
+ }
+ ]
+ # credit/debit notes post ledger entries against itself
+ expected_values_for_cr_note1 = [
{
"voucher_type": cr_note1.doctype,
"voucher_no": cr_note1.name,
- "against_voucher_type": si3.doctype,
- "against_voucher_no": si3.name,
+ "against_voucher_type": cr_note1.doctype,
+ "against_voucher_no": cr_note1.name,
"amount": -amount,
"delinked": 0,
},
]
- self.assertEqual(pl_entries[0], expected_values[0])
- self.assertEqual(pl_entries[1], expected_values[1])
+ self.assertEqual(pl_entries_si3, expected_values_for_si3)
+ self.assertEqual(pl_entries_cr_note1, expected_values_for_cr_note1)
def test_je_against_inv_and_note(self):
ple = self.ple
diff --git a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
index 07b46a4..7ef5278 100644
--- a/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
+++ b/erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.py
@@ -186,15 +186,12 @@
self.common_filter_conditions.append(ple.account == self.receivable_payable_account)
self.get_return_invoices()
- return_invoices = [
- x for x in self.return_invoices if x.return_against == None or x.return_against == ""
- ]
outstanding_dr_or_cr = []
- if return_invoices:
+ if self.return_invoices:
ple_query = QueryPaymentLedger()
return_outstanding = ple_query.get_voucher_outstandings(
- vouchers=return_invoices,
+ vouchers=self.return_invoices,
common_filter=self.common_filter_conditions,
posting_date=self.ple_posting_date_filter,
min_outstanding=-(self.minimum_payment_amount) if self.minimum_payment_amount else None,
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index 66438a7..efe9741 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -86,8 +86,7 @@
}
}
- if(doc.docstatus == 1 && doc.outstanding_amount != 0
- && !(doc.is_return && doc.return_against) && !doc.on_hold) {
+ if(doc.docstatus == 1 && doc.outstanding_amount != 0 && !doc.on_hold) {
this.frm.add_custom_button(
__('Payment'),
() => this.make_payment_entry(),
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index f334399..9f1224d 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -628,9 +628,7 @@
"credit_in_account_currency": base_grand_total
if self.party_account_currency == self.company_currency
else grand_total,
- "against_voucher": self.return_against
- if cint(self.is_return) and self.return_against
- else self.name,
+ "against_voucher": self.name,
"against_voucher_type": self.doctype,
"project": self.project,
"cost_center": self.cost_center,
@@ -1644,12 +1642,8 @@
elif outstanding_amount > 0 and getdate(self.due_date) >= getdate():
self.status = "Unpaid"
# Check if outstanding amount is 0 due to debit note issued against invoice
- elif (
- outstanding_amount <= 0
- and self.is_return == 0
- and frappe.db.get_value(
- "Purchase Invoice", {"is_return": 1, "return_against": self.name, "docstatus": 1}
- )
+ elif self.is_return == 0 and frappe.db.get_value(
+ "Purchase Invoice", {"is_return": 1, "return_against": self.name, "docstatus": 1}
):
self.status = "Debit Note Issued"
elif self.is_return == 1:
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index a4bcdb4..642e99c 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -98,8 +98,7 @@
erpnext.accounts.ledger_preview.show_stock_ledger_preview(this.frm);
}
- if (doc.docstatus == 1 && doc.outstanding_amount!=0
- && !(cint(doc.is_return) && doc.return_against)) {
+ if (doc.docstatus == 1 && doc.outstanding_amount!=0) {
this.frm.add_custom_button(
__('Payment'),
() => this.make_payment_entry(),
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 0bc5aa2..fba2fa7 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -1104,9 +1104,7 @@
"debit_in_account_currency": base_grand_total
if self.party_account_currency == self.company_currency
else grand_total,
- "against_voucher": self.return_against
- if cint(self.is_return) and self.return_against
- else self.name,
+ "against_voucher": self.name,
"against_voucher_type": self.doctype,
"cost_center": self.cost_center,
"project": self.project,
@@ -1732,12 +1730,8 @@
elif outstanding_amount > 0 and getdate(self.due_date) >= getdate():
self.status = "Unpaid"
# Check if outstanding amount is 0 due to credit note issued against invoice
- elif (
- outstanding_amount <= 0
- and self.is_return == 0
- and frappe.db.get_value(
- "Sales Invoice", {"is_return": 1, "return_against": self.name, "docstatus": 1}
- )
+ elif self.is_return == 0 and frappe.db.get_value(
+ "Sales Invoice", {"is_return": 1, "return_against": self.name, "docstatus": 1}
):
self.status = "Credit Note Issued"
elif self.is_return == 1:
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index f9cfe5a..21b39d7 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -1500,8 +1500,8 @@
self.assertEqual(party_credited, 1000)
# Check outstanding amount
- self.assertFalse(si1.outstanding_amount)
- self.assertEqual(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"), 1500)
+ self.assertEqual(frappe.db.get_value("Sales Invoice", si1.name, "outstanding_amount"), -1000)
+ self.assertEqual(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"), 2500)
def test_gle_made_when_asset_is_returned(self):
create_asset_data()