[validation] over billing against DN/PR
diff --git a/accounts/doctype/purchase_invoice/purchase_invoice.py b/accounts/doctype/purchase_invoice/purchase_invoice.py
index c7135f4..ca13458 100644
--- a/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -75,6 +75,7 @@
self.validate_write_off_account()
self.update_raw_material_cost()
self.update_valuation_rate("entries")
+ self.validate_multiple_billing("Purchase Receipt", "pr_detail", "import_amount")
def get_credit_to(self):
acc_head = sql("""select name, credit_days from `tabAccount`
diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py
index c5c510c..35f9002 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/accounts/doctype/sales_invoice/sales_invoice.py
@@ -93,6 +93,7 @@
self.validate_c_form()
self.validate_time_logs_are_submitted()
self.validate_recurring_invoice()
+ self.validate_multiple_billing("Delivered Note", "dn_detail", "export_amount")
def on_submit(self):
if cint(self.doc.update_stock) == 1:
diff --git a/controllers/accounts_controller.py b/controllers/accounts_controller.py
index 957958c..41b033b 100644
--- a/controllers/accounts_controller.py
+++ b/controllers/accounts_controller.py
@@ -354,6 +354,22 @@
"advance_amount": flt(d.amount),
"allocate_amount": 0
})
+
+ def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on):
+ for item in self.doclist.get({"parentfield": "entries"}):
+ if item.fields.get(item_ref_dn):
+ already_billed = webnotes.conn.sql("""select sum(%s) from `tab%s`
+ where %s=%s and docstatus=1""" % (based_on, self.tname, item_ref_dn, '%s'),
+ item.fields[item_ref_dn])[0][0]
+ if already_billed:
+ max_allowed_amt = webnotes.conn.get_value(ref_dt + " Item",
+ item.fields[item_ref_dn], based_on)
+
+ if flt(already_billed) + flt(item.fields[based_on]) > max_allowed_amt:
+ webnotes.msgprint(_("Row ")+ item.idx + ": " + item.item_code +
+ _(" will be over-billed against mentioned ") + ref_dt +
+ _(". Max allowed " + based_on + ": " + max_allowed_amt),
+ raise_exception=1)
def get_company_default(self, fieldname):
from accounts.utils import get_company_default
diff --git a/stock/doctype/delivery_note/test_delivery_note.py b/stock/doctype/delivery_note/test_delivery_note.py
index a8ff87e..e7e66ed 100644
--- a/stock/doctype/delivery_note/test_delivery_note.py
+++ b/stock/doctype/delivery_note/test_delivery_note.py
@@ -28,6 +28,25 @@
pr.run_method("calculate_taxes_and_totals")
pr.insert()
pr.submit()
+
+ def test_over_billing_against_dn(self):
+ from stock.doctype.delivery_note.delivery_note import make_sales_invoice
+
+ dn = webnotes.bean(copy=test_records[0]).insert()
+
+ self.assertRaises(webnotes.ValidationError, make_sales_invoice,
+ dn.doc.name)
+
+ dn = webnotes.bean("Delivery Note", dn.doc.name)
+ dn.submit()
+ si = make_sales_invoice(dn.doc.name)
+
+ self.assertEquals(len(si), len(dn.doclist))
+
+ # modify export_amount
+ si[1].export_rate = 200
+ self.assertRaises(webnotes.ValidationError, webnotes.bean(si).submit)
+
def test_delivery_note_no_gl_entry(self):
webnotes.conn.sql("""delete from `tabBin`""")
diff --git a/stock/doctype/purchase_receipt/test_purchase_receipt.py b/stock/doctype/purchase_receipt/test_purchase_receipt.py
index e754e69..377f91d 100644
--- a/stock/doctype/purchase_receipt/test_purchase_receipt.py
+++ b/stock/doctype/purchase_receipt/test_purchase_receipt.py
@@ -22,7 +22,7 @@
from webnotes.utils import cint
class TestPurchaseReceipt(unittest.TestCase):
- def test_make_purchase_invocie(self):
+ def test_make_purchase_invoice(self):
from stock.doctype.purchase_receipt.purchase_receipt import make_purchase_invoice
pr = webnotes.bean(copy=test_records[0]).insert()
@@ -37,6 +37,10 @@
self.assertEquals(pi[0]["doctype"], "Purchase Invoice")
self.assertEquals(len(pi), len(pr.doclist))
+ # modify import_rate
+ pi[1].import_rate = 200
+ self.assertRaises(webnotes.ValidationError, webnotes.bean(pi).submit)
+
def test_purchase_receipt_no_gl_entry(self):
pr = webnotes.bean(copy=test_records[0])
pr.run_method("calculate_taxes_and_totals")