From ea55d772003d6e7f30b33faaa832f736d81c2f47 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 15 Apr 2014 15:11:00 +0530 Subject: [PATCH] added validation for update_after_submit #270 --- frappe/exceptions.py | 1 + frappe/model/base_document.py | 11 +++++++-- frappe/model/document.py | 5 ++++ frappe/tests/test_document.py | 45 +++++++++++++++++++++-------------- frappe/utils/backups.py | 3 +-- 5 files changed, 43 insertions(+), 22 deletions(-) diff --git a/frappe/exceptions.py b/frappe/exceptions.py index 19919f757f..422d9fc99d 100644 --- a/frappe/exceptions.py +++ b/frappe/exceptions.py @@ -37,6 +37,7 @@ class MandatoryError(ValidationError): pass class InvalidSignatureError(ValidationError): pass class RateLimitExceededError(ValidationError): pass class CannotChangeConstantError(ValidationError): pass +class UpdateAfterSubmitError(ValidationError): pass class LinkValidationError(ValidationError): pass class DocstatusTransitionError(ValidationError): pass class TimestampMismatchError(ValidationError): pass diff --git a/frappe/model/base_document.py b/frappe/model/base_document.py index aa47592497..fa51511d1a 100644 --- a/frappe/model/base_document.py +++ b/frappe/model/base_document.py @@ -258,10 +258,17 @@ class BaseDocument(object): for fieldname in constants: if self.get(fieldname) != values.get(fieldname): - frappe.throw("{0}: {1}".format(_("Value cannot be changed for"), - _(self.meta.get_label(fieldname))), + frappe.throw(_("Value cannot be changed for {0}").format(self.meta.get_label(fieldname)), 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(): + df = self.meta.get_field(key) + if df and not df.allow_on_submit and self.get(key) != value: + frappe.throw(_("Not allowed to change {0} after submission").format(df.label), + frappe.UpdateAfterSubmitError) + 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 20be3cf12b..5479ad7dbe 100644 --- a/frappe/model/document.py +++ b/frappe/model/document.py @@ -217,6 +217,7 @@ class Document(BaseDocument): self._validate_constants() for d in self.get_all_children(): d._validate_constants() + self._extract_images_from_text_editor() def _set_defaults(self): @@ -297,6 +298,10 @@ class Document(BaseDocument): if getattr(self, "ignore_validate_update_after_submit", False): return + self._validate_update_after_submit() + for d in self.get_all_children(): + d._validate_update_after_submit() + # TODO check only allowed values are updated def _validate_mandatory(self): diff --git a/frappe/tests/test_document.py b/frappe/tests/test_document.py index 3cc8b1ae1d..212b5dc4e7 100644 --- a/frappe/tests/test_document.py +++ b/frappe/tests/test_document.py @@ -1,13 +1,13 @@ # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors # MIT License. See license.txt -import frappe, unittest, time +import frappe, unittest class TestDocument(unittest.TestCase): def test_get_return_empty_list_for_table_field_if_none(self): d = frappe.get_doc({"doctype":"User"}) self.assertEquals(d.get("user_roles"), []) - + def test_load(self): d = frappe.get_doc("DocType", "User") self.assertEquals(d.doctype, "DocType") @@ -16,13 +16,13 @@ class TestDocument(unittest.TestCase): self.assertTrue(isinstance(d.fields, list)) self.assertTrue(isinstance(d.permissions, list)) self.assertTrue(filter(lambda d: d.fieldname=="email", d.fields)) - + def test_load_single(self): d = frappe.get_doc("Website Settings", "Website Settings") self.assertEquals(d.name, "Website Settings") self.assertEquals(d.doctype, "Website Settings") self.assertTrue(d.disable_signup in (0, 1)) - + def test_insert(self): d = frappe.get_doc({ "doctype":"Event", @@ -32,13 +32,13 @@ class TestDocument(unittest.TestCase): }) d.insert() self.assertTrue(d.name.startswith("EV")) - self.assertEquals(frappe.db.get_value("Event", d.name, "subject"), + self.assertEquals(frappe.db.get_value("Event", d.name, "subject"), "test-doc-test-event 1") - + # test if default values are added self.assertEquals(d.send_reminder, 1) return d - + def test_insert_with_child(self): d = frappe.get_doc({ "doctype":"Event", @@ -53,30 +53,30 @@ class TestDocument(unittest.TestCase): }) d.insert() self.assertTrue(d.name.startswith("EV")) - self.assertEquals(frappe.db.get_value("Event", d.name, "subject"), + self.assertEquals(frappe.db.get_value("Event", d.name, "subject"), "test-doc-test-event 2") - + d1 = frappe.get_doc("Event", d.name) self.assertTrue(d1.event_individuals[0].person, "Administrator") - + def test_update(self): d = self.test_insert() d.subject = "subject changed" d.save() - + self.assertEquals(frappe.db.get_value(d.doctype, d.name, "subject"), "subject changed") - + def test_mandatory(self): d = frappe.get_doc({ "doctype": "User", "email": "test_mandatory@example.com", }) self.assertRaises(frappe.MandatoryError, d.insert) - + d.set("first_name", "Test Mandatory") d.insert() self.assertEquals(frappe.db.get_value("User", d.name), d.name) - + def test_confict_validation(self): d1 = self.test_insert() d2 = frappe.get_doc(d1.doctype, d1.name) @@ -93,13 +93,13 @@ class TestDocument(unittest.TestCase): frappe.set_user("Guest") d = self.assertRaises(frappe.PermissionError, self.test_insert) frappe.set_user("Administrator") - + def test_permission_single(self): frappe.set_user("Guest") d = frappe.get_doc("Website Settings", "Website Settigns") self.assertRaises(frappe.PermissionError, d.save) frappe.set_user("Administrator") - + def test_link_validation(self): d = frappe.get_doc({ "doctype": "User", @@ -118,7 +118,7 @@ class TestDocument(unittest.TestCase): }) d.insert() self.assertEquals(frappe.db.get_value("User", d.name), d.name) - + def test_validate(self): d = self.test_insert() d.starts_on = "2014-01-01" @@ -126,4 +126,13 @@ class TestDocument(unittest.TestCase): self.assertRaises(frappe.ValidationError, d.validate) self.assertRaises(frappe.ValidationError, d.run_method, "validate") self.assertRaises(frappe.ValidationError, d.save) - + + def test_update_after_submit(self): + d = self.test_insert() + d.starts_on = "2014-09-09" + self.assertRaises(frappe.UpdateAfterSubmitError, d.validate_update_after_submit) + d.meta.get_field("starts_on").allow_on_submit = 1 + d.validate_update_after_submit() + d.meta.get_field("starts_on").allow_on_submit = 0 + + diff --git a/frappe/utils/backups.py b/frappe/utils/backups.py index 6ec1b07c52..81aa373f6d 100644 --- a/frappe/utils/backups.py +++ b/frappe/utils/backups.py @@ -108,8 +108,7 @@ class BackupGenerator:

2. Click here to download\ the files backup

This link will be valid for 24 hours. A new backup will be available - for download only after 24 hours.

-

Have a nice day!
ERPNext

""" % { + for download only after 24 hours.

""" % { "db_backup_url": db_backup_url, "files_backup_url": files_backup_url }