소스 검색

[merge] develop

version-14
Rushabh Mehta 10 년 전
부모
커밋
c3ac0b9113
22개의 변경된 파일697개의 추가작업 그리고 344개의 파일을 삭제
  1. +2
    -1
      frappe/__init__.py
  2. +282
    -282
      frappe/core/doctype/docfield/docfield.json
  3. +41
    -0
      frappe/core/page/data_import_tool/exporter.py
  4. +257
    -0
      frappe/core/page/data_import_tool/test_exporter_fixtures.py
  5. +2
    -2
      frappe/custom/doctype/custom_field/custom_field.json
  6. +6
    -7
      frappe/custom/doctype/custom_field/custom_field.py
  7. +11
    -0
      frappe/custom/doctype/customize_form/customize_form.py
  8. +2
    -2
      frappe/custom/doctype/customize_form_field/customize_form_field.json
  9. +0
    -1
      frappe/hooks.py
  10. +22
    -15
      frappe/model/db_schema.py
  11. BIN
      frappe/public/css/font/notosans-400.ttf
  12. BIN
      frappe/public/css/font/notosans-700.ttf
  13. +17
    -12
      frappe/public/js/frappe/form/control.js
  14. +1
    -1
      frappe/public/js/frappe/misc/datetime.js
  15. +3
    -3
      frappe/public/js/frappe/ui/filters.js
  16. +1
    -0
      frappe/templates/pages/list.py
  17. +12
    -1
      frappe/templates/styles/standard.css
  18. +6
    -4
      frappe/utils/fixtures.py
  19. +1
    -0
      frappe/utils/jinja.py
  20. +29
    -11
      frappe/website/website_generator.py
  21. +0
    -1
      setup.py
  22. +2
    -1
      test_sites/test_site/site_config.json

+ 2
- 1
frappe/__init__.py 파일 보기

@@ -537,7 +537,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",
@@ -550,6 +550,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):


+ 282
- 282
frappe/core/doctype/docfield/docfield.json 파일 보기

@@ -1,331 +1,331 @@
{
"allow_copy": 0,
"autoname": "FL.#####",
"creation": "2013-02-22 01:27:33",
"docstatus": 0,
"doctype": "DocType",
"allow_copy": 0,
"autoname": "FL.#####",
"creation": "2013-02-22 01:27:33",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "label_and_type",
"fieldtype": "Section Break",
"label": "Label and Type",
"fieldname": "label_and_type",
"fieldtype": "Section Break",
"label": "Label and Type",
"permlevel": 0
},
{
"fieldname": "label",
"fieldtype": "Data",
"hidden": 0,
"in_list_view": 1,
"label": "Label",
"oldfieldname": "label",
"oldfieldtype": "Data",
"permlevel": 0,
"print_width": "163",
"reqd": 0,
"search_index": 1,
},
{
"fieldname": "label",
"fieldtype": "Data",
"hidden": 0,
"in_list_view": 1,
"label": "Label",
"oldfieldname": "label",
"oldfieldtype": "Data",
"permlevel": 0,
"print_width": "163",
"reqd": 0,
"search_index": 1,
"width": "163"
},
{
"default": "Data",
"fieldname": "fieldtype",
"fieldtype": "Select",
"hidden": 0,
"in_list_view": 1,
"label": "Type",
"oldfieldname": "fieldtype",
"oldfieldtype": "Select",
"options": "Attach\nButton\nCheck\nCode\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime",
"permlevel": 0,
"reqd": 1,
},
{
"default": "Data",
"fieldname": "fieldtype",
"fieldtype": "Select",
"hidden": 0,
"in_list_view": 1,
"label": "Type",
"oldfieldname": "fieldtype",
"oldfieldtype": "Select",
"options": "Attach\nButton\nCheck\nCode\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime",
"permlevel": 0,
"reqd": 1,
"search_index": 1
},
{
"fieldname": "fieldname",
"fieldtype": "Data",
"hidden": 0,
"in_list_view": 1,
"label": "Name",
"oldfieldname": "fieldname",
"oldfieldtype": "Data",
"permlevel": 0,
"reqd": 0,
},
{
"fieldname": "fieldname",
"fieldtype": "Data",
"hidden": 0,
"in_list_view": 1,
"label": "Name",
"oldfieldname": "fieldname",
"oldfieldtype": "Data",
"permlevel": 0,
"reqd": 0,
"search_index": 1
},
{
"fieldname": "reqd",
"fieldtype": "Check",
"hidden": 0,
"in_list_view": 1,
"label": "Mandatory",
"oldfieldname": "reqd",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
},
{
"fieldname": "reqd",
"fieldtype": "Check",
"hidden": 0,
"in_list_view": 1,
"label": "Mandatory",
"oldfieldname": "reqd",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"fieldname": "search_index",
"fieldtype": "Check",
"hidden": 0,
"label": "Index",
"oldfieldname": "search_index",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
},
{
"fieldname": "search_index",
"fieldtype": "Check",
"hidden": 0,
"label": "Index",
"oldfieldname": "search_index",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
},
{
"fieldname": "unique",
"fieldtype": "Check",
"label": "Unique",
"permlevel": 0,
"fieldname": "unique",
"fieldtype": "Check",
"label": "Unique",
"permlevel": 0,
"precision": ""
},
},
{
"fieldname": "in_list_view",
"fieldtype": "Check",
"label": "In List View",
"permlevel": 0,
"print_width": "70px",
"fieldname": "in_list_view",
"fieldtype": "Check",
"label": "In List View",
"permlevel": 0,
"print_width": "70px",
"width": "70px"
},
},
{
"fieldname": "column_break_6",
"fieldtype": "Column Break",
"fieldname": "column_break_6",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"depends_on": "eval:in_list([\"Float\", \"Currency\", \"Percent\"], doc.fieldtype)",
"description": "Set non-standard precision for a Float or Currency field",
"fieldname": "precision",
"fieldtype": "Select",
"label": "Precision",
"options": "\n1\n2\n3\n4\n5\n6",
"permlevel": 0,
},
{
"depends_on": "eval:in_list([\"Float\", \"Currency\", \"Percent\"], doc.fieldtype)",
"description": "Set non-standard precision for a Float or Currency field",
"fieldname": "precision",
"fieldtype": "Select",
"label": "Precision",
"options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9",
"permlevel": 0,
"print_hide": 1
},
{
"description": "For Links, enter the DocType as range\nFor Select, enter list of Options separated by comma",
"fieldname": "options",
"fieldtype": "Text",
"hidden": 0,
"in_list_view": 1,
"label": "Options",
"oldfieldname": "options",
"oldfieldtype": "Text",
"permlevel": 0,
"reqd": 0,
},
{
"description": "For Links, enter the DocType as range\nFor Select, enter list of Options separated by comma",
"fieldname": "options",
"fieldtype": "Text",
"hidden": 0,
"in_list_view": 1,
"label": "Options",
"oldfieldname": "options",
"oldfieldtype": "Text",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
},
{
"fieldname": "permissions",
"fieldtype": "Section Break",
"label": "Permissions",
"fieldname": "permissions",
"fieldtype": "Section Break",
"label": "Permissions",
"permlevel": 0
},
},
{
"fieldname": "depends_on",
"fieldtype": "Data",
"label": "Depends On",
"oldfieldname": "depends_on",
"oldfieldtype": "Data",
"fieldname": "depends_on",
"fieldtype": "Data",
"label": "Depends On",
"oldfieldname": "depends_on",
"oldfieldtype": "Data",
"permlevel": 0
},
{
"default": "0",
"fieldname": "permlevel",
"fieldtype": "Int",
"hidden": 0,
"label": "Perm Level",
"oldfieldname": "permlevel",
"oldfieldtype": "Int",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
},
{
"default": "0",
"fieldname": "permlevel",
"fieldtype": "Int",
"hidden": 0,
"label": "Perm Level",
"oldfieldname": "permlevel",
"oldfieldtype": "Int",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"fieldname": "hidden",
"fieldtype": "Check",
"hidden": 0,
"label": "Hidden",
"oldfieldname": "hidden",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
},
{
"fieldname": "hidden",
"fieldtype": "Check",
"hidden": 0,
"label": "Hidden",
"oldfieldname": "hidden",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
},
{
"fieldname": "read_only",
"fieldtype": "Check",
"label": "Read Only",
"permlevel": 0,
"print_width": "50px",
"fieldname": "read_only",
"fieldtype": "Check",
"label": "Read Only",
"permlevel": 0,
"print_width": "50px",
"width": "50px"
},
},
{
"description": "Do not allow user to change after set the first time",
"fieldname": "set_only_once",
"fieldtype": "Check",
"label": "Set Only Once",
"description": "Do not allow user to change after set the first time",
"fieldname": "set_only_once",
"fieldtype": "Check",
"label": "Set Only Once",
"permlevel": 0
},
},
{
"fieldname": "column_break_13",
"fieldtype": "Column Break",
"fieldname": "column_break_13",
"fieldtype": "Column Break",
"permlevel": 0
},
},
{
"description": "User permissions should not apply for this Link",
"fieldname": "ignore_user_permissions",
"fieldtype": "Check",
"label": "Ignore User Permissions",
"description": "User permissions should not apply for this Link",
"fieldname": "ignore_user_permissions",
"fieldtype": "Check",
"label": "Ignore User Permissions",
"permlevel": 0
},
{
"fieldname": "allow_on_submit",
"fieldtype": "Check",
"label": "Allow on Submit",
"oldfieldname": "allow_on_submit",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
},
{
"fieldname": "allow_on_submit",
"fieldtype": "Check",
"label": "Allow on Submit",
"oldfieldname": "allow_on_submit",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"width": "50px"
},
{
"fieldname": "report_hide",
"fieldtype": "Check",
"label": "Report Hide",
"oldfieldname": "report_hide",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
},
{
"fieldname": "report_hide",
"fieldtype": "Check",
"label": "Report Hide",
"oldfieldname": "report_hide",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"width": "50px"
},
},
{
"fieldname": "display",
"fieldtype": "Section Break",
"label": "Display",
"fieldname": "display",
"fieldtype": "Section Break",
"label": "Display",
"permlevel": 0
},
{
"fieldname": "default",
"fieldtype": "Text",
"hidden": 0,
"label": "Default",
"oldfieldname": "default",
"oldfieldtype": "Text",
"permlevel": 0,
"reqd": 0,
},
{
"fieldname": "default",
"fieldtype": "Text",
"hidden": 0,
"label": "Default",
"oldfieldname": "default",
"oldfieldtype": "Text",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "in_filter",
"fieldtype": "Check",
"label": "In Filter",
"oldfieldname": "in_filter",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
},
{
"fieldname": "in_filter",
"fieldtype": "Check",
"label": "In Filter",
"oldfieldname": "in_filter",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"width": "50px"
},
{
"fieldname": "no_copy",
"fieldtype": "Check",
"label": "No Copy",
"oldfieldname": "no_copy",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
},
{
"fieldname": "no_copy",
"fieldtype": "Check",
"label": "No Copy",
"oldfieldname": "no_copy",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"width": "50px"
},
},
{
"fieldname": "column_break_22",
"fieldtype": "Column Break",
"fieldname": "column_break_22",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"fieldname": "description",
"fieldtype": "Text",
"in_list_view": 1,
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Text",
"permlevel": 0,
"print_width": "300px",
},
{
"fieldname": "description",
"fieldtype": "Text",
"in_list_view": 1,
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Text",
"permlevel": 0,
"print_width": "300px",
"width": "300px"
},
{
"fieldname": "print_hide",
"fieldtype": "Check",
"hidden": 0,
"label": "Print Hide",
"oldfieldname": "print_hide",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
},
{
"fieldname": "print_hide",
"fieldtype": "Check",
"hidden": 0,
"label": "Print Hide",
"oldfieldname": "print_hide",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
},
{
"fieldname": "print_width",
"fieldtype": "Data",
"label": "Print Width",
"fieldname": "print_width",
"fieldtype": "Data",
"label": "Print Width",
"permlevel": 0
},
{
"fieldname": "width",
"fieldtype": "Data",
"hidden": 0,
"label": "Width",
"oldfieldname": "width",
"oldfieldtype": "Data",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
},
{
"fieldname": "width",
"fieldtype": "Data",
"hidden": 0,
"label": "Width",
"oldfieldname": "width",
"oldfieldtype": "Data",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"fieldname": "oldfieldname",
"fieldtype": "Data",
"hidden": 1,
"oldfieldname": "oldfieldname",
"oldfieldtype": "Data",
"permlevel": 0,
"reqd": 0,
},
{
"fieldname": "oldfieldname",
"fieldtype": "Data",
"hidden": 1,
"oldfieldname": "oldfieldname",
"oldfieldtype": "Data",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "oldfieldtype",
"fieldtype": "Data",
"hidden": 1,
"oldfieldname": "oldfieldtype",
"oldfieldtype": "Data",
"permlevel": 0,
"reqd": 0,
},
{
"fieldname": "oldfieldtype",
"fieldtype": "Data",
"hidden": 1,
"oldfieldname": "oldfieldtype",
"oldfieldtype": "Data",
"permlevel": 0,
"reqd": 0,
"search_index": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"in_dialog": 1,
"issingle": 0,
"istable": 1,
"modified": "2014-09-26 05:03:44.822570",
"modified_by": "Administrator",
"module": "Core",
"name": "DocField",
"owner": "Administrator",
"permissions": [],
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"in_dialog": 1,
"issingle": 0,
"istable": 1,
"modified": "2014-11-07 11:40:55.281141",
"modified_by": "Administrator",
"module": "Core",
"name": "DocField",
"owner": "Administrator",
"permissions": [],
"read_only": 0
}
}

+ 41
- 0
frappe/core/page/data_import_tool/exporter.py 파일 보기

@@ -6,13 +6,32 @@ from __future__ import unicode_literals
import frappe, json, os
from frappe import _
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 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()
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]
doctype = doctype[0]
if not parent_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
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 = []



+ 257
- 0
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)

+ 2
- 2
frappe/custom/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": ""
},
@@ -274,7 +274,7 @@
],
"icon": "icon-glass",
"idx": 1,
"modified": "2014-09-26 05:04:49.148737",
"modified": "2014-09-26 05:04:49.148738",
"modified_by": "Administrator",
"module": "Custom",
"name": "Custom Field",


+ 6
- 7
frappe/custom/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,11 @@ 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 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
self.create_property_setter()
@@ -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):


+ 11
- 0
frappe/custom/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

@@ -104,6 +105,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
@@ -123,9 +125,17 @@ 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")):
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"):
@@ -160,6 +170,7 @@ class CustomizeForm(Document):
changed = True

if changed:
custom_field.ignore_validate = True
custom_field.save()

def delete_custom_fields(self):


+ 2
- 2
frappe/custom/doctype/customize_form_field/customize_form_field.json 파일 보기

@@ -93,7 +93,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": ""
},
@@ -285,7 +285,7 @@
"idx": 1,
"issingle": 0,
"istable": 1,
"modified": "2014-09-26 05:06:37.372435",
"modified": "2014-09-26 05:06:37.372436",
"modified_by": "Administrator",
"module": "Custom",
"name": "Customize Form Field",


+ 0
- 1
frappe/hooks.py 파일 보기

@@ -4,7 +4,6 @@ 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 = "5.0.0-alpha"

app_color = "#3498db"
app_email = "support@frappe.io"



+ 22
- 15
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')
@@ -134,20 +134,23 @@ 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
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('unique'))
f['fieldtype'], f.get('length'), f.get('default'), f.get('search_index'),
f.get('options'), f.get('unique'), precisions.get(f['fieldname']) or f.get('precision'))

def get_columns_from_db(self):
self.show_columns = frappe.db.sql("desc `%s`" % self.name)
@@ -229,7 +232,7 @@ class DbTable:

class DbColumn:
def __init__(self, table, fieldname, fieldtype, length, default,
set_index, options, unique):
set_index, options, unique, precision):
self.table = table
self.fieldname = fieldname
self.fieldtype = fieldtype
@@ -238,9 +241,10 @@ class DbColumn:
self.default = default
self.options = options
self.unique = unique
self.precision = precision

def get_definition(self):
column_def = get_definition(self.fieldtype)
def get_definition(self, with_default=1):
column_def = get_definition(self.fieldtype, self.precision)

if self.default and (self.default not in default_shortcuts) \
and not self.default.startswith(":") and column_def not in ['text', 'longtext']:
@@ -418,7 +422,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:
@@ -426,12 +430,15 @@ 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,9'
ret += '(' + length + ')'

return ret

def add_column(doctype, column_name, fieldtype):
"""Add a column to the database"""
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)))


BIN
frappe/public/css/font/notosans-400.ttf 파일 보기


BIN
frappe/public/css/font/notosans-700.ttf 파일 보기


+ 17
- 12
frappe/public/js/frappe/form/control.js 파일 보기

@@ -229,19 +229,21 @@ frappe.ui.form.ControlInput = frappe.ui.form.Control.extend({
} else {
// inline
var value = me.get_value();
if(me.parse) {
value = me.parse(value);
var parsed = me.parse ? me.parse(value) : value;
var set_input = function(before, after) {
if(before !== after) {
me.set_input(after);
} else {
me.set_mandatory && me.set_mandatory(before);
}
}
if(me.validate) {
me.validate(value, function(value1) {
if(value !== value1) {
me.set_input(value1)
} else {
me.set_mandatory && me.set_mandatory(value);
}
me.validate(parsed, function(validated) {
set_input(value, validated);
});
} else {
me.set_mandatory && me.set_mandatory(value);
set_input(value, parsed);

}
}
});
@@ -380,14 +382,17 @@ frappe.ui.form.ControlInt = frappe.ui.form.ControlData.extend({
return false;
})
},
parse: function(value) {
return cint(value, null);
},
validate: function(value, callback) {
return callback(cint(value, null));
return callback(value);
}
});

frappe.ui.form.ControlFloat = frappe.ui.form.ControlInt.extend({
validate: function(value, callback) {
return callback(isNaN(parseFloat(value)) ? null : flt(value));
parse: function(value) {
return isNaN(parseFloat(value)) ? null : flt(value);
},
format_for_input: function(value) {
var number_format;


+ 1
- 1
frappe/public/js/frappe/misc/datetime.js 파일 보기

@@ -9,7 +9,7 @@ frappe.provide("frappe.datetime");

$.extend(frappe.datetime, {
str_to_obj: function(d) {
return moment(d)._d;
return moment(d, "YYYY-MM-DD HH:mm:ss")._d;
},

obj_to_str: function(d) {


+ 3
- 3
frappe/public/js/frappe/ui/filters.js 파일 보기

@@ -365,12 +365,12 @@ frappe.ui.Filter = Class.extend({

if(this.field.df.fieldname==="docstatus") {
value = {0:"Draft", 1:"Submitted", 2:"Cancelled"}[value] || value;
}

if(this.field.df.original_type==="Check") {
} else if(this.field.df.original_type==="Check") {
value = {0:"No", 1:"Yes"}[cint(value)];
} else if (in_list(["Date", "Datetime"], this.field.df.fieldtype)) {
value = frappe.datetime.str_to_user(value);
} else {
value = this.field.get_value();
}

this.$btn_group.find(".toggle-filter")


+ 1
- 0
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


+ 12
- 1
frappe/templates/styles/standard.css 파일 보기

@@ -1,4 +1,15 @@
@import url(https://fonts.googleapis.com/css?family=Noto+Sans:400,700);
@font-face {
font-family: 'Noto Sans';
font-style: normal;
font-weight: 400;
src: local('Noto Sans'), local('NotoSans'), url({{ frappe.get_url("/assets/frappe/css/font/notosans-400.ttf") }}) format('truetype');
}
@font-face {
font-family: 'Noto Sans';
font-style: normal;
font-weight: 700;
src: local('Noto Sans Bold'), local('NotoSans-Bold'), url({{ frappe.get_url("/assets/frappe/css/font/notosans-700.ttf")}}) format('truetype');
}

@media screen {
.print-format-gutter {


+ 6
- 4
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"))

+ 1
- 0
frappe/utils/jinja.py 파일 보기

@@ -47,6 +47,7 @@ def get_allowed_functions_for_jenv():
# make available limited methods of frappe
"frappe": {
"_": frappe._,
"get_url": frappe.utils.get_url,
"format_value": frappe.format_value,
"format_date": frappe.utils.data.global_date_format,
"form_dict": frappe.local.form_dict,


+ 29
- 11
frappe/website/website_generator.py 파일 보기

@@ -3,6 +3,7 @@

from __future__ import unicode_literals
import frappe
from frappe.utils import now
from frappe.model.document import Document
from frappe.model.naming import append_number_if_name_exists
from frappe.website.utils import cleanup_page_name, get_home_page
@@ -26,9 +27,16 @@ class WebsiteGenerator(Document):

def validate(self):
self.set_parent_website_route()
if self.website_published() and self.meta.get_field("page_name") and not self.page_name:
self.page_name = self.get_page_name()
self.update_routes_of_descendants()

if self.meta.get_field("page_name") and not self.get("__islocal"):
current_route = self.get_route()
current_page_name = self.page_name

self.page_name = self.make_page_name()

# page name changed, rename everything
if current_page_name and current_page_name != self.page_name:
self.update_routes_of_descendants(current_route)

def on_update(self):
clear_cache(self.get_route())
@@ -36,9 +44,6 @@ class WebsiteGenerator(Document):
frappe.add_version(self)

def get_route(self, doc = None):
if not self.website_published():
return None

self.get_page_name()
return make_route(self)

@@ -51,11 +56,14 @@ class WebsiteGenerator(Document):
def get_or_make_page_name(self):
page_name = self.get("page_name")
if not page_name:
page_name = cleanup_page_name(self.get(self.page_title_field))
page_name = self.make_page_name()
self.set("page_name", page_name)

return page_name

def make_page_name(self):
return cleanup_page_name(self.get(self.page_title_field))

def before_rename(self, oldname, name, merge):
self._local = self.get_route()
self.clear_cache()
@@ -88,10 +96,20 @@ class WebsiteGenerator(Document):
old_route = frappe.get_doc(self.doctype, self.name).get_route()

if old_route and old_route != self.get_route():
frappe.db.sql("""update `tab{0}` set
parent_website_route = replace(parent_website_route, %s, %s)
where parent_website_route like %s""".format(self.doctype),
(old_route, self.get_route(), old_route + "%"))
# clear cache of old routes
old_routes = frappe.get_all(self.doctype, fields=["parent_website_route", "page_name"],
filters={"parent_website_route": ("like", old_route + "%")})

if old_routes:
for old_route in old_routes:
clear_cache(old_route)

frappe.db.sql("""update `tab{0}` set
parent_website_route = replace(parent_website_route, %s, %s),
modified = %s
modified_by = %s
where parent_website_route like %s""".format(self.doctype),
(old_route, self.get_route(), now(), frappe.session.user, old_route + "%"))

def get_website_route(self):
route = frappe._dict()


+ 0
- 1
setup.py 파일 보기

@@ -1,5 +1,4 @@
from setuptools import setup, find_packages
import os

version = "5.0.0-alpha"



+ 2
- 1
test_sites/test_site/site_config.json 파일 보기

@@ -5,5 +5,6 @@
"mail_server": "smtp.example.com",
"mail_login": "test@example.com",
"mail_password": "test",
"admin_password": "admin"
"admin_password": "admin",
"mute_emails": 1
}

불러오는 중...
취소
저장