From 28a9e35de9a93d924512d33e4c1c1395ee0fc560 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 8 Jul 2015 13:10:52 +0530 Subject: [PATCH] Validate item rate with reference document with tolerance 0.009 --- .../purchase_invoice/purchase_invoice.py | 19 +++++-------------- .../doctype/sales_invoice/sales_invoice.py | 19 +++++-------------- .../doctype/delivery_note/delivery_note.py | 17 +++++------------ .../purchase_receipt/purchase_receipt.py | 11 ++--------- erpnext/utilities/transaction_base.py | 13 ++++++++++++- 5 files changed, 29 insertions(+), 50 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 50a79ec01b..af144cbf40 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -124,20 +124,11 @@ class PurchaseInvoice(BuyingController): } }) - if cint(frappe.defaults.get_global_default('maintain_same_rate')): - super(PurchaseInvoice, self).validate_with_previous_doc({ - "Purchase Order Item": { - "ref_dn_field": "po_detail", - "compare_fields": [["rate", "="]], - "is_child_table": True, - "allow_duplicate_prev_row_id": True - }, - "Purchase Receipt Item": { - "ref_dn_field": "pr_detail", - "compare_fields": [["rate", "="]], - "is_child_table": True - } - }) + if cint(frappe.db.get_single_value('Buying Settings', 'maintain_same_rate')): + self.validate_rate_with_reference_doc([ + ["Purchase Order", "purchase_order", "po_detail"], + ["Purchase Receipt", "purchase_receipt", "pr_detail"] + ]) def set_against_expense_account(self): auto_accounting_for_stock = cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index 604370b326..75d4e2db32 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -263,20 +263,11 @@ class SalesInvoice(SellingController): }, }) - if cint(frappe.defaults.get_global_default('maintain_same_sales_rate')): - super(SalesInvoice, self).validate_with_previous_doc({ - "Sales Order Item": { - "ref_dn_field": "so_detail", - "compare_fields": [["rate", "="]], - "is_child_table": True, - "allow_duplicate_prev_row_id": True - }, - "Delivery Note Item": { - "ref_dn_field": "dn_detail", - "compare_fields": [["rate", "="]], - "is_child_table": True - } - }) + if cint(frappe.db.get_single_value('Selling Settings', 'maintain_same_sales_rate')): + self.validate_rate_with_reference_doc([ + ["Sales Order", "sales_order", "so_detail"], + ["Delivery Note", "delivery_note", "dn_detail"] + ]) def set_against_income_account(self): """Set against account for debit to account""" diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py index f52f7e51ca..90a8a6c720 100644 --- a/erpnext/stock/doctype/delivery_note/delivery_note.py +++ b/erpnext/stock/doctype/delivery_note/delivery_note.py @@ -108,11 +108,9 @@ class DeliveryNote(SellingController): if not self.installation_status: self.installation_status = 'Not Installed' def validate_with_previous_doc(self): - items = self.get("items") - for fn in (("Sales Order", "against_sales_order", "so_detail"), ("Sales Invoice", "against_sales_invoice", "si_detail")): - if filter(None, [getattr(d, fn[1], None) for d in items]): + if filter(None, [getattr(d, fn[1], None) for d in self.get("items")]): super(DeliveryNote, self).validate_with_previous_doc({ fn[0]: { "ref_dn_field": fn[1], @@ -120,15 +118,10 @@ class DeliveryNote(SellingController): ["currency", "="]], }, }) - - if cint(frappe.defaults.get_global_default('maintain_same_sales_rate')): - super(DeliveryNote, self).validate_with_previous_doc({ - fn[0] + " Item": { - "ref_dn_field": fn[2], - "compare_fields": [["rate", "="]], - "is_child_table": True - } - }) + + if cint(frappe.db.get_single_value('Selling Settings', 'maintain_same_sales_rate')): + self.validate_rate_with_reference_doc([["Sales Order", "sales_order", "so_detail"], + ["Sales Invoice", "sales_invoice", "si_detail"]]) def validate_proj_cust(self): """check for does customer belong to same project as entered..""" diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py index e56cd1e907..e78288908d 100644 --- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py @@ -104,15 +104,8 @@ class PurchaseReceipt(BuyingController): } }) - if cint(frappe.defaults.get_global_default('maintain_same_rate')): - super(PurchaseReceipt, self).validate_with_previous_doc({ - "Purchase Order Item": { - "ref_dn_field": "prevdoc_detail_docname", - "compare_fields": [["rate", "="]], - "is_child_table": True - } - }) - + if cint(frappe.db.get_single_value('Buying Settings', 'maintain_same_rate')): + self.validate_rate_with_reference_doc([["Purchase Order", "prevdoc_docname", "prevdoc_detail_docname"]]) def po_required(self): if frappe.db.get_value("Buying Settings", None, "po_required") == 'Yes': diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py index be74aeb920..63e8f6761e 100644 --- a/erpnext/utilities/transaction_base.py +++ b/erpnext/utilities/transaction_base.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe from frappe import _ -from frappe.utils import cstr, now_datetime, cint +from frappe.utils import cstr, now_datetime, cint, flt import frappe.share from erpnext.controllers.status_updater import StatusUpdater @@ -92,6 +92,17 @@ class TransactionBase(StatusUpdater): for field, condition in fields: if prevdoc_values[field] is not None: self.validate_value(field, condition, prevdoc_values[field], doc) + + + def validate_rate_with_reference_doc(self, ref_details): + for ref_dt, ref_dn_field, ref_link_field in ref_details: + for d in self.get("items"): + if d.get(ref_link_field): + ref_rate = frappe.db.get_value(ref_dt + " Item", d.get(ref_link_field), "rate") + + if abs(flt(d.rate - ref_rate, d.precision("rate"))) >= .01: + frappe.throw(_("Row #{0}: Rate must be same with {1}: {2} ({3} / {4}) ") + .format(d.idx, ref_dt, d.get(ref_dn_field), d.rate, ref_rate)) def delete_events(ref_type, ref_name):