From 6c3618be37882df254eaa5db0ca543d7d507ba51 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 16 Aug 2017 20:54:48 +0530 Subject: [PATCH 1/3] Unallocated and difference amount calculation in Payment Entry --- .../doctype/payment_entry/payment_entry.js | 16 ++--- .../doctype/payment_entry/payment_entry.py | 14 ++--- .../payment_entry/test_payment_entry.py | 62 +++++++++++++++++++ .../tests/test_payment_against_invoice.js | 51 +++++++++++++++ .../payment_entry/tests/test_payment_entry.js | 3 +- erpnext/tests/ui/tests.txt | 3 +- 6 files changed, 124 insertions(+), 25 deletions(-) create mode 100644 erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index 12e46c42d3..dc37574ea6 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -644,16 +644,9 @@ frappe.ui.form.on('Payment Entry', { if(frm.doc.party) { var party_amount = frm.doc.payment_type=="Receive" ? frm.doc.paid_amount : frm.doc.received_amount; - - var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [], - function(d) { return flt(d.amount) })); if(frm.doc.total_allocated_amount < party_amount) { - if(frm.doc.payment_type == "Receive") { - unallocated_amount = party_amount - (frm.doc.total_allocated_amount - total_deductions); - } else { - unallocated_amount = party_amount - (frm.doc.total_allocated_amount + total_deductions); - } + unallocated_amount = party_amount - frm.doc.total_allocated_amount; } } frm.set_value("unallocated_amount", unallocated_amount); @@ -672,11 +665,10 @@ frappe.ui.form.on('Payment Entry', { difference_amount = flt(frm.doc.base_paid_amount) - flt(frm.doc.base_received_amount); } - $.each(frm.doc.deductions || [], function(i, d) { - if(d.amount) difference_amount -= flt(d.amount); - }) + var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [], + function(d) { return flt(d.amount) })); - frm.set_value("difference_amount", difference_amount); + frm.set_value("difference_amount", difference_amount - total_deductions); frm.events.hide_unhide_fields(frm); }, diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index 9832c0527a..e8b383fe74 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -281,13 +281,8 @@ class PaymentEntry(AccountsController): if self.party: party_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount - total_deductions = sum([flt(d.amount) for d in self.get("deductions")]) - if self.total_allocated_amount < party_amount: - if self.payment_type == "Receive": - self.unallocated_amount = party_amount - (self.total_allocated_amount - total_deductions) - else: - self.unallocated_amount = party_amount - (self.total_allocated_amount + total_deductions) + self.unallocated_amount = party_amount - self.total_allocated_amount def set_difference_amount(self): base_unallocated_amount = flt(self.unallocated_amount) * (flt(self.source_exchange_rate) @@ -302,11 +297,10 @@ class PaymentEntry(AccountsController): else: self.difference_amount = self.base_paid_amount - flt(self.base_received_amount) - for d in self.get("deductions"): - if d.amount: - self.difference_amount -= flt(d.amount) + total_deductions = sum([flt(d.amount) for d in self.get("deductions")]) - self.difference_amount = flt(self.difference_amount, self.precision("difference_amount")) + self.difference_amount = flt(self.difference_amount - total_deductions, + self.precision("difference_amount")) def clear_unallocated_reference_document_rows(self): self.set("references", self.get("references", {"allocated_amount": ["not in", [0, None, ""]]})) diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py index 0316ccafe2..1ea767ef3e 100644 --- a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py @@ -267,3 +267,65 @@ class TestPaymentEntry(unittest.TestCase): return frappe.db.sql("""select account, debit, credit, against_voucher from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s order by account asc""", voucher_no, as_dict=1) + + def test_payment_entry_write_off_difference(self): + si = create_sales_invoice() + pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC") + pe.reference_no = "1" + pe.reference_date = "2016-01-01" + pe.received_amount = pe.paid_amount = 110 + pe.insert() + + self.assertEqual(pe.unallocated_amount, 10) + + pe.received_amount = pe.paid_amount = 95 + pe.append("deductions", { + "account": "_Test Write Off - _TC", + "cost_center": "_Test Cost Center - _TC", + "amount": 5 + }) + pe.save() + + self.assertEqual(pe.unallocated_amount, 0) + self.assertEqual(pe.difference_amount, 0) + + pe.submit() + + expected_gle = dict((d[0], d) for d in [ + ["Debtors - _TC", 0, 100, si.name], + ["_Test Cash - _TC", 95, 0, None], + ["_Test Write Off - _TC", 5, 0, None] + ]) + + self.validate_gl_entries(pe.name, expected_gle) + + def test_payment_entry_exchange_gain_loss(self): + si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC", + currency="USD", conversion_rate=50) + pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC") + pe.reference_no = "1" + pe.reference_date = "2016-01-01" + pe.target_exchange_rate = 55 + + pe.append("deductions", { + "account": "_Test Exchange Gain/Loss - _TC", + "cost_center": "_Test Cost Center - _TC", + "amount": -500 + }) + pe.save() + + self.assertEqual(pe.unallocated_amount, 0) + self.assertEqual(pe.difference_amount, 0) + + pe.submit() + + expected_gle = dict((d[0], d) for d in [ + ["_Test Receivable USD - _TC", 0, 5000, si.name], + ["_Test Bank USD - _TC", 5500, 0, None], + ["_Test Exchange Gain/Loss - _TC", 0, 500, None], + ]) + + self.validate_gl_entries(pe.name, expected_gle) + + outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount")) + self.assertEqual(outstanding_amount, 0) diff --git a/erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js b/erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js new file mode 100644 index 0000000000..ac203715a7 --- /dev/null +++ b/erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js @@ -0,0 +1,51 @@ +QUnit.module('Payment Entry'); + +QUnit.test("test payment entry", function(assert) { + assert.expect(6); + let done = assert.async(); + frappe.run_serially([ + () => { + return frappe.tests.make('Sales Invoice', [ + {customer: 'Test Customer 1'}, + {items: [ + [ + {'qty': 1}, + {'rate': 101}, + {'item_code': 'Test Product 1'}, + ] + ]} + ]); + }, + () => cur_frm.save(), + () => frappe.tests.click_button('Submit'), + () => frappe.tests.click_button('Yes'), + () => frappe.timeout(0.5), + () => frappe.tests.click_button('Close'), + () => frappe.timeout(0.5), + () => frappe.click_button('Make'), + () => frappe.click_link('Payment', 1), + () => frappe.timeout(2), + () => { + assert.equal(frappe.get_route()[1], 'Payment Entry', + 'made payment entry'); + assert.equal(cur_frm.doc.party, 'Test Customer 1', + 'customer set in payment entry'); + assert.equal(cur_frm.doc.paid_amount, 101, + 'paid amount set in payment entry'); + assert.equal(cur_frm.doc.references[0].allocated_amount, 101, + 'amount allocated against sales invoice'); + }, + () => cur_frm.set_value('paid_amount', 100), + () => { + cur_frm.doc.references[0].allocated_amount = 101 + }, + () => frappe.click_button('Write Off Difference Amount'), + () => { + assert.equal(cur_frm.doc.difference_amount, 0, + 'difference amount is zero'); + assert.equal(cur_frm.doc.deductions[0].amount, 1, + 'Write off amount = 1'); + }, + () => done() + ]); +}); \ No newline at end of file diff --git a/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry.js b/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry.js index a4ef0ca4eb..0c76343fa9 100644 --- a/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry.js @@ -25,5 +25,4 @@ QUnit.test("test payment entry", function(assert) { () => frappe.timeout(0.3), () => done() ]); -}); - +}); \ No newline at end of file diff --git a/erpnext/tests/ui/tests.txt b/erpnext/tests/ui/tests.txt index 313554bd9c..6017f6f67b 100644 --- a/erpnext/tests/ui/tests.txt +++ b/erpnext/tests/ui/tests.txt @@ -125,4 +125,5 @@ erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_transfer_f erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_subcontract.js erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_issue_with_serialize_item.js erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_repack.js -erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_serialize_item.js \ No newline at end of file +erpnext/accounts/doctype/sales_invoice/tests/test_sales_invoice_with_serialize_item.js +erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js From ded8d117286d8c4a7756805833ecc2a94dbec93a Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 17 Aug 2017 14:05:57 +0530 Subject: [PATCH 2/3] Js tests added for write off difference amount --- .../doctype/payment_entry/payment_entry.py | 2 +- .../payment_entry/test_payment_entry.py | 4 +- .../tests/test_payment_entry_write_off.js | 67 +++++++++++++++++++ erpnext/tests/ui/make_fixtures.js | 12 ++++ 4 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 erpnext/accounts/doctype/payment_entry/tests/test_payment_entry_write_off.js diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index e8b383fe74..908e58eeac 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -299,7 +299,7 @@ class PaymentEntry(AccountsController): total_deductions = sum([flt(d.amount) for d in self.get("deductions")]) - self.difference_amount = flt(self.difference_amount - total_deductions, + self.difference_amount = flt(self.difference_amount - total_deductions, self.precision("difference_amount")) def clear_unallocated_reference_document_rows(self): diff --git a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py index 1ea767ef3e..60be20dd89 100644 --- a/erpnext/accounts/doctype/payment_entry/test_payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/test_payment_entry.py @@ -288,7 +288,7 @@ class TestPaymentEntry(unittest.TestCase): self.assertEqual(pe.unallocated_amount, 0) self.assertEqual(pe.difference_amount, 0) - + pe.submit() expected_gle = dict((d[0], d) for d in [ @@ -316,7 +316,7 @@ class TestPaymentEntry(unittest.TestCase): self.assertEqual(pe.unallocated_amount, 0) self.assertEqual(pe.difference_amount, 0) - + pe.submit() expected_gle = dict((d[0], d) for d in [ diff --git a/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry_write_off.js b/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry_write_off.js new file mode 100644 index 0000000000..133f136298 --- /dev/null +++ b/erpnext/accounts/doctype/payment_entry/tests/test_payment_entry_write_off.js @@ -0,0 +1,67 @@ +QUnit.module('Payment Entry'); + +QUnit.test("test payment entry", function(assert) { + assert.expect(8); + let done = assert.async(); + frappe.run_serially([ + () => { + return frappe.tests.make('Sales Invoice', [ + {customer: 'Test Customer 1'}, + {company: '_Test Company'}, + {currency: 'INR'}, + {selling_price_list: '_Test Price List'}, + {items: [ + [ + {'qty': 1}, + {'item_code': 'Test Product 1'}, + ] + ]} + ]); + }, + () => frappe.timeout(1), + () => cur_frm.save(), + () => frappe.tests.click_button('Submit'), + () => frappe.tests.click_button('Yes'), + () => frappe.timeout(1.5), + () => frappe.click_button('Close'), + () => frappe.timeout(0.5), + () => frappe.click_button('Make'), + () => frappe.timeout(1), + () => frappe.click_link('Payment'), + () => frappe.timeout(2), + () => cur_frm.set_value("paid_to", "_Test Cash - _TC"), + () => frappe.timeout(0.5), + () => { + assert.equal(frappe.get_route()[1], 'Payment Entry', 'made payment entry'); + assert.equal(cur_frm.doc.party, 'Test Customer 1', 'customer set in payment entry'); + assert.equal(cur_frm.doc.paid_from, 'Debtors - _TC', 'customer account set in payment entry'); + assert.equal(cur_frm.doc.paid_amount, 100, 'paid amount set in payment entry'); + assert.equal(cur_frm.doc.references[0].allocated_amount, 100, + 'amount allocated against sales invoice'); + }, + () => cur_frm.set_value('paid_amount', 95), + () => frappe.timeout(1), + () => { + frappe.model.set_value("Payment Entry Reference", + cur_frm.doc.references[0].name, "allocated_amount", 100); + }, + () => frappe.timeout(.5), + () => { + assert.equal(cur_frm.doc.difference_amount, 5, 'difference amount is 5'); + }, + () => { + frappe.db.set_value("Company", "_Test Company", "write_off_account", "_Test Write Off - _TC"); + frappe.timeout(1); + frappe.db.set_value("Company", "_Test Company", + "exchange_gain_loss_account", "_Test Exchange Gain/Loss - _TC"); + }, + () => frappe.timeout(1), + () => frappe.click_button('Write Off Difference Amount'), + () => frappe.timeout(2), + () => { + assert.equal(cur_frm.doc.difference_amount, 0, 'difference amount is zero'); + assert.equal(cur_frm.doc.deductions[0].amount, 5, 'Write off amount = 5'); + }, + () => done() + ]); +}); \ No newline at end of file diff --git a/erpnext/tests/ui/make_fixtures.js b/erpnext/tests/ui/make_fixtures.js index 0c5b4beebe..f817c6549a 100644 --- a/erpnext/tests/ui/make_fixtures.js +++ b/erpnext/tests/ui/make_fixtures.js @@ -205,6 +205,18 @@ $.extend(frappe.test_data, { {title: "Test Term 2"} ] }, + "Item Price": { + "ITEM-PRICE-00001": [ + {item_code: 'Test Product 1'}, + {price_list: '_Test Price List'}, + {price_list_rate: 100} + ], + "ITEM-PRICE-00002": [ + {item_code: 'Test Product 2'}, + {price_list: '_Test Price List'}, + {price_list_rate: 200} + ] + } }); From 914fd197fc1cb53e31456e260d93ccd926d2619b Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Wed, 6 Sep 2017 12:42:58 +0530 Subject: [PATCH 3/3] Update test_payment_against_invoice.js --- .../payment_entry/tests/test_payment_against_invoice.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js b/erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js index ac203715a7..7dea76db80 100644 --- a/erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js +++ b/erpnext/accounts/doctype/payment_entry/tests/test_payment_against_invoice.js @@ -37,7 +37,7 @@ QUnit.test("test payment entry", function(assert) { }, () => cur_frm.set_value('paid_amount', 100), () => { - cur_frm.doc.references[0].allocated_amount = 101 + cur_frm.doc.references[0].allocated_amount = 101; }, () => frappe.click_button('Write Off Difference Amount'), () => { @@ -48,4 +48,4 @@ QUnit.test("test payment entry", function(assert) { }, () => done() ]); -}); \ No newline at end of file +});