diff --git a/erpnext/controllers/tests/test_item_close_billing.py b/erpnext/controllers/tests/test_item_close_billing.py index c10e10b02fb..517dc697984 100644 --- a/erpnext/controllers/tests/test_item_close_billing.py +++ b/erpnext/controllers/tests/test_item_close_billing.py @@ -2,6 +2,7 @@ # License: GNU General Public License v3. See license.txt import frappe +from frappe.utils import flt from erpnext.controllers.item_close import update_closed_status from erpnext.controllers.sales_and_purchase_return import make_return_doc @@ -201,3 +202,16 @@ class TestDeliveryNoteItemClose(ERPNextTestSuite): self.close_items(return_note, [row]) self.assertTrue(return_note.items[0].closed) + + def test_return_row_pending_amount_is_a_magnitude(self): + """The dialog shows what is outstanding, so a return row must not read as zero.""" + note = self.make_delivery_note() + return_note = make_return_doc("Delivery Note", note.name) + return_note.insert() + return_note.submit() + + row = return_note.items[0] + self.assertLess(row.amount, 0) + pending = abs(flt(row.amount)) - abs(flt(row.billed_amt)) + self.assertEqual(pending, abs(flt(note.items[0].amount))) + self.assertGreater(pending, 0) diff --git a/erpnext/public/js/utils/item_close.js b/erpnext/public/js/utils/item_close.js index f3fbfee25a3..0742f75485c 100644 --- a/erpnext/public/js/utils/item_close.js +++ b/erpnext/public/js/utils/item_close.js @@ -80,7 +80,8 @@ erpnext.item_close = { return { is_closable: (item) => !item.closed && - (flt(item[qty_field]) < flt(item.qty) || flt(item.billed_amt) < flt(item.amount)), + (flt(item[qty_field]) < flt(item.qty) || + Math.abs(flt(item.billed_amt)) < Math.abs(flt(item.amount))), help: help, summarise: (item) => ({ item_code: item.item_code, @@ -88,7 +89,7 @@ erpnext.item_close = { qty: item.qty, fulfilled_qty: item[qty_field] || 0, pending_qty: Math.max(flt(item.qty) - flt(item[qty_field]), 0), - pending_amount: Math.max(flt(item.amount) - flt(item.billed_amt), 0), + pending_amount: Math.max(Math.abs(flt(item.amount)) - Math.abs(flt(item.billed_amt)), 0), }), columns: [ erpnext.item_close.column("item_code", __("Item Code"), "Data", 3), @@ -103,7 +104,8 @@ erpnext.item_close = { billing_config(invoice_label) { return { - is_closable: (item) => !item.closed && flt(item.billed_amt) < flt(item.amount), + is_closable: (item) => + !item.closed && Math.abs(flt(item.billed_amt)) < Math.abs(flt(item.amount)), help: __( "Closed rows stop being expected. Their unbilled amount is written off and they are skipped when creating a {0}.", [invoice_label] @@ -114,7 +116,7 @@ erpnext.item_close = { qty: item.qty, amount: item.amount, billed_amt: item.billed_amt || 0, - pending_amount: Math.max(flt(item.amount) - flt(item.billed_amt), 0), + pending_amount: Math.max(Math.abs(flt(item.amount)) - Math.abs(flt(item.billed_amt)), 0), }), columns: [ erpnext.item_close.column("item_code", __("Item Code"), "Data", 3),