Merge pull request #6657 from rohitwaghchaure/invoice_unlink_feature
[Feature] Provision to allow unlink the payment against the invoice
This commit is contained in:
commit
725b547641
@ -10,6 +10,7 @@
|
|||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Other",
|
"document_type": "Other",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@ -194,6 +195,33 @@
|
|||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "1",
|
||||||
|
"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,
|
"hide_heading": 0,
|
||||||
@ -207,8 +235,8 @@
|
|||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2016-10-05 16:13:10.978208",
|
"modified": "2016-10-20 16:12:38.595075",
|
||||||
"modified_by": "rohitw1991@gmail.com",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounts Settings",
|
"name": "Accounts Settings",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
|
@ -578,7 +578,8 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
if not self.is_return:
|
if not self.is_return:
|
||||||
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
|
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_prevdoc_status()
|
||||||
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
|
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
|
||||||
|
@ -6,7 +6,7 @@ from __future__ import unicode_literals
|
|||||||
import unittest
|
import unittest
|
||||||
import frappe
|
import frappe
|
||||||
import frappe.model
|
import frappe.model
|
||||||
from frappe.utils import cint, flt, today
|
from frappe.utils import cint, flt, today, nowdate
|
||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \
|
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory, \
|
||||||
test_records as pr_test_records
|
test_records as pr_test_records
|
||||||
@ -17,6 +17,12 @@ test_dependencies = ["Item", "Cost Center"]
|
|||||||
test_ignore = ["Serial No"]
|
test_ignore = ["Serial No"]
|
||||||
|
|
||||||
class TestPurchaseInvoice(unittest.TestCase):
|
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):
|
def test_gl_entries_without_auto_accounting_for_stock(self):
|
||||||
set_perpetual_inventory(0)
|
set_perpetual_inventory(0)
|
||||||
self.assertTrue(not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")))
|
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)
|
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):
|
def test_gl_entries_with_auto_accounting_for_stock_against_pr(self):
|
||||||
set_perpetual_inventory(1)
|
set_perpetual_inventory(1)
|
||||||
self.assertEqual(cint(frappe.defaults.get_global_default("auto_accounting_for_stock")), 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,
|
self.assertEquals(frappe.db.get_value("Serial No", pi.get("items")[0].rejected_serial_no,
|
||||||
"warehouse"), pi.get("items")[0].rejected_warehouse)
|
"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):
|
def make_purchase_invoice(**args):
|
||||||
pi = frappe.new_doc("Purchase Invoice")
|
pi = frappe.new_doc("Purchase Invoice")
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
|
@ -136,7 +136,8 @@ class SalesInvoice(SellingController):
|
|||||||
self.check_close_sales_order("sales_order")
|
self.check_close_sales_order("sales_order")
|
||||||
|
|
||||||
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
|
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:
|
if self.is_return:
|
||||||
# NOTE status updating bypassed for is_return
|
# NOTE status updating bypassed for is_return
|
||||||
|
@ -4,8 +4,9 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
import unittest, copy
|
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.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.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
||||||
from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency
|
from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency
|
||||||
from erpnext.stock.doctype.serial_no.serial_no import SerialNoWarehouseError
|
from erpnext.stock.doctype.serial_no.serial_no import SerialNoWarehouseError
|
||||||
@ -19,6 +20,12 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
w.submit()
|
w.submit()
|
||||||
return w
|
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):
|
def test_timestamp_change(self):
|
||||||
w = frappe.copy_doc(test_records[0])
|
w = frappe.copy_doc(test_records[0])
|
||||||
w.docstatus = 0
|
w.docstatus = 0
|
||||||
@ -78,6 +85,28 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
self.assertEquals(si.base_grand_total, 1627.05)
|
self.assertEquals(si.base_grand_total, 1627.05)
|
||||||
self.assertEquals(si.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):
|
def test_sales_invoice_calculation_export_currency(self):
|
||||||
si = frappe.copy_doc(test_records[2])
|
si = frappe.copy_doc(test_records[2])
|
||||||
si.currency = "USD"
|
si.currency = "USD"
|
||||||
|
@ -7,4 +7,8 @@
|
|||||||
|
|
||||||
* Credit Controller: Role that is allowed to submit transactions that exceed credit limits set.
|
* 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}
|
{next}
|
@ -340,3 +340,4 @@ erpnext.patches.v7_0.update_status_of_zero_amount_sales_order
|
|||||||
erpnext.patches.v7_1.add_field_for_task_dependent
|
erpnext.patches.v7_1.add_field_for_task_dependent
|
||||||
erpnext.patches.v7_0.repost_bin_qty_and_item_projected_qty
|
erpnext.patches.v7_0.repost_bin_qty_and_item_projected_qty
|
||||||
erpnext.patches.v7_1.set_prefered_contact_email
|
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'")
|
Loading…
x
Reference in New Issue
Block a user