From 8055bd39ba1e16cc758fa21372e6b0ab0a8dfb2e Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 19 Oct 2016 17:03:23 +0530 Subject: [PATCH 1/3] [Feature] Provision to allow unlink the payment against the invoice --- .../accounts_settings/accounts_settings.json | 31 +++++++++++++++++-- .../purchase_invoice/purchase_invoice.py | 3 +- .../doctype/sales_invoice/sales_invoice.py | 3 +- .../en/accounts/setup/accounts-settings.md | 4 +++ 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json index c5b3e5b969..359805286b 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -10,6 +10,7 @@ "doctype": "DocType", "document_type": "Other", "editable_grid": 1, + "engine": "InnoDB", "fields": [ { "allow_on_submit": 0, @@ -194,6 +195,32 @@ "search_index": 0, "set_only_once": 0, "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "unlink_payment_on_cancellation_of_invoice", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Unlink Payment on Cancellation of Invoice", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 } ], "hide_heading": 0, @@ -207,8 +234,8 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2016-10-05 16:13:10.978208", - "modified_by": "rohitw1991@gmail.com", + "modified": "2016-10-19 16:37:11.664552", + "modified_by": "Administrator", "module": "Accounts", "name": "Accounts Settings", "owner": "Administrator", diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 042af0bcd3..1c9bcbc577 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -578,7 +578,8 @@ class PurchaseInvoice(BuyingController): if not self.is_return: from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries - unlink_ref_doc_from_payment_entries(self.doctype, self.name) + if frappe.db.get_single_value('Accounts Settings', 'unlink_payment_on_cancellation_of_invoice'): + unlink_ref_doc_from_payment_entries(self.doctype, self.name) self.update_prevdoc_status() self.update_billing_status_for_zero_amount_refdoc("Purchase Order") diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 3c46a165da..521b0eb048 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -136,7 +136,8 @@ class SalesInvoice(SellingController): self.check_close_sales_order("sales_order") from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries - unlink_ref_doc_from_payment_entries(self.doctype, self.name) + if frappe.db.get_single_value('Accounts Settings', 'unlink_payment_on_cancellation_of_invoice'): + unlink_ref_doc_from_payment_entries(self.doctype, self.name) if self.is_return: # NOTE status updating bypassed for is_return diff --git a/erpnext/docs/user/manual/en/accounts/setup/accounts-settings.md b/erpnext/docs/user/manual/en/accounts/setup/accounts-settings.md index 5242b391c6..e920b654e8 100644 --- a/erpnext/docs/user/manual/en/accounts/setup/accounts-settings.md +++ b/erpnext/docs/user/manual/en/accounts/setup/accounts-settings.md @@ -7,4 +7,8 @@ * Credit Controller: Role that is allowed to submit transactions that exceed credit limits set. +* Make Payment via Journal Entry: If checked, on invoice if uer has clicked on payment system open the journal entry else payment entry + +* Unlink Payment on Cancellation of Invoice: If checked system inlink the payment against the invoice else shows the link error. + {next} \ No newline at end of file From 7917ff6936147fafc5c5c20cdb6ef778975c5005 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 20 Oct 2016 15:29:21 +0530 Subject: [PATCH 2/3] Test cases --- .../purchase_invoice/test_purchase_invoice.py | 36 +++++++++++++++++-- .../sales_invoice/test_sales_invoice.py | 31 +++++++++++++++- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 4ea18aceb8..b4b8444e77 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -6,7 +6,7 @@ from __future__ import unicode_literals import unittest import frappe import frappe.model -from frappe.utils import cint, flt, today +from frappe.utils import cint, flt, today, nowdate import frappe.defaults from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \ test_records as pr_test_records @@ -17,6 +17,12 @@ test_dependencies = ["Item", "Cost Center"] test_ignore = ["Serial No"] class TestPurchaseInvoice(unittest.TestCase): + def setUp(self): + unlink_payment_on_cancel_of_invoice() + + def tearDown(self): + unlink_payment_on_cancel_of_invoice(0) + def test_gl_entries_without_auto_accounting_for_stock(self): set_perpetual_inventory(0) self.assertTrue(not cint(frappe.defaults.get_global_default("auto_accounting_for_stock"))) @@ -55,6 +61,27 @@ class TestPurchaseInvoice(unittest.TestCase): set_perpetual_inventory(0) + def test_payment_entry_unlink_against_purchase_invoice(self): + from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry + unlink_payment_on_cancel_of_invoice(0) + + pi_doc = make_purchase_invoice() + + pe = get_payment_entry("Purchase Invoice", pi_doc.name, bank_account="_Test Bank - _TC") + pe.reference_no = "1" + pe.reference_date = nowdate() + pe.paid_from_account_currency = pi_doc.currency + pe.paid_to_account_currency = pi_doc.currency + pe.source_exchange_rate = 1 + pe.target_exchange_rate = 1 + pe.paid_amount = pi_doc.grand_total + pe.save(ignore_permissions=True) + pe.submit() + + pi_doc = frappe.get_doc('Purchase Invoice', pi_doc.name) + + self.assertRaises(frappe.LinkExistsError, pi_doc.cancel) + def test_gl_entries_with_auto_accounting_for_stock_against_pr(self): set_perpetual_inventory(1) self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 1) @@ -411,6 +438,11 @@ class TestPurchaseInvoice(unittest.TestCase): self.assertEquals(frappe.db.get_value("Serial No", pi.get("items")[0].rejected_serial_no, "warehouse"), pi.get("items")[0].rejected_warehouse) +def unlink_payment_on_cancel_of_invoice(enable=1): + accounts_settings = frappe.get_doc("Accounts Settings") + accounts_settings.unlink_payment_on_cancellation_of_invoice = enable + accounts_settings.save() + def make_purchase_invoice(**args): pi = frappe.new_doc("Purchase Invoice") args = frappe._dict(args) @@ -455,4 +487,4 @@ def make_purchase_invoice(**args): pi.submit() return pi -test_records = frappe.get_test_records('Purchase Invoice') +test_records = frappe.get_test_records('Purchase Invoice') \ No newline at end of file diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py index 1bb7b1c2ac..83fc83ca65 100644 --- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -4,8 +4,9 @@ from __future__ import unicode_literals import frappe import unittest, copy -from frappe.utils import nowdate, add_days, flt +from frappe.utils import nowdate, add_days, flt, nowdate from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction +from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import unlink_payment_on_cancel_of_invoice from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency from erpnext.stock.doctype.serial_no.serial_no import SerialNoWarehouseError @@ -19,6 +20,12 @@ class TestSalesInvoice(unittest.TestCase): w.submit() return w + def setUp(self): + unlink_payment_on_cancel_of_invoice() + + def tearDown(self): + unlink_payment_on_cancel_of_invoice(0) + def test_timestamp_change(self): w = frappe.copy_doc(test_records[0]) w.docstatus = 0 @@ -78,6 +85,28 @@ class TestSalesInvoice(unittest.TestCase): self.assertEquals(si.base_grand_total, 1627.05) self.assertEquals(si.grand_total, 1627.05) + def test_payment_entry_unlink_against_invoice(self): + from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry + si = frappe.copy_doc(test_records[0]) + si.is_pos = 0 + si.insert() + si.submit() + + pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC") + pe.reference_no = "1" + pe.reference_date = nowdate() + pe.paid_from_account_currency = si.currency + pe.paid_to_account_currency = si.currency + pe.source_exchange_rate = 1 + pe.target_exchange_rate = 1 + pe.paid_amount = si.grand_total + pe.insert() + pe.submit() + + unlink_payment_on_cancel_of_invoice(0) + si = frappe.get_doc('Sales Invoice', si.name) + self.assertRaises(frappe.LinkExistsError, si.cancel) + def test_sales_invoice_calculation_export_currency(self): si = frappe.copy_doc(test_records[2]) si.currency = "USD" From 18fa0d8691394353d8b953624324830a68583d8d Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Thu, 20 Oct 2016 16:16:28 +0530 Subject: [PATCH 3/3] patch to set default value as 1 --- .../accounts/doctype/accounts_settings/accounts_settings.json | 3 ++- erpnext/patches.txt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json index 359805286b..c389b5c47b 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -201,6 +201,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "default": "1", "fieldname": "unlink_payment_on_cancellation_of_invoice", "fieldtype": "Check", "hidden": 0, @@ -234,7 +235,7 @@ "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2016-10-19 16:37:11.664552", + "modified": "2016-10-20 16:12:38.595075", "modified_by": "Administrator", "module": "Accounts", "name": "Accounts Settings", diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 84312b87db..7d599d7475 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -339,4 +339,5 @@ finally:erpnext.patches.v7_0.update_timesheet_communications erpnext.patches.v7_0.update_status_of_zero_amount_sales_order erpnext.patches.v7_1.add_field_for_task_dependent erpnext.patches.v7_0.repost_bin_qty_and_item_projected_qty -erpnext.patches.v7_1.set_prefered_contact_email \ No newline at end of file +erpnext.patches.v7_1.set_prefered_contact_email +execute:frappe.db.sql("update `tabSingles` set value = 1 where field = 'unlink_payment_on_cancellation_of_invoice' and doctype = 'Accounts Settings'") \ No newline at end of file