@@ -530,7 +530,7 @@ def call(fn, *args, **kwargs): | |||||
newargs[a] = kwargs.get(a) | newargs[a] = kwargs.get(a) | ||||
return fn(*args, **newargs) | 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) | args = _dict(args) | ||||
ps = get_doc({ | ps = get_doc({ | ||||
'doctype': "Property Setter", | 'doctype': "Property Setter", | ||||
@@ -543,6 +543,7 @@ def make_property_setter(args, ignore_validate=False): | |||||
'__islocal': 1 | '__islocal': 1 | ||||
}) | }) | ||||
ps.ignore_validate = ignore_validate | ps.ignore_validate = ignore_validate | ||||
ps.validate_fields_for_doctype = validate_fields_for_doctype | |||||
ps.insert() | ps.insert() | ||||
def import_doc(path, ignore_links=False, ignore_insert=False, insert=False): | def import_doc(path, ignore_links=False, ignore_insert=False, insert=False): | ||||
@@ -1 +1 @@ | |||||
__version__ = "4.5.2" | |||||
__version__ = "4.5.3" |
@@ -68,7 +68,7 @@ | |||||
"fieldname": "precision", | "fieldname": "precision", | ||||
"fieldtype": "Select", | "fieldtype": "Select", | ||||
"label": "Precision", | "label": "Precision", | ||||
"options": "\n1\n2\n3\n4\n5\n6", | |||||
"options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9", | |||||
"permlevel": 0, | "permlevel": 0, | ||||
"precision": "" | "precision": "" | ||||
}, | }, | ||||
@@ -267,7 +267,7 @@ | |||||
], | ], | ||||
"icon": "icon-glass", | "icon": "icon-glass", | ||||
"idx": 1, | "idx": 1, | ||||
"modified": "2014-09-05 07:41:13.076820", | |||||
"modified": "2014-11-07 12:59:28.734894", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Core", | "module": "Core", | ||||
"name": "Custom Field", | "name": "Custom Field", | ||||
@@ -3,7 +3,7 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import frappe | import frappe | ||||
from frappe.utils import cint, cstr | |||||
from frappe.utils import cstr | |||||
from frappe import _ | from frappe import _ | ||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
@@ -30,12 +30,11 @@ class CustomField(Document): | |||||
frappe.throw(_("Fieldname not set for Custom Field")) | frappe.throw(_("Fieldname not set for Custom Field")) | ||||
def on_update(self): | def on_update(self): | ||||
# validate field | |||||
from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype | |||||
frappe.clear_cache(doctype=self.dt) | frappe.clear_cache(doctype=self.dt) | ||||
validate_fields_for_doctype(self.dt) | |||||
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) | |||||
# create property setter to emulate insert after | # create property setter to emulate insert after | ||||
self.create_property_setter() | self.create_property_setter() | ||||
@@ -74,7 +73,7 @@ class CustomField(Document): | |||||
"fieldname": self.fieldname, | "fieldname": self.fieldname, | ||||
"property": "previous_field", | "property": "previous_field", | ||||
"value": self.insert_after | "value": self.insert_after | ||||
}) | |||||
}, validate_fields_for_doctype=False) | |||||
@frappe.whitelist() | @frappe.whitelist() | ||||
def get_fields_label(doctype=None): | def get_fields_label(doctype=None): | ||||
@@ -8,6 +8,7 @@ from __future__ import unicode_literals | |||||
""" | """ | ||||
import frappe, json | import frappe, json | ||||
from frappe import _ | from frappe import _ | ||||
from frappe.utils import cint | |||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype | from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype | ||||
@@ -103,6 +104,7 @@ class CustomizeForm(Document): | |||||
self.make_property_setter(property=property, value=self.get(property), | self.make_property_setter(property=property, value=self.get(property), | ||||
property_type=self.doctype_properties[property]) | property_type=self.doctype_properties[property]) | ||||
update_db = False | |||||
for df in self.get("customize_form_fields"): | for df in self.get("customize_form_fields"): | ||||
if df.get("__islocal"): | if df.get("__islocal"): | ||||
continue | continue | ||||
@@ -122,9 +124,17 @@ class CustomizeForm(Document): | |||||
.format(df.idx)) | .format(df.idx)) | ||||
continue | continue | ||||
elif property == "precision" and cint(df.get("precision")) > 6 \ | |||||
and cint(df.get("precision")) > cint(meta_df[0].get("precision")): | |||||
update_db = True | |||||
self.make_property_setter(property=property, value=df.get(property), | self.make_property_setter(property=property, value=df.get(property), | ||||
property_type=self.docfield_properties[property], fieldname=df.fieldname) | 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): | def update_custom_fields(self): | ||||
for df in self.get("customize_form_fields"): | for df in self.get("customize_form_fields"): | ||||
if df.get("__islocal"): | if df.get("__islocal"): | ||||
@@ -159,6 +169,7 @@ class CustomizeForm(Document): | |||||
changed = True | changed = True | ||||
if changed: | if changed: | ||||
custom_field.ignore_validate = True | |||||
custom_field.save() | custom_field.save() | ||||
def delete_custom_fields(self): | def delete_custom_fields(self): | ||||
@@ -86,7 +86,7 @@ | |||||
"fieldname": "precision", | "fieldname": "precision", | ||||
"fieldtype": "Select", | "fieldtype": "Select", | ||||
"label": "Precision", | "label": "Precision", | ||||
"options": "\n1\n2\n3\n4\n5\n6", | |||||
"options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9", | |||||
"permlevel": 0, | "permlevel": 0, | ||||
"precision": "" | "precision": "" | ||||
}, | }, | ||||
@@ -278,7 +278,7 @@ | |||||
"idx": 1, | "idx": 1, | ||||
"issingle": 0, | "issingle": 0, | ||||
"istable": 1, | "istable": 1, | ||||
"modified": "2014-09-05 07:41:29.641454", | |||||
"modified": "2014-11-07 11:08:52.125289", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Core", | "module": "Core", | ||||
"name": "Customize Form Field", | "name": "Customize Form Field", | ||||
@@ -97,7 +97,7 @@ | |||||
"fieldname": "precision", | "fieldname": "precision", | ||||
"fieldtype": "Select", | "fieldtype": "Select", | ||||
"label": "Precision", | "label": "Precision", | ||||
"options": "\n1\n2\n3\n4\n5\n6", | |||||
"options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9", | |||||
"permlevel": 0, | "permlevel": 0, | ||||
"print_hide": 1 | "print_hide": 1 | ||||
}, | }, | ||||
@@ -314,7 +314,7 @@ | |||||
"in_dialog": 1, | "in_dialog": 1, | ||||
"issingle": 0, | "issingle": 0, | ||||
"istable": 1, | "istable": 1, | ||||
"modified": "2014-09-05 07:41:05.956027", | |||||
"modified": "2014-11-07 11:40:55.281141", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Core", | "module": "Core", | ||||
"name": "DocField", | "name": "DocField", | ||||
@@ -6,13 +6,32 @@ from __future__ import unicode_literals | |||||
import frappe, json, os | import frappe, json, os | ||||
from frappe import _ | from frappe import _ | ||||
import frappe.permissions | import frappe.permissions | ||||
import re | |||||
from frappe.utils.csvutils import UnicodeWriter | from frappe.utils.csvutils import UnicodeWriter | ||||
from frappe.utils import cstr, cint, flt | from frappe.utils import cstr, cint, flt | ||||
from frappe.core.page.data_import_tool.data_import_tool import get_data_keys | from frappe.core.page.data_import_tool.data_import_tool import get_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() | @frappe.whitelist() | ||||
def get_template(doctype=None, parent_doctype=None, all_doctypes="No", with_data="No"): | def get_template(doctype=None, parent_doctype=None, all_doctypes="No", with_data="No"): | ||||
all_doctypes = all_doctypes=="Yes" | 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] | |||||
doctype = doctype[0] | |||||
if not parent_doctype: | if not parent_doctype: | ||||
parent_doctype = doctype | parent_doctype = doctype | ||||
@@ -151,6 +170,28 @@ def get_template(doctype=None, parent_doctype=None, all_doctypes="No", with_data | |||||
# get permitted data only | # get permitted data only | ||||
data = frappe.get_list(doctype, fields=["*"], limit_page_length=None) | data = frappe.get_list(doctype, fields=["*"], limit_page_length=None) | ||||
for doc in data: | 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 | # add main table | ||||
row_group = [] | row_group = [] | ||||
@@ -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) | |||||
@@ -3,7 +3,7 @@ app_title = "Frappe Framework" | |||||
app_publisher = "Web Notes Technologies Pvt. Ltd." | app_publisher = "Web Notes Technologies Pvt. Ltd." | ||||
app_description = "Full Stack Web Application Framework in Python" | app_description = "Full Stack Web Application Framework in Python" | ||||
app_icon = "assets/frappe/images/frappe.svg" | app_icon = "assets/frappe/images/frappe.svg" | ||||
app_version = "4.5.2" | |||||
app_version = "4.5.3" | |||||
app_color = "#3498db" | app_color = "#3498db" | ||||
app_email = "support@frappe.io" | app_email = "support@frappe.io" | ||||
@@ -11,7 +11,7 @@ Syncs a database table to the `DocType` (metadata) | |||||
import os | import os | ||||
import frappe | import frappe | ||||
from frappe import _ | from frappe import _ | ||||
from frappe.utils import cstr | |||||
from frappe.utils import cstr, cint | |||||
type_map = { | type_map = { | ||||
'Currency': ('decimal', '18,6') | 'Currency': ('decimal', '18,6') | ||||
@@ -94,20 +94,23 @@ class DbTable: | |||||
get columns from docfields and custom fields | get columns from docfields and custom fields | ||||
""" | """ | ||||
fl = frappe.db.sql("SELECT * FROM tabDocField WHERE parent = %s", self.doctype, as_dict = 1) | 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("""\ | custom_fl = frappe.db.sql("""\ | ||||
SELECT * FROM `tabCustom Field` | SELECT * FROM `tabCustom Field` | ||||
WHERE dt = %s AND docstatus < 2""", (self.doctype,), as_dict=1) | WHERE dt = %s AND docstatus < 2""", (self.doctype,), as_dict=1) | ||||
if custom_fl: fl += custom_fl | if custom_fl: fl += custom_fl | ||||
except Exception, e: | |||||
if e.args[0]!=1146: # ignore no custom field | |||||
raise | |||||
# 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: | for f in fl: | ||||
self.columns[f['fieldname']] = DbColumn(self, f['fieldname'], | self.columns[f['fieldname']] = DbColumn(self, f['fieldname'], | ||||
f['fieldtype'], f.get('length'), f.get('default'), | |||||
f.get('search_index'), f.get('options')) | |||||
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): | def get_columns_from_db(self): | ||||
self.show_columns = frappe.db.sql("desc `%s`" % self.name) | self.show_columns = frappe.db.sql("desc `%s`" % self.name) | ||||
@@ -212,7 +215,7 @@ class DbTable: | |||||
frappe.db.sql("alter table `{}` {}".format(self.name, ", ".join(query))) | frappe.db.sql("alter table `{}` {}".format(self.name, ", ".join(query))) | ||||
class DbColumn: | 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.table = table | ||||
self.fieldname = fieldname | self.fieldname = fieldname | ||||
self.fieldtype = fieldtype | self.fieldtype = fieldtype | ||||
@@ -220,9 +223,10 @@ class DbColumn: | |||||
self.set_index = set_index | self.set_index = set_index | ||||
self.default = default | self.default = default | ||||
self.options = options | self.options = options | ||||
self.precision = precision | |||||
def get_definition(self, with_default=1): | 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) \ | if with_default and self.default and (self.default not in default_shortcuts) \ | ||||
and not self.default.startswith(":") and ret not in ['text', 'longtext']: | and not self.default.startswith(":") and ret not in ['text', 'longtext']: | ||||
@@ -406,7 +410,7 @@ def remove_all_foreign_keys(): | |||||
for f in fklist: | for f in fklist: | ||||
frappe.db.sql("alter table `tab%s` drop foreign key `%s`" % (t[0], f[1])) | 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) | d = type_map.get(fieldtype) | ||||
if not d: | if not d: | ||||
@@ -414,12 +418,16 @@ def get_definition(fieldtype): | |||||
ret = d[0] | ret = d[0] | ||||
if d[1]: | if d[1]: | ||||
ret += '(' + d[1] + ')' | |||||
length = d[1] | |||||
if fieldtype in ["Float", "Currency", "Percent"] and cint(precision) > 6: | |||||
length = '18,9' | |||||
ret += '(' + length + ')' | |||||
return ret | return ret | ||||
def add_column(doctype, column_name, fieldtype): | |||||
def add_column(doctype, column_name, fieldtype, precision=None): | |||||
frappe.db.commit() | frappe.db.commit() | ||||
frappe.db.sql("alter table `tab%s` add column %s %s" % (doctype, | frappe.db.sql("alter table `tab%s` add column %s %s" % (doctype, | ||||
column_name, get_definition(fieldtype))) | |||||
column_name, get_definition(fieldtype, precision))) | |||||
@@ -4,6 +4,7 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import frappe, os | import frappe, os | ||||
from frappe.modules import get_doc_path, load_doctype_module | from frappe.modules import get_doc_path, load_doctype_module | ||||
from jinja2 import Template | |||||
no_cache = 1 | no_cache = 1 | ||||
no_sitemap = 1 | no_sitemap = 1 | ||||
@@ -22,10 +22,12 @@ def sync_fixtures(app=None): | |||||
def export_fixtures(): | def export_fixtures(): | ||||
for app in frappe.get_installed_apps(): | for app in frappe.get_installed_apps(): | ||||
for fixture in frappe.get_hooks("fixtures", app_name=app): | 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")): | if not os.path.exists(frappe.get_app_path(app, "fixtures")): | ||||
os.mkdir(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: | 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")) |
@@ -1,7 +1,7 @@ | |||||
from setuptools import setup, find_packages | from setuptools import setup, find_packages | ||||
import os | import os | ||||
version = "4.5.2" | |||||
version = "4.5.3" | |||||
with open("requirements.txt", "r") as f: | with open("requirements.txt", "r") as f: | ||||
install_requires = f.readlines() | install_requires = f.readlines() | ||||
@@ -2,5 +2,6 @@ | |||||
"db_name": "test_frappe", | "db_name": "test_frappe", | ||||
"db_password": "test_frappe", | "db_password": "test_frappe", | ||||
"admin_password": "admin", | "admin_password": "admin", | ||||
"auto_email_id": "test@example.com", | |||||
"mute_emails": 1 | "mute_emails": 1 | ||||
} | } |