From 67b4d5d2f318d1de90687e2bf9480d30f4cbc88d Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 3 Apr 2015 19:42:48 +0530 Subject: [PATCH] [fix] cast and compare values in update after submit --- frappe/model/base_document.py | 41 ++++++++++++++++++++++++++++++----- frappe/model/document.py | 16 +++----------- frappe/tests/test_document.py | 4 ++++ 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/frappe/model/base_document.py b/frappe/model/base_document.py index 8e4cbc1529..d6173aff9a 100644 --- a/frappe/model/base_document.py +++ b/frappe/model/base_document.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe, sys from frappe import _ -from frappe.utils import cint, flt, now, cstr, strip_html +from frappe.utils import cint, flt, now, cstr, strip_html, getdate, get_datetime from frappe.model import default_fields from frappe.model.naming import set_new_name from frappe.modules import load_doctype_module @@ -401,12 +401,16 @@ class BaseDocument(object): frappe.CannotChangeConstantError) def _validate_update_after_submit(self): - current = frappe.db.get_value(self.doctype, self.name, "*", as_dict=True) - for key, value in current.iteritems(): + db_values = frappe.db.get_value(self.doctype, self.name, "*", as_dict=True) + for key, db_value in db_values.iteritems(): df = self.meta.get_field(key) - if df and not df.allow_on_submit and (self.get(key) or value) and self.get(key) != value: - frappe.throw(_("Not allowed to change {0} after submission").format(df.label), - frappe.UpdateAfterSubmitError) + + if df and not df.allow_on_submit and (self.get(key) or db_value): + self_value = self.get_value(key) + + if self_value != db_value: + frappe.throw(_("Not allowed to change {0} after submission").format(df.label), + frappe.UpdateAfterSubmitError) def precision(self, fieldname, parentfield=None): """Returns float precision for a particular field (or get global default). @@ -496,6 +500,31 @@ class BaseDocument(object): for df in to_reset: self.set(df.fieldname, ref_doc.get(df.fieldname)) + def get_value(self, fieldname): + df = self.meta.get_field(fieldname) + val = self.get(fieldname) + + return self.cast(val, df) + + def cast(self, val, df): + if df.fieldtype in ("Currency", "Float", "Percent"): + val = flt(val, self.precision(df.fieldname)) + + elif df.fieldtype in ("Int", "Check"): + val = cint(val) + + elif df.fieldtype in ("Data", "Text", "Small Text", "Long Text", + "Text Editor", "Select", "Link", "Dynamic Link"): + val = cstr(val) + + elif df.fieldtype == "Date": + val = getdate(val) + + elif df.fieldtype == "Datetime": + val = get_datetime(val) + + return val + def _filter(data, filters, limit=None): """pass filters as: {"key": "val", "key": ["!=", "val"], diff --git a/frappe/model/document.py b/frappe/model/document.py index 3006df458d..eb019096b2 100644 --- a/frappe/model/document.py +++ b/frappe/model/document.py @@ -639,20 +639,10 @@ class Document(BaseDocument): if not doc: doc = self + val1 = doc.get_value(fieldname) + df = doc.meta.get_field(fieldname) - - val1 = doc.get(fieldname) - - if df.fieldtype in ("Currency", "Float", "Percent"): - val1 = flt(val1, self.precision(df.fieldname, doc.parentfield or None)) - val2 = flt(val2, self.precision(df.fieldname, doc.parentfield or None)) - elif df.fieldtype in ("Int", "Check"): - val1 = cint(val1) - val2 = cint(val2) - elif df.fieldtype in ("Data", "Text", "Small Text", "Long Text", - "Text Editor", "Select", "Link", "Dynamic Link"): - val1 = cstr(val1) - val2 = cstr(val2) + val2 = doc.cast(val2, df) if not frappe.compare(val1, condition, val2): label = doc.meta.get_label(fieldname) diff --git a/frappe/tests/test_document.py b/frappe/tests/test_document.py index 9c12556f8b..7a33026e4a 100644 --- a/frappe/tests/test_document.py +++ b/frappe/tests/test_document.py @@ -146,3 +146,7 @@ class TestDocument(unittest.TestCase): d.validate_update_after_submit() d.meta.get_field("starts_on").allow_on_submit = 0 + # when comparing date(2014, 1, 1) and "2014-01-01" + d.load_from_db() + d.starts_on = "2014-01-01" + d.validate_update_after_submit()