From 5b8af5c64ee96dde9e7f6c58c244046b0ba4430e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20Fernandes?= Date: Mon, 6 Oct 2014 11:31:44 +0100 Subject: [PATCH 01/13] Extends exports fixtures --- frappe/core/page/data_import_tool/exporter.py | 42 +++ .../test_exporter_fixtures.py | 257 ++++++++++++++++++ frappe/utils/fixtures.py | 10 +- 3 files changed, 305 insertions(+), 4 deletions(-) create mode 100644 frappe/core/page/data_import_tool/test_exporter_fixtures.py diff --git a/frappe/core/page/data_import_tool/exporter.py b/frappe/core/page/data_import_tool/exporter.py index c1ef21e410..6c25277ed6 100644 --- a/frappe/core/page/data_import_tool/exporter.py +++ b/frappe/core/page/data_import_tool/exporter.py @@ -5,14 +5,34 @@ from __future__ import unicode_literals import frappe, json, os import frappe.permissions +import re from frappe.utils.csvutils import UnicodeWriter from frappe.utils import cstr, cint, flt from frappe.core.page.data_import_tool.data_import_tool import data_keys +reflags = { + "I":re.I, + "L":re.L, + "M":re.M, + "U":re.U, + "S":re.S, + "X":re.X, + "D": re.DEBUG +} + @frappe.whitelist() def get_template(doctype=None, parent_doctype=None, all_doctypes="No", with_data="No"): all_doctypes = all_doctypes=="Yes" + docs_to_export = {} + if doctype: + if isinstance(doctype, basestring): + doctype = [doctype]; + + if len(doctype) > 1: + docs_to_export = doctype[1]#dictionary for selective exports + #here, doctype is allways a list. Was converted to list in module fixtures.py + doctype = doctype[0] if not parent_doctype: parent_doctype = doctype @@ -148,6 +168,28 @@ def get_template(doctype=None, parent_doctype=None, all_doctypes="No", with_data # get permitted data only data = frappe.get_list(doctype, fields=["*"], limit_page_length=None) for doc in data: + op = docs_to_export.get("op") + names = docs_to_export.get("name") + + if names and op: + if op == '=' and doc.name not in names: + continue + elif op == '!=' and doc.name in names: + continue + elif names: + try: + sflags = docs_to_export.get("flags", "I,U").upper() + flags = 0 + for a in re.split('\W+',sflags): + flags = flags | reflags.get(a,0) + + c = re.compile(names, flags) + m = c.match(doc.name) + if not m: + continue + except: + if doc.name not in names: + continue # add main table row_group = [] diff --git a/frappe/core/page/data_import_tool/test_exporter_fixtures.py b/frappe/core/page/data_import_tool/test_exporter_fixtures.py new file mode 100644 index 0000000000..b83ab7c1a1 --- /dev/null +++ b/frappe/core/page/data_import_tool/test_exporter_fixtures.py @@ -0,0 +1,257 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# MIT License. See license.txt + +import frappe +import frappe.defaults +from frappe.core.page.data_import_tool.data_import_tool import export_csv +import unittest + +class TestDataImportFixtures(unittest.TestCase): + + def setUp(self): + print "\nTeste for export explicit fixtures" + print "see fixtures csv test files in sites folder" + + #start test for Custom Script + def test_Custom_Script_fixture_simple(self): + fixture = "Custom Script" + path = frappe.scrub(fixture) + "_original_style.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Script_fixture_simple_name_equal_default(self): + fixture = ["Custom Script", {"name":["Item-Client"]}] + path = frappe.scrub(fixture[0]) + "_simple_name_equal_default.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Script_fixture_simple_name_equal(self): + fixture = ["Custom Script", {"name":["Item-Client"],"op":"="}] + path = frappe.scrub(fixture[0]) + "_simple_name_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Script_fixture_simple_name_not_equal(self): + fixture = ["Custom Script", {"name":["Item-Client"],"op":"!="}] + path = frappe.scrub(fixture[0]) + "_simple_name_not_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + #without [] around the name... + def test_Custom_Script_fixture_simple_name_at_least_equal(self): + fixture = ["Custom Script", {"name":"Item-Cli"}] + path = frappe.scrub(fixture[0]) + "_simple_name_at_least_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Script_fixture_multi_name_equal(self): + fixture = ["Custom Script", {"name":["Item-Client", "Customer-Client"],"op":"="}] + path = frappe.scrub(fixture[0]) + "_multi_name_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Script_fixture_multi_name_not_equal(self): + fixture = ["Custom Script", {"name":["Item-Client", "Customer-Client"],"op":"!="}] + path = frappe.scrub(fixture[0]) + "_multi_name_not_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Script_fixture_empty_object(self): + fixture = ["Custom Script", {}] + path = frappe.scrub(fixture[0]) + "_empty_object_should_be_all.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Script_fixture_just_list(self): + fixture = ["Custom Script"] + path = frappe.scrub(fixture[0]) + "_just_list_should_be_all.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + # Custom Script regular expression + def test_Custom_Script_fixture_rex_no_flags(self): + fixture = ["Custom Script", {"name":r"^[i|A]"}] + path = frappe.scrub(fixture[0]) + "_rex_no_flags.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Script_fixture_rex_with_flags(self): + fixture = ["Custom Script", {"name":r"^[i|A]", "flags":"L,M"}] + path = frappe.scrub(fixture[0]) + "_rex_with_flags.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + + #start test for Custom Field + def test_Custom_Field_fixture_simple(self): + fixture = "Custom Field" + path = frappe.scrub(fixture) + "_original_style.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Field_fixture_simple_name_equal_default(self): + fixture = ["Custom Field", {"name":["Item-vat"]}] + path = frappe.scrub(fixture[0]) + "_simple_name_equal_default.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Field_fixture_simple_name_equal(self): + fixture = ["Custom Field", {"name":["Item-vat"],"op":"="}] + path = frappe.scrub(fixture[0]) + "_simple_name_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Field_fixture_simple_name_not_equal(self): + fixture = ["Custom Field", {"name":["Item-vat"],"op":"!="}] + path = frappe.scrub(fixture[0]) + "_simple_name_not_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + #without [] around the name... + def test_Custom_Field_fixture_simple_name_at_least_equal(self): + fixture = ["Custom Field", {"name":"Item-va"}] + path = frappe.scrub(fixture[0]) + "_simple_name_at_least_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Field_fixture_multi_name_equal(self): + fixture = ["Custom Field", {"name":["Item-vat", "Bin-vat"],"op":"="}] + path = frappe.scrub(fixture[0]) + "_multi_name_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Field_fixture_multi_name_not_equal(self): + fixture = ["Custom Field", {"name":["Item-vat", "Bin-vat"],"op":"!="}] + path = frappe.scrub(fixture[0]) + "_multi_name_not_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Field_fixture_empty_object(self): + fixture = ["Custom Field", {}] + path = frappe.scrub(fixture[0]) + "_empty_object_should_be_all.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Field_fixture_just_list(self): + fixture = ["Custom Field"] + path = frappe.scrub(fixture[0]) + "_just_list_should_be_all.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + # Custom Field regular expression + def test_Custom_Field_fixture_rex_no_flags(self): + fixture = ["Custom Field", {"name":r"^[r|L]"}] + path = frappe.scrub(fixture[0]) + "_rex_no_flags.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Field_fixture_rex_with_flags(self): + fixture = ["Custom Field", {"name":r"^[i|A]", "flags":"L,M"}] + path = frappe.scrub(fixture[0]) + "_rex_with_flags.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + + #start test for Doctype + def test_Doctype_fixture_simple(self): + fixture = "Customer" + path = "Doctype_" + frappe.scrub(fixture) + "_original_style.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Doctype_fixture_simple_name_equal_default(self): + fixture = ["Customer", {"name":["_Test Lead"]}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_equal_default.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Doctype_fixture_simple_name_equal(self): + fixture = ["Customer", {"name":["_Test Customer 1"],"op":"="}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Doctype_simple_name_not_equal(self): + fixture = ["Customer", {"name":["_Test Customer 2"],"op":"!="}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_not_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + #without [] around the name... + def test_Doctype_fixture_simple_name_at_least_equal(self): + fixture = ["Customer", {"name":"_Test Customer"}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_at_least_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Doctype_multi_name_equal(self): + fixture = ["Customer", {"name":["_Test Customer 1", "_Test Customer 2"],"op":"="}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_multi_name_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Doctype_multi_name_not_equal(self): + fixture = ["Customer", {"name":["_Test Customer 1", "_Test Customer 2"],"op":"!="}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_multi_name_not_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Doctype_fixture_empty_object(self): + fixture = ["Customer", {}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_empty_object_should_be_all.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Doctype_fixture_just_list(self): + fixture = ["Customer"] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_just_list_should_be_all.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + # Doctype regular expression + def test_Doctype_fixture_rex_no_flags(self): + fixture = ["Customer", {"name":r"_Test (?=L)"}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_rex_no_flags.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Doctype_fixture_rex_with_flags(self): + fixture = ["Customer", {"name":r"_Test (?!C)", "flags":"L,M"}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_rex_with_flags.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + \ No newline at end of file diff --git a/frappe/utils/fixtures.py b/frappe/utils/fixtures.py index 6062c9ec38..bfcf0ae91c 100644 --- a/frappe/utils/fixtures.py +++ b/frappe/utils/fixtures.py @@ -22,10 +22,12 @@ def sync_fixtures(app=None): def export_fixtures(): for app in frappe.get_installed_apps(): for fixture in frappe.get_hooks("fixtures", app_name=app): - print "Exporting " + fixture + print "Exporting {0}".format(fixture) if not os.path.exists(frappe.get_app_path(app, "fixtures")): os.mkdir(frappe.get_app_path(app, "fixtures")) - if frappe.db.get_value("DocType", fixture, "issingle"): - export_fixture(fixture, fixture, app) + if isinstance(fixture, basestring): + fixture = [fixture]; + if frappe.db.get_value("DocType", fixture[0], "issingle"): + export_fixture(fixture[0], fixture[0], app) else: - export_csv(fixture, frappe.get_app_path(app, "fixtures", frappe.scrub(fixture) + ".csv")) + export_csv(fixture, frappe.get_app_path(app, "fixtures", frappe.scrub(fixture[0]) + ".csv")) From 9a682a68b99d1f21ee1bb3ed395223e72dac6b52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20Fernandes?= Date: Mon, 6 Oct 2014 11:38:04 +0100 Subject: [PATCH 02/13] Extends export fixtures --- frappe/core/page/data_import_tool/exporter.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frappe/core/page/data_import_tool/exporter.py b/frappe/core/page/data_import_tool/exporter.py index 6c25277ed6..6884b0894e 100644 --- a/frappe/core/page/data_import_tool/exporter.py +++ b/frappe/core/page/data_import_tool/exporter.py @@ -28,11 +28,10 @@ def get_template(doctype=None, parent_doctype=None, all_doctypes="No", with_data if doctype: if isinstance(doctype, basestring): doctype = [doctype]; - if len(doctype) > 1: - docs_to_export = doctype[1]#dictionary for selective exports - #here, doctype is allways a list. Was converted to list in module fixtures.py + docs_to_export = doctype[1] doctype = doctype[0] + if not parent_doctype: parent_doctype = doctype From e74b50cdb7e292d43172332a2ff6dc24d3427e3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20Fernandes?= Date: Mon, 6 Oct 2014 12:30:09 +0100 Subject: [PATCH 03/13] Extends export fixtures no test file --- .../test_exporter_fixtures.py | 257 ------------------ 1 file changed, 257 deletions(-) delete mode 100644 frappe/core/page/data_import_tool/test_exporter_fixtures.py diff --git a/frappe/core/page/data_import_tool/test_exporter_fixtures.py b/frappe/core/page/data_import_tool/test_exporter_fixtures.py deleted file mode 100644 index b83ab7c1a1..0000000000 --- a/frappe/core/page/data_import_tool/test_exporter_fixtures.py +++ /dev/null @@ -1,257 +0,0 @@ -# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors -# MIT License. See license.txt - -import frappe -import frappe.defaults -from frappe.core.page.data_import_tool.data_import_tool import export_csv -import unittest - -class TestDataImportFixtures(unittest.TestCase): - - def setUp(self): - print "\nTeste for export explicit fixtures" - print "see fixtures csv test files in sites folder" - - #start test for Custom Script - def test_Custom_Script_fixture_simple(self): - fixture = "Custom Script" - path = frappe.scrub(fixture) + "_original_style.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Custom_Script_fixture_simple_name_equal_default(self): - fixture = ["Custom Script", {"name":["Item-Client"]}] - path = frappe.scrub(fixture[0]) + "_simple_name_equal_default.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Custom_Script_fixture_simple_name_equal(self): - fixture = ["Custom Script", {"name":["Item-Client"],"op":"="}] - path = frappe.scrub(fixture[0]) + "_simple_name_equal.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Custom_Script_fixture_simple_name_not_equal(self): - fixture = ["Custom Script", {"name":["Item-Client"],"op":"!="}] - path = frappe.scrub(fixture[0]) + "_simple_name_not_equal.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - #without [] around the name... - def test_Custom_Script_fixture_simple_name_at_least_equal(self): - fixture = ["Custom Script", {"name":"Item-Cli"}] - path = frappe.scrub(fixture[0]) + "_simple_name_at_least_equal.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Custom_Script_fixture_multi_name_equal(self): - fixture = ["Custom Script", {"name":["Item-Client", "Customer-Client"],"op":"="}] - path = frappe.scrub(fixture[0]) + "_multi_name_equal.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Custom_Script_fixture_multi_name_not_equal(self): - fixture = ["Custom Script", {"name":["Item-Client", "Customer-Client"],"op":"!="}] - path = frappe.scrub(fixture[0]) + "_multi_name_not_equal.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Custom_Script_fixture_empty_object(self): - fixture = ["Custom Script", {}] - path = frappe.scrub(fixture[0]) + "_empty_object_should_be_all.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Custom_Script_fixture_just_list(self): - fixture = ["Custom Script"] - path = frappe.scrub(fixture[0]) + "_just_list_should_be_all.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - # Custom Script regular expression - def test_Custom_Script_fixture_rex_no_flags(self): - fixture = ["Custom Script", {"name":r"^[i|A]"}] - path = frappe.scrub(fixture[0]) + "_rex_no_flags.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Custom_Script_fixture_rex_with_flags(self): - fixture = ["Custom Script", {"name":r"^[i|A]", "flags":"L,M"}] - path = frappe.scrub(fixture[0]) + "_rex_with_flags.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - - #start test for Custom Field - def test_Custom_Field_fixture_simple(self): - fixture = "Custom Field" - path = frappe.scrub(fixture) + "_original_style.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Custom_Field_fixture_simple_name_equal_default(self): - fixture = ["Custom Field", {"name":["Item-vat"]}] - path = frappe.scrub(fixture[0]) + "_simple_name_equal_default.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Custom_Field_fixture_simple_name_equal(self): - fixture = ["Custom Field", {"name":["Item-vat"],"op":"="}] - path = frappe.scrub(fixture[0]) + "_simple_name_equal.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Custom_Field_fixture_simple_name_not_equal(self): - fixture = ["Custom Field", {"name":["Item-vat"],"op":"!="}] - path = frappe.scrub(fixture[0]) + "_simple_name_not_equal.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - #without [] around the name... - def test_Custom_Field_fixture_simple_name_at_least_equal(self): - fixture = ["Custom Field", {"name":"Item-va"}] - path = frappe.scrub(fixture[0]) + "_simple_name_at_least_equal.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Custom_Field_fixture_multi_name_equal(self): - fixture = ["Custom Field", {"name":["Item-vat", "Bin-vat"],"op":"="}] - path = frappe.scrub(fixture[0]) + "_multi_name_equal.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Custom_Field_fixture_multi_name_not_equal(self): - fixture = ["Custom Field", {"name":["Item-vat", "Bin-vat"],"op":"!="}] - path = frappe.scrub(fixture[0]) + "_multi_name_not_equal.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Custom_Field_fixture_empty_object(self): - fixture = ["Custom Field", {}] - path = frappe.scrub(fixture[0]) + "_empty_object_should_be_all.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Custom_Field_fixture_just_list(self): - fixture = ["Custom Field"] - path = frappe.scrub(fixture[0]) + "_just_list_should_be_all.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - # Custom Field regular expression - def test_Custom_Field_fixture_rex_no_flags(self): - fixture = ["Custom Field", {"name":r"^[r|L]"}] - path = frappe.scrub(fixture[0]) + "_rex_no_flags.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Custom_Field_fixture_rex_with_flags(self): - fixture = ["Custom Field", {"name":r"^[i|A]", "flags":"L,M"}] - path = frappe.scrub(fixture[0]) + "_rex_with_flags.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - - #start test for Doctype - def test_Doctype_fixture_simple(self): - fixture = "Customer" - path = "Doctype_" + frappe.scrub(fixture) + "_original_style.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Doctype_fixture_simple_name_equal_default(self): - fixture = ["Customer", {"name":["_Test Lead"]}] - path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_equal_default.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Doctype_fixture_simple_name_equal(self): - fixture = ["Customer", {"name":["_Test Customer 1"],"op":"="}] - path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_equal.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Doctype_simple_name_not_equal(self): - fixture = ["Customer", {"name":["_Test Customer 2"],"op":"!="}] - path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_not_equal.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - #without [] around the name... - def test_Doctype_fixture_simple_name_at_least_equal(self): - fixture = ["Customer", {"name":"_Test Customer"}] - path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_at_least_equal.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Doctype_multi_name_equal(self): - fixture = ["Customer", {"name":["_Test Customer 1", "_Test Customer 2"],"op":"="}] - path = "Doctype_" + frappe.scrub(fixture[0]) + "_multi_name_equal.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Doctype_multi_name_not_equal(self): - fixture = ["Customer", {"name":["_Test Customer 1", "_Test Customer 2"],"op":"!="}] - path = "Doctype_" + frappe.scrub(fixture[0]) + "_multi_name_not_equal.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Doctype_fixture_empty_object(self): - fixture = ["Customer", {}] - path = "Doctype_" + frappe.scrub(fixture[0]) + "_empty_object_should_be_all.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Doctype_fixture_just_list(self): - fixture = ["Customer"] - path = "Doctype_" + frappe.scrub(fixture[0]) + "_just_list_should_be_all.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - # Doctype regular expression - def test_Doctype_fixture_rex_no_flags(self): - fixture = ["Customer", {"name":r"_Test (?=L)"}] - path = "Doctype_" + frappe.scrub(fixture[0]) + "_rex_no_flags.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - def test_Doctype_fixture_rex_with_flags(self): - fixture = ["Customer", {"name":r"_Test (?!C)", "flags":"L,M"}] - path = "Doctype_" + frappe.scrub(fixture[0]) + "_rex_with_flags.csv" - print "teste done {}".format(path) - export_csv(fixture, path) - self.assertTrue(True) - - \ No newline at end of file From 704d7043c8ddf4419e04df9ddfd4c39562de0c2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20Fernandes?= Date: Mon, 6 Oct 2014 13:17:57 +0100 Subject: [PATCH 04/13] Extends export fixtures - added test file with ToDo as doctype --- .../test_exporter_fixtures.py | 257 ++++++++++++++++++ 1 file changed, 257 insertions(+) create mode 100644 frappe/core/page/data_import_tool/test_exporter_fixtures.py diff --git a/frappe/core/page/data_import_tool/test_exporter_fixtures.py b/frappe/core/page/data_import_tool/test_exporter_fixtures.py new file mode 100644 index 0000000000..862268b00f --- /dev/null +++ b/frappe/core/page/data_import_tool/test_exporter_fixtures.py @@ -0,0 +1,257 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# MIT License. See license.txt + +import frappe +import frappe.defaults +from frappe.core.page.data_import_tool.data_import_tool import export_csv +import unittest + +class TestDataImportFixtures(unittest.TestCase): + + def setUp(self): + print "\nTeste for export explicit fixtures" + print "see fixtures csv test files in sites folder" + + #start test for Custom Script + def test_Custom_Script_fixture_simple(self): + fixture = "Custom Script" + path = frappe.scrub(fixture) + "_original_style.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Script_fixture_simple_name_equal_default(self): + fixture = ["Custom Script", {"name":["Item-Client"]}] + path = frappe.scrub(fixture[0]) + "_simple_name_equal_default.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Script_fixture_simple_name_equal(self): + fixture = ["Custom Script", {"name":["Item-Client"],"op":"="}] + path = frappe.scrub(fixture[0]) + "_simple_name_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Script_fixture_simple_name_not_equal(self): + fixture = ["Custom Script", {"name":["Item-Client"],"op":"!="}] + path = frappe.scrub(fixture[0]) + "_simple_name_not_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + #without [] around the name... + def test_Custom_Script_fixture_simple_name_at_least_equal(self): + fixture = ["Custom Script", {"name":"Item-Cli"}] + path = frappe.scrub(fixture[0]) + "_simple_name_at_least_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Script_fixture_multi_name_equal(self): + fixture = ["Custom Script", {"name":["Item-Client", "Customer-Client"],"op":"="}] + path = frappe.scrub(fixture[0]) + "_multi_name_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Script_fixture_multi_name_not_equal(self): + fixture = ["Custom Script", {"name":["Item-Client", "Customer-Client"],"op":"!="}] + path = frappe.scrub(fixture[0]) + "_multi_name_not_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Script_fixture_empty_object(self): + fixture = ["Custom Script", {}] + path = frappe.scrub(fixture[0]) + "_empty_object_should_be_all.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Script_fixture_just_list(self): + fixture = ["Custom Script"] + path = frappe.scrub(fixture[0]) + "_just_list_should_be_all.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + # Custom Script regular expression + def test_Custom_Script_fixture_rex_no_flags(self): + fixture = ["Custom Script", {"name":r"^[i|A]"}] + path = frappe.scrub(fixture[0]) + "_rex_no_flags.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Script_fixture_rex_with_flags(self): + fixture = ["Custom Script", {"name":r"^[i|A]", "flags":"L,M"}] + path = frappe.scrub(fixture[0]) + "_rex_with_flags.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + + #start test for Custom Field + def test_Custom_Field_fixture_simple(self): + fixture = "Custom Field" + path = frappe.scrub(fixture) + "_original_style.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Field_fixture_simple_name_equal_default(self): + fixture = ["Custom Field", {"name":["Item-vat"]}] + path = frappe.scrub(fixture[0]) + "_simple_name_equal_default.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Field_fixture_simple_name_equal(self): + fixture = ["Custom Field", {"name":["Item-vat"],"op":"="}] + path = frappe.scrub(fixture[0]) + "_simple_name_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Field_fixture_simple_name_not_equal(self): + fixture = ["Custom Field", {"name":["Item-vat"],"op":"!="}] + path = frappe.scrub(fixture[0]) + "_simple_name_not_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + #without [] around the name... + def test_Custom_Field_fixture_simple_name_at_least_equal(self): + fixture = ["Custom Field", {"name":"Item-va"}] + path = frappe.scrub(fixture[0]) + "_simple_name_at_least_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Field_fixture_multi_name_equal(self): + fixture = ["Custom Field", {"name":["Item-vat", "Bin-vat"],"op":"="}] + path = frappe.scrub(fixture[0]) + "_multi_name_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Field_fixture_multi_name_not_equal(self): + fixture = ["Custom Field", {"name":["Item-vat", "Bin-vat"],"op":"!="}] + path = frappe.scrub(fixture[0]) + "_multi_name_not_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Field_fixture_empty_object(self): + fixture = ["Custom Field", {}] + path = frappe.scrub(fixture[0]) + "_empty_object_should_be_all.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Field_fixture_just_list(self): + fixture = ["Custom Field"] + path = frappe.scrub(fixture[0]) + "_just_list_should_be_all.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + # Custom Field regular expression + def test_Custom_Field_fixture_rex_no_flags(self): + fixture = ["Custom Field", {"name":r"^[r|L]"}] + path = frappe.scrub(fixture[0]) + "_rex_no_flags.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Custom_Field_fixture_rex_with_flags(self): + fixture = ["Custom Field", {"name":r"^[i|A]", "flags":"L,M"}] + path = frappe.scrub(fixture[0]) + "_rex_with_flags.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + + #start test for Doctype + def test_Doctype_fixture_simple(self): + fixture = "ToDo" + path = "Doctype_" + frappe.scrub(fixture) + "_original_style_should_be_all.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Doctype_fixture_simple_name_equal_default(self): + fixture = ["ToDo", {"name":["TDI00000008"]}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_equal_default.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Doctype_fixture_simple_name_equal(self): + fixture = ["ToDo", {"name":["TDI00000002"],"op":"="}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Doctype_simple_name_not_equal(self): + fixture = ["ToDo", {"name":["TDI00000002"],"op":"!="}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_not_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + #without [] around the name... + def test_Doctype_fixture_simple_name_at_least_equal(self): + fixture = ["ToDo", {"name":"TDI"}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_at_least_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Doctype_multi_name_equal(self): + fixture = ["ToDo", {"name":["TDI00000002", "TDI00000008"],"op":"="}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_multi_name_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Doctype_multi_name_not_equal(self): + fixture = ["ToDo", {"name":["TDI00000002", "TDI00000008"],"op":"!="}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_multi_name_not_equal.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Doctype_fixture_empty_object(self): + fixture = ["ToDo", {}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_empty_object_should_be_all.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Doctype_fixture_just_list(self): + fixture = ["ToDo"] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_just_list_should_be_all.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + # Doctype regular expression + def test_Doctype_fixture_rex_no_flags(self): + fixture = ["ToDo", {"name":r"^TDi"}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_rex_no_flags_should_be_all.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + def test_Doctype_fixture_rex_with_flags(self): + fixture = ["ToDo", {"name":r"^TDi", "flags":"L,M"}] + path = "Doctype_" + frappe.scrub(fixture[0]) + "_rex_with_flags_should_be_none.csv" + print "teste done {}".format(path) + export_csv(fixture, path) + self.assertTrue(True) + + \ No newline at end of file From e7d9bc17a4ce4621262e991e8e7126f64d53a5a4 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Tue, 28 Oct 2014 16:37:43 +0530 Subject: [PATCH 05/13] [minor] add jinja import to list.py --- frappe/templates/pages/list.py | 1 + 1 file changed, 1 insertion(+) diff --git a/frappe/templates/pages/list.py b/frappe/templates/pages/list.py index 6f00acfcd7..3ec8e92672 100644 --- a/frappe/templates/pages/list.py +++ b/frappe/templates/pages/list.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals import frappe, os from frappe.modules import get_doc_path, load_doctype_module +from jinja2 import Template no_cache = 1 no_sitemap = 1 From e308e8cee423a6bdce59b9de0058a55f68e6b42b Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Thu, 6 Nov 2014 18:33:38 +0530 Subject: [PATCH 06/13] [minor] add auto_mail_id to test_site site_config.json --- test_sites/test_site/site_config.json | 1 + 1 file changed, 1 insertion(+) diff --git a/test_sites/test_site/site_config.json b/test_sites/test_site/site_config.json index 12007b87ec..7e52d5b941 100644 --- a/test_sites/test_site/site_config.json +++ b/test_sites/test_site/site_config.json @@ -2,5 +2,6 @@ "db_name": "test_frappe", "db_password": "test_frappe", "admin_password": "admin", + "auto_email_id": "test@example.com", "mute_emails": 1 } From 812515f3122fd039e4ffee4e5fe8923835acb428 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 7 Nov 2014 12:29:48 +0530 Subject: [PATCH 07/13] Allowed precision upto 9 for Float, Currency, Percent fieldtype --- .../doctype/customize_form/customize_form.py | 8 +++++++ .../customize_form_field.json | 4 ++-- frappe/core/doctype/docfield/docfield.json | 4 ++-- frappe/model/db_schema.py | 21 ++++++++++++------- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/frappe/core/doctype/customize_form/customize_form.py b/frappe/core/doctype/customize_form/customize_form.py index 04d74eb287..e65023400e 100644 --- a/frappe/core/doctype/customize_form/customize_form.py +++ b/frappe/core/doctype/customize_form/customize_form.py @@ -8,6 +8,7 @@ from __future__ import unicode_literals """ import frappe, json from frappe import _ +from frappe.utils import cint from frappe.model.document import Document from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype @@ -122,6 +123,13 @@ class CustomizeForm(Document): .format(df.idx)) continue + elif property == "precision" and cint(df.get("precision")) > 6 \ + and cint(df.get("precision")) > cint(meta_df[0].get("precision")): + from frappe.model.db_schema import get_definition + frappe.db.sql_ddl("alter table `tab{table}` modify {col_name} {col_def}"\ + .format(table=self.doc_type, col_name=df.fieldname, + col_def=get_definition(df.fieldtype, df.precision))) + self.make_property_setter(property=property, value=df.get(property), property_type=self.docfield_properties[property], fieldname=df.fieldname) diff --git a/frappe/core/doctype/customize_form_field/customize_form_field.json b/frappe/core/doctype/customize_form_field/customize_form_field.json index 0c540044bc..f852b31e4b 100644 --- a/frappe/core/doctype/customize_form_field/customize_form_field.json +++ b/frappe/core/doctype/customize_form_field/customize_form_field.json @@ -86,7 +86,7 @@ "fieldname": "precision", "fieldtype": "Select", "label": "Precision", - "options": "\n1\n2\n3\n4\n5\n6", + "options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9", "permlevel": 0, "precision": "" }, @@ -278,7 +278,7 @@ "idx": 1, "issingle": 0, "istable": 1, - "modified": "2014-09-05 07:41:29.641454", + "modified": "2014-11-07 11:08:52.125289", "modified_by": "Administrator", "module": "Core", "name": "Customize Form Field", diff --git a/frappe/core/doctype/docfield/docfield.json b/frappe/core/doctype/docfield/docfield.json index 1bb0d71a57..ba5696a44a 100644 --- a/frappe/core/doctype/docfield/docfield.json +++ b/frappe/core/doctype/docfield/docfield.json @@ -97,7 +97,7 @@ "fieldname": "precision", "fieldtype": "Select", "label": "Precision", - "options": "\n1\n2\n3\n4\n5\n6", + "options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9", "permlevel": 0, "print_hide": 1 }, @@ -314,7 +314,7 @@ "in_dialog": 1, "issingle": 0, "istable": 1, - "modified": "2014-09-05 07:41:05.956027", + "modified": "2014-11-07 11:40:55.281141", "modified_by": "Administrator", "module": "Core", "name": "DocField", diff --git a/frappe/model/db_schema.py b/frappe/model/db_schema.py index b93d033562..9b79620451 100644 --- a/frappe/model/db_schema.py +++ b/frappe/model/db_schema.py @@ -11,7 +11,7 @@ Syncs a database table to the `DocType` (metadata) import os import frappe from frappe import _ -from frappe.utils import cstr +from frappe.utils import cstr, cint type_map = { 'Currency': ('decimal', '18,6') @@ -107,7 +107,7 @@ class DbTable: for f in fl: self.columns[f['fieldname']] = DbColumn(self, f['fieldname'], f['fieldtype'], f.get('length'), f.get('default'), - f.get('search_index'), f.get('options')) + f.get('search_index'), f.get('options'), f.get('precision')) def get_columns_from_db(self): self.show_columns = frappe.db.sql("desc `%s`" % self.name) @@ -212,7 +212,7 @@ class DbTable: frappe.db.sql("alter table `{}` {}".format(self.name, ", ".join(query))) class DbColumn: - def __init__(self, table, fieldname, fieldtype, length, default, set_index, options): + def __init__(self, table, fieldname, fieldtype, length, default, set_index, options, precision): self.table = table self.fieldname = fieldname self.fieldtype = fieldtype @@ -220,9 +220,10 @@ class DbColumn: self.set_index = set_index self.default = default self.options = options + self.precision = precision def get_definition(self, with_default=1): - ret = get_definition(self.fieldtype) + ret = get_definition(self.fieldtype, self.precision) if with_default and self.default and (self.default not in default_shortcuts) \ and not self.default.startswith(":") and ret not in ['text', 'longtext']: @@ -406,7 +407,7 @@ def remove_all_foreign_keys(): for f in fklist: frappe.db.sql("alter table `tab%s` drop foreign key `%s`" % (t[0], f[1])) -def get_definition(fieldtype): +def get_definition(fieldtype, precision=None): d = type_map.get(fieldtype) if not d: @@ -414,12 +415,16 @@ def get_definition(fieldtype): ret = d[0] if d[1]: - ret += '(' + d[1] + ')' + length = d[1] + if fieldtype in ["Float", "Currency", "Percent"] and cint(precision) > 6: + length = '18,{0}'.format(precision) + ret += '(' + length + ')' + return ret -def add_column(doctype, column_name, fieldtype): +def add_column(doctype, column_name, fieldtype, precision=None): frappe.db.commit() frappe.db.sql("alter table `tab%s` add column %s %s" % (doctype, - column_name, get_definition(fieldtype))) + column_name, get_definition(fieldtype, precision))) From a7448bf1c18f3fd623872f8c0497a39850e86814 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 7 Nov 2014 13:00:43 +0530 Subject: [PATCH 08/13] Allowed precision upto 9 for Float, Currency, Percent fieldtype --- frappe/core/doctype/custom_field/custom_field.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/core/doctype/custom_field/custom_field.json b/frappe/core/doctype/custom_field/custom_field.json index 712ba856f7..07b0f67e86 100644 --- a/frappe/core/doctype/custom_field/custom_field.json +++ b/frappe/core/doctype/custom_field/custom_field.json @@ -68,7 +68,7 @@ "fieldname": "precision", "fieldtype": "Select", "label": "Precision", - "options": "\n1\n2\n3\n4\n5\n6", + "options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9", "permlevel": 0, "precision": "" }, @@ -267,7 +267,7 @@ ], "icon": "icon-glass", "idx": 1, - "modified": "2014-09-05 07:41:13.076820", + "modified": "2014-11-07 12:59:28.734894", "modified_by": "Administrator", "module": "Core", "name": "Custom Field", From 0987bdd849cdaeb06d65d690cbc7e51f20631f2c Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 7 Nov 2014 15:56:39 +0530 Subject: [PATCH 09/13] Don't validate fields for doctype for custom fields when called from customize form --- frappe/core/doctype/custom_field/custom_field.py | 10 +++++----- frappe/core/doctype/customize_form/customize_form.py | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/frappe/core/doctype/custom_field/custom_field.py b/frappe/core/doctype/custom_field/custom_field.py index 852786f914..a0e27b5953 100644 --- a/frappe/core/doctype/custom_field/custom_field.py +++ b/frappe/core/doctype/custom_field/custom_field.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import frappe -from frappe.utils import cint, cstr +from frappe.utils import cstr from frappe import _ from frappe.model.document import Document @@ -30,12 +30,12 @@ class CustomField(Document): frappe.throw(_("Fieldname not set for Custom Field")) def on_update(self): - # validate field - from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype - frappe.clear_cache(doctype=self.dt) - validate_fields_for_doctype(self.dt) + if not self.ignore_validate: + # validate field + from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype + validate_fields_for_doctype(self.dt) # create property setter to emulate insert after self.create_property_setter() diff --git a/frappe/core/doctype/customize_form/customize_form.py b/frappe/core/doctype/customize_form/customize_form.py index e65023400e..0f92b0c996 100644 --- a/frappe/core/doctype/customize_form/customize_form.py +++ b/frappe/core/doctype/customize_form/customize_form.py @@ -167,6 +167,7 @@ class CustomizeForm(Document): changed = True if changed: + custom_field.ignore_validate = True custom_field.save() def delete_custom_fields(self): From c3406b8d5a3748c5b2d14d823fd22317451c1008 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 7 Nov 2014 17:03:35 +0530 Subject: [PATCH 10/13] Allowed precision upto 9 for Float, Currency, Percent fieldtype --- frappe/core/doctype/customize_form/customize_form.py | 10 ++++++---- frappe/model/db_schema.py | 12 +++++++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/frappe/core/doctype/customize_form/customize_form.py b/frappe/core/doctype/customize_form/customize_form.py index 0f92b0c996..be80515f9c 100644 --- a/frappe/core/doctype/customize_form/customize_form.py +++ b/frappe/core/doctype/customize_form/customize_form.py @@ -104,6 +104,7 @@ class CustomizeForm(Document): self.make_property_setter(property=property, value=self.get(property), property_type=self.doctype_properties[property]) + update_db = False for df in self.get("customize_form_fields"): if df.get("__islocal"): continue @@ -125,14 +126,15 @@ class CustomizeForm(Document): elif property == "precision" and cint(df.get("precision")) > 6 \ and cint(df.get("precision")) > cint(meta_df[0].get("precision")): - from frappe.model.db_schema import get_definition - frappe.db.sql_ddl("alter table `tab{table}` modify {col_name} {col_def}"\ - .format(table=self.doc_type, col_name=df.fieldname, - col_def=get_definition(df.fieldtype, df.precision))) + update_db = True self.make_property_setter(property=property, value=df.get(property), property_type=self.docfield_properties[property], fieldname=df.fieldname) + if update_db: + from frappe.model.db_schema import updatedb + updatedb(self.doc_type) + def update_custom_fields(self): for df in self.get("customize_form_fields"): if df.get("__islocal"): diff --git a/frappe/model/db_schema.py b/frappe/model/db_schema.py index 9b79620451..0c091d9cec 100644 --- a/frappe/model/db_schema.py +++ b/frappe/model/db_schema.py @@ -104,10 +104,16 @@ class DbTable: if e.args[0]!=1146: # ignore no custom field raise + # get precision from property setters + precisions = {} + for ps in frappe.get_all("Property Setter", fields=["field_name", "value"], + filters={"doc_type": self.doctype, "doctype_or_field": "DocField", "property": "precision"}): + precisions[ps.field_name] = ps.value + for f in fl: self.columns[f['fieldname']] = DbColumn(self, f['fieldname'], - f['fieldtype'], f.get('length'), f.get('default'), - f.get('search_index'), f.get('options'), f.get('precision')) + f['fieldtype'], f.get('length'), f.get('default'), f.get('search_index'), + f.get('options'), precisions.get(f['fieldname']) or f.get('precision')) def get_columns_from_db(self): self.show_columns = frappe.db.sql("desc `%s`" % self.name) @@ -417,7 +423,7 @@ def get_definition(fieldtype, precision=None): if d[1]: length = d[1] if fieldtype in ["Float", "Currency", "Percent"] and cint(precision) > 6: - length = '18,{0}'.format(precision) + length = '18,9' ret += '(' + length + ')' return ret From dea587bcadaa92d9ca52d965532d254d26b468c9 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 7 Nov 2014 17:57:48 +0530 Subject: [PATCH 11/13] check property setter and custom field only called after install --- frappe/core/doctype/custom_field/custom_field.py | 2 +- frappe/model/db_schema.py | 15 ++++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/frappe/core/doctype/custom_field/custom_field.py b/frappe/core/doctype/custom_field/custom_field.py index a0e27b5953..4f164f83ae 100644 --- a/frappe/core/doctype/custom_field/custom_field.py +++ b/frappe/core/doctype/custom_field/custom_field.py @@ -32,7 +32,7 @@ class CustomField(Document): def on_update(self): frappe.clear_cache(doctype=self.dt) - if not self.ignore_validate: + if not getattr(self, "ignore_validate", None): # validate field from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype validate_fields_for_doctype(self.dt) diff --git a/frappe/model/db_schema.py b/frappe/model/db_schema.py index 0c091d9cec..5c11f6f742 100644 --- a/frappe/model/db_schema.py +++ b/frappe/model/db_schema.py @@ -94,21 +94,18 @@ class DbTable: get columns from docfields and custom fields """ fl = frappe.db.sql("SELECT * FROM tabDocField WHERE parent = %s", self.doctype, as_dict = 1) + precisions = {} - try: + if not frappe.flags.in_install_app: custom_fl = frappe.db.sql("""\ SELECT * FROM `tabCustom Field` WHERE dt = %s AND docstatus < 2""", (self.doctype,), as_dict=1) if custom_fl: fl += custom_fl - except Exception, e: - if e.args[0]!=1146: # ignore no custom field - raise - # get precision from property setters - precisions = {} - for ps in frappe.get_all("Property Setter", fields=["field_name", "value"], - filters={"doc_type": self.doctype, "doctype_or_field": "DocField", "property": "precision"}): - precisions[ps.field_name] = ps.value + # get precision from property setters + for ps in frappe.get_all("Property Setter", fields=["field_name", "value"], + filters={"doc_type": self.doctype, "doctype_or_field": "DocField", "property": "precision"}): + precisions[ps.field_name] = ps.value for f in fl: self.columns[f['fieldname']] = DbColumn(self, f['fieldname'], From 91679155a142a1dafc58f022aab8b9ccecb0533c Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Sat, 8 Nov 2014 14:52:05 +0530 Subject: [PATCH 12/13] Don't validate fields for doctype for custom fields when called from customize form --- frappe/__init__.py | 3 ++- frappe/core/doctype/custom_field/custom_field.py | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frappe/__init__.py b/frappe/__init__.py index 7ead092a62..9d3e52800e 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -530,7 +530,7 @@ def call(fn, *args, **kwargs): newargs[a] = kwargs.get(a) return fn(*args, **newargs) -def make_property_setter(args, ignore_validate=False): +def make_property_setter(args, ignore_validate=False, validate_fields_for_doctype=True): args = _dict(args) ps = get_doc({ 'doctype': "Property Setter", @@ -543,6 +543,7 @@ def make_property_setter(args, ignore_validate=False): '__islocal': 1 }) ps.ignore_validate = ignore_validate + ps.validate_fields_for_doctype = validate_fields_for_doctype ps.insert() def import_doc(path, ignore_links=False, ignore_insert=False, insert=False): diff --git a/frappe/core/doctype/custom_field/custom_field.py b/frappe/core/doctype/custom_field/custom_field.py index 4f164f83ae..2c2adb92bf 100644 --- a/frappe/core/doctype/custom_field/custom_field.py +++ b/frappe/core/doctype/custom_field/custom_field.py @@ -31,8 +31,7 @@ class CustomField(Document): def on_update(self): frappe.clear_cache(doctype=self.dt) - - if not getattr(self, "ignore_validate", None): + if not getattr(self, "ignore_validate", False): # validate field from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype validate_fields_for_doctype(self.dt) @@ -74,7 +73,7 @@ class CustomField(Document): "fieldname": self.fieldname, "property": "previous_field", "value": self.insert_after - }) + }, validate_fields_for_doctype=False) @frappe.whitelist() def get_fields_label(doctype=None): From 923cff7fe32ac9c2f2738847379bf80803795c96 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Sat, 8 Nov 2014 15:32:05 +0600 Subject: [PATCH 13/13] bumped to version 4.5.3 --- frappe/__version__.py | 2 +- frappe/hooks.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frappe/__version__.py b/frappe/__version__.py index f490a96479..5b43808f60 100644 --- a/frappe/__version__.py +++ b/frappe/__version__.py @@ -1 +1 @@ -__version__ = "4.5.2" +__version__ = "4.5.3" diff --git a/frappe/hooks.py b/frappe/hooks.py index 16230e9e1c..ae5ef2ac71 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -3,7 +3,7 @@ app_title = "Frappe Framework" app_publisher = "Web Notes Technologies Pvt. Ltd." app_description = "Full Stack Web Application Framework in Python" app_icon = "assets/frappe/images/frappe.svg" -app_version = "4.5.2" +app_version = "4.5.3" app_color = "#3498db" app_email = "support@frappe.io" diff --git a/setup.py b/setup.py index 108dec9ddb..3ff6b857a7 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import os -version = "4.5.2" +version = "4.5.3" with open("requirements.txt", "r") as f: install_requires = f.readlines()