diff --git a/frappe/__version__.py b/frappe/__version__.py
index 3ef413303b..284940332b 100644
--- a/frappe/__version__.py
+++ b/frappe/__version__.py
@@ -1,2 +1,2 @@
from __future__ import unicode_literals
-__version__ = "5.1.3"
+__version__ = "5.1.4"
diff --git a/frappe/commands.py b/frappe/commands.py
index 1d7ae3aff8..4f5c316af6 100644
--- a/frappe/commands.py
+++ b/frappe/commands.py
@@ -4,7 +4,6 @@
from __future__ import unicode_literals, absolute_import
import sys
import os
-import subprocess
import json
import click
import hashlib
@@ -140,7 +139,7 @@ def reinstall(context):
frappe.clear_cache()
installed = frappe.get_installed_apps()
frappe.clear_cache()
- except Exception, e:
+ except Exception:
installed = []
finally:
if frappe.db:
@@ -191,8 +190,6 @@ def migrate(context, rebuild_website=False):
import frappe.translate
from frappe.desk.notifications import clear_notifications
- verbose = context.verbose
-
for site in context.sites:
print 'Migrating', site
frappe.init(site=site)
@@ -312,15 +309,16 @@ def destroy_all_sessions(context):
frappe.destroy()
@click.command('sync-www')
+@click.option('--force', help='Rebuild all pages', is_flag=True, default=False)
@pass_context
-def sync_www(context):
+def sync_www(context, force=False):
"Sync files from static pages from www directory to Web Pages"
from frappe.website import statics
for site in context.sites:
try:
frappe.init(site=site)
frappe.connect()
- statics.sync_statics(rebuild=context.force)
+ statics.sync_statics(rebuild=force)
frappe.db.commit()
finally:
frappe.destroy()
@@ -341,32 +339,17 @@ def build_website(context):
frappe.destroy()
@click.command('setup-docs')
-@click.argument('app')
-@click.argument('docs-app')
-@click.argument('path')
@pass_context
-def setup_docs(context,app, docs_app, path):
+def setup_docs(context):
"Setup docs in target folder of target app"
from frappe.utils.setup_docs import setup_docs
+ from frappe.website import statics
for site in context.sites:
try:
frappe.init(site=site)
frappe.connect()
- setup_docs(app, docs_app, path)
- finally:
- frappe.destroy()
-
-@click.command('build-docs')
-@click.argument('app')
-@pass_context
-def build_docs(context, app):
- "Build docs from /src to /www folder in app"
- from frappe.utils.autodoc import build
- frappe.destroy()
- for site in context.sites:
- try:
- frappe.init(site=site)
- build(app)
+ setup_docs()
+ statics.sync_statics(rebuild=True)
finally:
frappe.destroy()
@@ -826,7 +809,6 @@ commands = [
sync_www,
build_website,
setup_docs,
- build_docs,
reset_perms,
execute,
celery,
diff --git a/frappe/core/doctype/comment/comment.py b/frappe/core/doctype/comment/comment.py
index fa2c8cb37e..eba36506be 100644
--- a/frappe/core/doctype/comment/comment.py
+++ b/frappe/core/doctype/comment/comment.py
@@ -11,7 +11,6 @@ from frappe.utils import get_fullname
class Comment(Document):
"""Comments are added to Documents via forms or views like blogs etc."""
- __doclink__ = "https://frappe.io/docs/models/core/comment"
no_feed_on_delete = True
def get_feed(self):
@@ -134,4 +133,3 @@ def on_doctype_update():
frappe.db.commit()
frappe.db.sql("""alter table `tabComment`
add index comment_doctype_docname_index(comment_doctype, comment_docname)""")
-
diff --git a/frappe/core/doctype/docfield/docfield.py b/frappe/core/doctype/docfield/docfield.py
index 9dae3aea53..6b53be3288 100644
--- a/frappe/core/doctype/docfield/docfield.py
+++ b/frappe/core/doctype/docfield/docfield.py
@@ -6,5 +6,4 @@ from __future__ import unicode_literals
from frappe.model.document import Document
class DocField(Document):
- __doclink__ = "https://frappe.io/docs/models/core/docfield"
pass
diff --git a/frappe/core/doctype/docperm/docperm.json b/frappe/core/doctype/docperm/docperm.json
index 04f8b0c19e..971f50911e 100644
--- a/frappe/core/doctype/docperm/docperm.json
+++ b/frappe/core/doctype/docperm/docperm.json
@@ -33,6 +33,14 @@
"label": "Apply User Permissions",
"permlevel": 0
},
+ {
+ "description": "Apply this rule if the User is the Owner",
+ "fieldname": "if_owner",
+ "fieldtype": "Check",
+ "label": "If user is the owner",
+ "permlevel": 0,
+ "precision": ""
+ },
{
"fieldname": "column_break_2",
"fieldtype": "Column Break",
@@ -232,7 +240,7 @@
"idx": 1,
"issingle": 0,
"istable": 1,
- "modified": "2015-03-18 06:09:58.928014",
+ "modified": "2015-07-22 07:39:40.471092",
"modified_by": "Administrator",
"module": "Core",
"name": "DocPerm",
diff --git a/frappe/core/doctype/docperm/docperm.py b/frappe/core/doctype/docperm/docperm.py
index 919ed1179e..36ed9acbe6 100644
--- a/frappe/core/doctype/docperm/docperm.py
+++ b/frappe/core/doctype/docperm/docperm.py
@@ -7,5 +7,4 @@ import frappe
from frappe.model.document import Document
class DocPerm(Document):
- __doclink__ = "https://frappe.io/docs/models/v5.x/core/docperm"
pass
diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py
index 170fc72989..c0145e4bec 100644
--- a/frappe/core/doctype/doctype/doctype.py
+++ b/frappe/core/doctype/doctype/doctype.py
@@ -18,7 +18,6 @@ form_grid_templates = {
}
class DocType(Document):
- __doclink__ = "https://frappe.io/docs/models/core/doctype"
def get_feed(self):
return self.name
@@ -363,14 +362,21 @@ def validate_permissions(doctype, for_remove=False):
def check_double(d):
has_similar = False
+ similar_because_of = ""
for p in permissions:
- if (p.role==d.role and p.permlevel==d.permlevel
- and p.apply_user_permissions==d.apply_user_permissions and p!=d):
- has_similar = True
- break
+ if p.role==d.role and p.permlevel==d.permlevel and p!=d:
+ if p.apply_user_permissions==d.apply_user_permissions:
+ has_similar = True
+ similar_because_of = _("Apply User Permissions")
+ break
+ elif p.if_owner==d.if_owner:
+ similar_because_of = _("If Owner")
+ has_similar = True
+ break
if has_similar:
- frappe.throw(_("{0}: Only one rule allowed with the same Role, Level and Apply User Permissions").format(get_txt(d)))
+ frappe.throw(_("{0}: Only one rule allowed with the same Role, Level and {1}")\
+ .format(get_txt(d), similar_because_of))
def check_level_zero_is_set(d):
if cint(d.permlevel) > 0 and d.role != 'All':
@@ -467,4 +473,3 @@ def init_list(doctype):
doc = frappe.get_meta(doctype)
make_boilerplate("controller_list.js", doc)
make_boilerplate("controller_list.html", doc)
-
diff --git a/frappe/core/doctype/module_def/module_def.py b/frappe/core/doctype/module_def/module_def.py
index 75b7e14825..44df59cb52 100644
--- a/frappe/core/doctype/module_def/module_def.py
+++ b/frappe/core/doctype/module_def/module_def.py
@@ -7,7 +7,6 @@ import frappe, os
from frappe.model.document import Document
class ModuleDef(Document):
- __doclink__ = "https://frappe.io/docs/models/core/module_def"
def on_update(self):
"""If in `developer_mode`, create folder for module and
add in `modules.txt` of app if missing."""
@@ -39,7 +38,3 @@ class ModuleDef(Document):
frappe.clear_cache()
frappe.setup_module_map()
-
-
-
-
diff --git a/frappe/core/doctype/page/page.py b/frappe/core/doctype/page/page.py
index fef48e2f0b..9c4059d792 100644
--- a/frappe/core/doctype/page/page.py
+++ b/frappe/core/doctype/page/page.py
@@ -5,6 +5,7 @@ from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from frappe.build import html_to_js_template
+from frappe import conf
class Page(Document):
def autoname(self):
@@ -36,7 +37,6 @@ class Page(Document):
Writes the .txt for this page and if write_content is checked,
it will write out a .html file
"""
- from frappe import conf
from frappe.core.doctype.doctype.doctype import make_module_and_roles
make_module_and_roles(self, "roles")
diff --git a/frappe/core/doctype/user/user.json b/frappe/core/doctype/user/user.json
index 51fc55df99..e1789d655d 100644
--- a/frappe/core/doctype/user/user.json
+++ b/frappe/core/doctype/user/user.json
@@ -1,519 +1,519 @@
{
- "allow_copy": 0,
- "allow_import": 1,
- "allow_rename": 1,
- "creation": "2014-03-11 14:55:00",
- "description": "Represents a User in the system.",
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Master",
+ "allow_copy": 0,
+ "allow_import": 1,
+ "allow_rename": 1,
+ "creation": "2014-03-11 14:55:00",
+ "description": "Represents a User in the system.",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Master",
"fields": [
{
- "fieldname": "sb0_5",
- "fieldtype": "Section Break",
- "label": "",
+ "fieldname": "sb0_5",
+ "fieldtype": "Section Break",
+ "label": "",
"permlevel": 0
- },
+ },
{
- "default": "1",
- "fieldname": "enabled",
- "fieldtype": "Check",
- "in_list_view": 0,
- "label": "Enabled",
- "no_copy": 0,
- "oldfieldname": "enabled",
- "oldfieldtype": "Check",
- "permlevel": 0,
+ "default": "1",
+ "fieldname": "enabled",
+ "fieldtype": "Check",
+ "in_list_view": 0,
+ "label": "Enabled",
+ "no_copy": 0,
+ "oldfieldname": "enabled",
+ "oldfieldtype": "Check",
+ "permlevel": 0,
"read_only": 1
- },
+ },
{
- "fieldname": "section_break_3",
- "fieldtype": "Section Break",
- "permlevel": 0,
+ "fieldname": "section_break_3",
+ "fieldtype": "Section Break",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "email",
- "fieldtype": "Data",
- "hidden": 0,
- "label": "Email",
- "no_copy": 1,
- "oldfieldname": "email",
- "oldfieldtype": "Data",
- "options": "Email",
- "permlevel": 0,
- "reqd": 1,
+ "fieldname": "email",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "label": "Email",
+ "no_copy": 1,
+ "oldfieldname": "email",
+ "oldfieldtype": "Data",
+ "options": "Email",
+ "permlevel": 0,
+ "reqd": 1,
"search_index": 0
- },
+ },
{
- "fieldname": "first_name",
- "fieldtype": "Data",
- "in_list_view": 0,
- "label": "First Name",
- "no_copy": 0,
- "oldfieldname": "first_name",
- "oldfieldtype": "Data",
- "permlevel": 0,
+ "fieldname": "first_name",
+ "fieldtype": "Data",
+ "in_list_view": 0,
+ "label": "First Name",
+ "no_copy": 0,
+ "oldfieldname": "first_name",
+ "oldfieldtype": "Data",
+ "permlevel": 0,
"reqd": 1
- },
+ },
{
- "fieldname": "middle_name",
- "fieldtype": "Data",
- "label": "Middle Name (Optional)",
- "no_copy": 0,
- "oldfieldname": "middle_name",
- "oldfieldtype": "Data",
+ "fieldname": "middle_name",
+ "fieldtype": "Data",
+ "label": "Middle Name (Optional)",
+ "no_copy": 0,
+ "oldfieldname": "middle_name",
+ "oldfieldtype": "Data",
"permlevel": 0
- },
+ },
{
- "fieldname": "last_name",
- "fieldtype": "Data",
- "in_list_view": 0,
- "label": "Last Name",
- "oldfieldname": "last_name",
- "oldfieldtype": "Data",
+ "fieldname": "last_name",
+ "fieldtype": "Data",
+ "in_list_view": 0,
+ "label": "Last Name",
+ "oldfieldname": "last_name",
+ "oldfieldtype": "Data",
"permlevel": 0
- },
+ },
{
- "default": "1",
- "depends_on": "eval:doc.__islocal",
- "fieldname": "send_welcome_email",
- "fieldtype": "Check",
- "label": "Send Welcome Email",
- "permlevel": 0,
+ "default": "1",
+ "depends_on": "eval:doc.__islocal",
+ "fieldname": "send_welcome_email",
+ "fieldtype": "Check",
+ "label": "Send Welcome Email",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "unsubscribed",
- "fieldtype": "Check",
- "hidden": 1,
- "label": "Unsubscribed",
- "no_copy": 1,
+ "fieldname": "unsubscribed",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "label": "Unsubscribed",
+ "no_copy": 1,
"permlevel": 0
- },
+ },
{
- "fieldname": "column_break0",
- "fieldtype": "Column Break",
- "oldfieldtype": "Column Break",
- "permlevel": 0,
- "print_width": "50%",
+ "fieldname": "column_break0",
+ "fieldtype": "Column Break",
+ "oldfieldtype": "Column Break",
+ "permlevel": 0,
+ "print_width": "50%",
"width": "50%"
- },
+ },
{
- "description": "",
- "fieldname": "language",
- "fieldtype": "Select",
- "label": "Language",
- "options": "Loading...",
+ "description": "",
+ "fieldname": "language",
+ "fieldtype": "Select",
+ "label": "Language",
+ "options": "Loading...",
"permlevel": 0
- },
+ },
{
- "description": "",
- "fieldname": "time_zone",
- "fieldtype": "Select",
- "label": "Timezone",
+ "description": "",
+ "fieldname": "time_zone",
+ "fieldtype": "Select",
+ "label": "Timezone",
"permlevel": 0
- },
+ },
{
- "depends_on": "eval:!doc.__islocal",
- "fieldname": "change_password",
- "fieldtype": "Section Break",
- "label": "",
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "change_password",
+ "fieldtype": "Section Break",
+ "label": "",
"permlevel": 0
- },
+ },
{
- "fieldname": "new_password",
- "fieldtype": "Password",
- "label": "Set New Password",
- "no_copy": 1,
+ "fieldname": "new_password",
+ "fieldtype": "Password",
+ "label": "Set New Password",
+ "no_copy": 1,
"permlevel": 0
- },
+ },
{
- "depends_on": "",
- "fieldname": "send_password_update_notification",
- "fieldtype": "Check",
- "label": "Send Password Update Notification",
- "permlevel": 0,
+ "depends_on": "",
+ "fieldname": "send_password_update_notification",
+ "fieldtype": "Check",
+ "label": "Send Password Update Notification",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "reset_password_key",
- "fieldtype": "Data",
- "hidden": 1,
- "label": "Reset Password Key",
- "no_copy": 1,
- "permlevel": 0,
- "print_hide": 1,
+ "fieldname": "reset_password_key",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "label": "Reset Password Key",
+ "no_copy": 1,
+ "permlevel": 0,
+ "print_hide": 1,
"read_only": 1
- },
+ },
{
- "depends_on": "eval:!doc.__islocal",
- "fieldname": "display_settings",
- "fieldtype": "Section Break",
- "label": "",
+ "depends_on": "eval:!doc.__islocal",
+ "fieldname": "display_settings",
+ "fieldtype": "Section Break",
+ "label": "",
"permlevel": 0
- },
+ },
{
- "description": "Get your globally recognized avatar from Gravatar.com",
- "fieldname": "user_image",
- "fieldtype": "Attach",
- "hidden": 0,
- "label": "User Image",
- "no_copy": 1,
+ "description": "Get your globally recognized avatar from Gravatar.com",
+ "fieldname": "user_image",
+ "fieldtype": "Attach",
+ "hidden": 0,
+ "label": "User Image",
+ "no_copy": 1,
"permlevel": 0
- },
+ },
{
- "fieldname": "cb21",
- "fieldtype": "Column Break",
+ "fieldname": "cb21",
+ "fieldtype": "Column Break",
"permlevel": 0
- },
+ },
{
- "fieldname": "user_image_show",
- "fieldtype": "Image",
- "label": "user_image_show",
- "options": "user_image",
+ "fieldname": "user_image_show",
+ "fieldtype": "Image",
+ "label": "user_image_show",
+ "options": "user_image",
"permlevel": 0
- },
+ },
{
- "fieldname": "email_settings",
- "fieldtype": "Section Break",
- "label": "Email Settings",
- "permlevel": 0,
+ "fieldname": "email_settings",
+ "fieldtype": "Section Break",
+ "label": "Email Settings",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "default": "1",
- "fieldname": "thread_notify",
- "fieldtype": "Check",
- "label": "Send Notifications for Transactions I Follow",
- "permlevel": 0,
+ "default": "1",
+ "fieldname": "thread_notify",
+ "fieldtype": "Check",
+ "label": "Send Notifications for Transactions I Follow",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "email_signature",
- "fieldtype": "Small Text",
- "label": "Email Signature",
- "no_copy": 1,
+ "fieldname": "email_signature",
+ "fieldtype": "Small Text",
+ "label": "Email Signature",
+ "no_copy": 1,
"permlevel": 0
- },
+ },
{
- "fieldname": "background",
- "fieldtype": "Section Break",
- "label": "",
- "permlevel": 0,
+ "fieldname": "background",
+ "fieldtype": "Section Break",
+ "label": "",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "background_image",
- "fieldtype": "Attach",
- "label": "Background Image",
- "permlevel": 0,
+ "fieldname": "background_image",
+ "fieldtype": "Attach",
+ "label": "Background Image",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "background_style",
- "fieldtype": "Select",
- "label": "Background Style",
- "options": "Fill Screen\nTile",
- "permlevel": 0,
+ "fieldname": "background_style",
+ "fieldtype": "Select",
+ "label": "Background Style",
+ "options": "Fill Screen\nTile",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "short_bio",
- "fieldtype": "Section Break",
- "label": "",
+ "fieldname": "short_bio",
+ "fieldtype": "Section Break",
+ "label": "",
"permlevel": 0
- },
+ },
{
- "fieldname": "gender",
- "fieldtype": "Select",
- "label": "Gender",
- "oldfieldname": "gender",
- "oldfieldtype": "Select",
- "options": "\nMale\nFemale\nOther",
- "permlevel": 0,
+ "fieldname": "gender",
+ "fieldtype": "Select",
+ "label": "Gender",
+ "oldfieldname": "gender",
+ "oldfieldtype": "Select",
+ "options": "\nMale\nFemale\nOther",
+ "permlevel": 0,
"search_index": 0
- },
+ },
{
- "fieldname": "birth_date",
- "fieldtype": "Date",
- "label": "Birth Date",
- "no_copy": 1,
- "oldfieldname": "birth_date",
- "oldfieldtype": "Date",
+ "fieldname": "birth_date",
+ "fieldtype": "Date",
+ "label": "Birth Date",
+ "no_copy": 1,
+ "oldfieldname": "birth_date",
+ "oldfieldtype": "Date",
"permlevel": 0
- },
+ },
{
- "fieldname": "location",
- "fieldtype": "Data",
- "label": "Location",
- "no_copy": 1,
+ "fieldname": "location",
+ "fieldtype": "Data",
+ "label": "Location",
+ "no_copy": 1,
"permlevel": 0
- },
+ },
{
- "fieldname": "column_break_22",
- "fieldtype": "Column Break",
+ "fieldname": "column_break_22",
+ "fieldtype": "Column Break",
"permlevel": 0
- },
+ },
{
- "fieldname": "bio",
- "fieldtype": "Small Text",
- "label": "Bio",
- "no_copy": 1,
- "permlevel": 0,
+ "fieldname": "bio",
+ "fieldtype": "Small Text",
+ "label": "Bio",
+ "no_copy": 1,
+ "permlevel": 0,
"set_only_once": 0
- },
+ },
{
- "description": "Check / Uncheck roles assigned to the User. Click on the Role to find out what permissions that Role has.",
- "fieldname": "sb1",
- "fieldtype": "Section Break",
- "label": "Roles",
- "permlevel": 1,
+ "description": "Check / Uncheck roles assigned to the User. Click on the Role to find out what permissions that Role has.",
+ "fieldname": "sb1",
+ "fieldtype": "Section Break",
+ "label": "Roles",
+ "permlevel": 1,
"read_only": 1
- },
+ },
{
- "fieldname": "roles_html",
- "fieldtype": "HTML",
- "label": "Roles HTML",
- "permlevel": 0,
+ "fieldname": "roles_html",
+ "fieldtype": "HTML",
+ "label": "Roles HTML",
+ "permlevel": 0,
"read_only": 1
- },
+ },
{
- "fieldname": "user_roles",
- "fieldtype": "Table",
- "hidden": 1,
- "label": "Roles Assigned",
- "options": "UserRole",
- "permlevel": 1,
- "print_hide": 1,
+ "fieldname": "user_roles",
+ "fieldtype": "Table",
+ "hidden": 1,
+ "label": "Roles Assigned",
+ "options": "UserRole",
+ "permlevel": 1,
+ "print_hide": 1,
"read_only": 1
- },
+ },
{
- "default": "",
- "description": "Uncheck modules to hide from user's desktop",
- "fieldname": "modules_access",
- "fieldtype": "Section Break",
- "label": "Modules Access",
- "permlevel": 1,
+ "default": "",
+ "description": "Uncheck modules to hide from user's desktop",
+ "fieldname": "modules_access",
+ "fieldtype": "Section Break",
+ "label": "Modules Access",
+ "permlevel": 1,
"precision": ""
- },
+ },
{
- "fieldname": "modules_html",
- "fieldtype": "HTML",
- "label": "Modules HTML",
- "permlevel": 1,
+ "fieldname": "modules_html",
+ "fieldtype": "HTML",
+ "label": "Modules HTML",
+ "permlevel": 1,
"precision": ""
- },
+ },
{
- "fieldname": "block_modules",
- "fieldtype": "Table",
- "hidden": 1,
- "label": "Block Modules",
- "options": "Block Module",
- "permlevel": 1,
+ "fieldname": "block_modules",
+ "fieldtype": "Table",
+ "hidden": 1,
+ "label": "Block Modules",
+ "options": "Block Module",
+ "permlevel": 1,
"precision": ""
- },
+ },
{
- "description": "These values will be automatically updated in transactions and also will be useful to restrict permissions for this user on transactions containing these values.",
- "fieldname": "sb2",
- "fieldtype": "Section Break",
- "hidden": 1,
- "label": "Defaults",
- "oldfieldtype": "Column Break",
- "permlevel": 1,
- "print_width": "50%",
- "read_only": 1,
+ "description": "These values will be automatically updated in transactions and also will be useful to restrict permissions for this user on transactions containing these values.",
+ "fieldname": "sb2",
+ "fieldtype": "Section Break",
+ "hidden": 1,
+ "label": "Defaults",
+ "oldfieldtype": "Column Break",
+ "permlevel": 1,
+ "print_width": "50%",
+ "read_only": 1,
"width": "50%"
- },
+ },
{
- "description": "Enter default value fields (keys) and values. If you add multiple values for a field, the first one will be picked. These defaults are also used to set \"match\" permission rules. To see list of fields, go to Customize Form.",
- "fieldname": "defaults",
- "fieldtype": "Table",
- "hidden": 1,
- "label": "User Defaults",
- "no_copy": 1,
- "options": "DefaultValue",
+ "description": "Enter default value fields (keys) and values. If you add multiple values for a field, the first one will be picked. These defaults are also used to set \"match\" permission rules. To see list of fields, go to \"Customize Form\".",
+ "fieldname": "defaults",
+ "fieldtype": "Table",
+ "hidden": 1,
+ "label": "User Defaults",
+ "no_copy": 1,
+ "options": "DefaultValue",
"permlevel": 0
- },
+ },
{
- "fieldname": "sb3",
- "fieldtype": "Section Break",
- "label": "Security Settings",
- "oldfieldtype": "Section Break",
- "permlevel": 0,
+ "fieldname": "sb3",
+ "fieldtype": "Section Break",
+ "label": "Security Settings",
+ "oldfieldtype": "Section Break",
+ "permlevel": 0,
"read_only": 1
- },
+ },
{
- "default": "System User",
- "description": "User Type \"System User\" can access Desktop. \"Website User\" can only be logged into the website and portal pages. ",
- "fieldname": "user_type",
- "fieldtype": "Select",
- "in_list_view": 1,
- "label": "User Type",
- "oldfieldname": "user_type",
- "oldfieldtype": "Select",
- "options": "System User\nWebsite User",
- "permlevel": 0,
- "read_only": 1,
+ "default": "System User",
+ "description": "User Type \"System User\" can access Desktop. \"Website User\" can only be logged into the website and portal pages. ",
+ "fieldname": "user_type",
+ "fieldtype": "Select",
+ "in_list_view": 1,
+ "label": "User Type",
+ "oldfieldname": "user_type",
+ "oldfieldtype": "Select",
+ "options": "System User\nWebsite User",
+ "permlevel": 0,
+ "read_only": 1,
"reqd": 1
- },
+ },
{
- "description": "Allow user to login only after this hour (0-24)",
- "fieldname": "login_after",
- "fieldtype": "Int",
- "label": "Login After",
- "permlevel": 0,
+ "description": "Allow user to login only after this hour (0-24)",
+ "fieldname": "login_after",
+ "fieldtype": "Int",
+ "label": "Login After",
+ "permlevel": 0,
"read_only": 1
- },
+ },
{
- "description": "Allow user to login only before this hour (0-24)",
- "fieldname": "login_before",
- "fieldtype": "Int",
- "label": "Login Before",
- "permlevel": 0,
+ "description": "Allow user to login only before this hour (0-24)",
+ "fieldname": "login_before",
+ "fieldtype": "Int",
+ "label": "Login Before",
+ "permlevel": 0,
"read_only": 1
- },
+ },
{
- "description": "Restrict user from this IP address only. Multiple IP addresses can be added by separating with commas. Also accepts partial IP addresses like (111.111.111)",
- "fieldname": "restrict_ip",
- "fieldtype": "Data",
- "label": "Restrict IP",
- "permlevel": 0,
+ "description": "Restrict user from this IP address only. Multiple IP addresses can be added by separating with commas. Also accepts partial IP addresses like (111.111.111)",
+ "fieldname": "restrict_ip",
+ "fieldtype": "Data",
+ "label": "Restrict IP",
+ "permlevel": 0,
"read_only": 1
- },
+ },
{
- "fieldname": "column_break1",
- "fieldtype": "Column Break",
- "oldfieldtype": "Column Break",
- "permlevel": 0,
- "print_width": "50%",
+ "fieldname": "column_break1",
+ "fieldtype": "Column Break",
+ "oldfieldtype": "Column Break",
+ "permlevel": 0,
+ "print_width": "50%",
"width": "50%"
- },
+ },
{
- "fieldname": "last_login",
- "fieldtype": "Read Only",
- "hidden": 0,
- "label": "Last Login",
- "no_copy": 1,
- "oldfieldname": "last_login",
- "oldfieldtype": "Read Only",
- "permlevel": 0,
- "read_only": 1,
- "reqd": 0,
+ "fieldname": "last_login",
+ "fieldtype": "Read Only",
+ "hidden": 0,
+ "label": "Last Login",
+ "no_copy": 1,
+ "oldfieldname": "last_login",
+ "oldfieldtype": "Read Only",
+ "permlevel": 0,
+ "read_only": 1,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "fieldname": "last_ip",
- "fieldtype": "Read Only",
- "label": "Last IP",
- "no_copy": 1,
- "oldfieldname": "last_ip",
- "oldfieldtype": "Read Only",
- "permlevel": 0,
+ "fieldname": "last_ip",
+ "fieldtype": "Read Only",
+ "label": "Last IP",
+ "no_copy": 1,
+ "oldfieldname": "last_ip",
+ "oldfieldtype": "Read Only",
+ "permlevel": 0,
"read_only": 1
- },
+ },
{
- "description": "Stores the JSON of last known versions of various installed apps. It is used to show release notes.",
- "fieldname": "last_known_versions",
- "fieldtype": "Text",
- "hidden": 1,
- "label": "Last Known Versions",
- "permlevel": 0,
- "precision": "",
+ "description": "Stores the JSON of last known versions of various installed apps. It is used to show release notes.",
+ "fieldname": "last_known_versions",
+ "fieldtype": "Text",
+ "hidden": 1,
+ "label": "Last Known Versions",
+ "permlevel": 0,
+ "precision": "",
"read_only": 1
- },
+ },
{
- "fieldname": "third_party_authentication",
- "fieldtype": "Section Break",
- "label": "Third Party Authentication",
+ "fieldname": "third_party_authentication",
+ "fieldtype": "Section Break",
+ "label": "Third Party Authentication",
"permlevel": 1
- },
+ },
{
- "fieldname": "fb_username",
- "fieldtype": "Data",
- "label": "Facebook Username",
- "no_copy": 1,
- "permlevel": 0,
+ "fieldname": "fb_username",
+ "fieldtype": "Data",
+ "label": "Facebook Username",
+ "no_copy": 1,
+ "permlevel": 0,
"read_only": 1
- },
+ },
{
- "fieldname": "fb_userid",
- "fieldtype": "Data",
- "label": "Facebook User ID",
- "no_copy": 1,
- "permlevel": 0,
+ "fieldname": "fb_userid",
+ "fieldtype": "Data",
+ "label": "Facebook User ID",
+ "no_copy": 1,
+ "permlevel": 0,
"read_only": 1
- },
+ },
{
- "fieldname": "google_userid",
- "fieldtype": "Data",
- "label": "Google User ID",
- "no_copy": 1,
- "permlevel": 0,
+ "fieldname": "google_userid",
+ "fieldtype": "Data",
+ "label": "Google User ID",
+ "no_copy": 1,
+ "permlevel": 0,
"read_only": 1
- },
+ },
{
- "fieldname": "column_break_49",
- "fieldtype": "Column Break",
- "permlevel": 0,
+ "fieldname": "column_break_49",
+ "fieldtype": "Column Break",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "github_userid",
- "fieldtype": "Data",
- "label": "Github User ID",
- "no_copy": 1,
- "permlevel": 0,
+ "fieldname": "github_userid",
+ "fieldtype": "Data",
+ "label": "Github User ID",
+ "no_copy": 1,
+ "permlevel": 0,
"read_only": 1
- },
+ },
{
- "fieldname": "github_username",
- "fieldtype": "Data",
- "label": "Github Username",
- "no_copy": 1,
- "permlevel": 0,
+ "fieldname": "github_username",
+ "fieldtype": "Data",
+ "label": "Github Username",
+ "no_copy": 1,
+ "permlevel": 0,
"read_only": 1
}
- ],
- "hide_heading": 0,
- "hide_toolbar": 0,
- "icon": "icon-user",
- "idx": 1,
- "issingle": 0,
- "istable": 0,
- "max_attachments": 5,
- "modified": "2015-06-01 01:00:32.901851",
- "modified_by": "Administrator",
- "module": "Core",
- "name": "User",
- "owner": "Administrator",
+ ],
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "icon": "icon-user",
+ "idx": 1,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 5,
+ "modified": "2015-07-27 01:00:32.901851",
+ "modified_by": "Administrator",
+ "module": "Core",
+ "name": "User",
+ "owner": "Administrator",
"permissions": [
{
- "create": 1,
- "delete": 1,
- "email": 1,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "System Manager",
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "share": 1,
+ "submit": 0,
"write": 1
- },
+ },
{
- "amend": 0,
- "cancel": 0,
- "create": 0,
- "delete": 0,
- "permlevel": 1,
- "read": 1,
- "report": 1,
- "role": "System Manager",
- "submit": 0,
+ "amend": 0,
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "permlevel": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "submit": 0,
"write": 1
}
- ],
- "read_only": 0,
+ ],
+ "read_only": 0,
"search_fields": "first_name, last_name"
-}
\ No newline at end of file
+}
diff --git a/frappe/core/page/data_import_tool/data_import_tool.py b/frappe/core/page/data_import_tool/data_import_tool.py
index 8c44c7088a..6b3ec60f72 100644
--- a/frappe/core/page/data_import_tool/data_import_tool.py
+++ b/frappe/core/page/data_import_tool/data_import_tool.py
@@ -30,12 +30,13 @@ def get_doctype_options():
doctype = frappe.form_dict['doctype']
return [doctype] + [d.options for d in frappe.get_meta(doctype).get_table_fields()]
-def import_file_by_path(path, ignore_links=False, overwrite=False, submit=False):
+def import_file_by_path(path, ignore_links=False, overwrite=False, submit=False, pre_process=None):
from frappe.utils.csvutils import read_csv_content
from frappe.core.page.data_import_tool.importer import upload
print "Importing " + path
with open(path, "r") as infile:
- upload(rows = read_csv_content(infile.read()), ignore_links=ignore_links, overwrite=overwrite, submit_after_import=submit)
+ upload(rows = read_csv_content(infile.read()), ignore_links=ignore_links, overwrite=overwrite,
+ submit_after_import=submit, pre_process=pre_process)
def export_csv(doctype, path):
from frappe.core.page.data_import_tool.exporter import get_template
@@ -80,7 +81,8 @@ def export_fixture(doctype, app):
export_json(doctype, frappe.get_app_path(app, "fixtures", frappe.scrub(doctype) + ".json"))
-def import_doc(path, overwrite=False, ignore_links=False, ignore_insert=False, insert=False, submit=False):
+def import_doc(path, overwrite=False, ignore_links=False, ignore_insert=False,
+ insert=False, submit=False, pre_process=None):
if os.path.isdir(path):
files = [os.path.join(path, f) for f in os.listdir(path)]
else:
@@ -89,8 +91,8 @@ def import_doc(path, overwrite=False, ignore_links=False, ignore_insert=False, i
for f in files:
if f.endswith(".json"):
frappe.flags.mute_emails = True
- frappe.modules.import_file.import_file_by_path(f, data_import=True, force=True)
+ frappe.modules.import_file.import_file_by_path(f, data_import=True, force=True, pre_process=pre_process)
frappe.flags.mute_emails = False
elif f.endswith(".csv"):
- import_file_by_path(f, ignore_links=ignore_links, overwrite=overwrite, submit=submit)
+ import_file_by_path(f, ignore_links=ignore_links, overwrite=overwrite, submit=submit, pre_process=pre_process)
frappe.db.commit()
diff --git a/frappe/core/page/data_import_tool/importer.py b/frappe/core/page/data_import_tool/importer.py
index 1ad6256b27..f05a7638f4 100644
--- a/frappe/core/page/data_import_tool/importer.py
+++ b/frappe/core/page/data_import_tool/importer.py
@@ -15,7 +15,8 @@ from frappe.utils import cint, cstr, flt
from frappe.core.page.data_import_tool.data_import_tool import get_data_keys
@frappe.whitelist()
-def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, overwrite=None, ignore_links=False):
+def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, overwrite=None,
+ ignore_links=False, pre_process=None):
"""upload data"""
frappe.flags.mute_emails = True
# extra input params
@@ -200,6 +201,9 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False,
doc = None
doc = get_doc(row_idx)
+ if pre_process:
+ pre_process(doc)
+
try:
frappe.local.message_log = []
if parentfield:
diff --git a/frappe/core/page/permission_manager/permission_manager.js b/frappe/core/page/permission_manager/permission_manager.js
index b9264833ff..d2dbe1a6f1 100644
--- a/frappe/core/page/permission_manager/permission_manager.js
+++ b/frappe/core/page/permission_manager/permission_manager.js
@@ -191,6 +191,7 @@ frappe.PermissionEngine = Class.extend({
if (d.permlevel===0) {
me.setup_user_permissions(d, role_cell);
+ me.setup_if_owner(d, role_cell);
}
var cell = me.add_cell(row, d, "permlevel");
@@ -269,6 +270,12 @@ frappe.PermissionEngine = Class.extend({
d.help = "";
},
+ setup_if_owner: function(d, role_cell) {
+ var checkbox = this.add_check(role_cell, d, "if_owner")
+ .removeClass("col-md-4")
+ .css({"margin-top": "15px"});
+ },
+
rights: ["read", "write", "create", "delete", "submit", "cancel", "amend",
"print", "email", "report", "import", "export", "set_user_permissions"],
diff --git a/frappe/core/page/permission_manager/permission_manager.py b/frappe/core/page/permission_manager/permission_manager.py
index 0dfd3f222a..4960e5aacf 100644
--- a/frappe/core/page/permission_manager/permission_manager.py
+++ b/frappe/core/page/permission_manager/permission_manager.py
@@ -19,7 +19,7 @@ def get_roles_and_doctypes():
name not in ('DocType') and
exists(select * from `tabDocField` where parent=dt.name)""")],
"roles": [d[0] for d in frappe.db.sql("""select name from tabRole where name not in
- ('Guest', 'Administrator')""")]
+ ('Administrator')""")]
}
@frappe.whitelist()
diff --git a/frappe/custom/doctype/custom_field/custom_field.js b/frappe/custom/doctype/custom_field/custom_field.js
index 6e154f6520..81c37ec3fc 100644
--- a/frappe/custom/doctype/custom_field/custom_field.js
+++ b/frappe/custom/doctype/custom_field/custom_field.js
@@ -52,7 +52,7 @@ cur_frm.cscript.fieldtype = function(doc, dt, dn) {
__('Name of the Document Type (DocType) you want this field to be linked to. e.g. Customer');
} else if(doc.fieldtype == 'Select') {
cur_frm.fields_dict['options_help'].disp_area.innerHTML =
- __('Options for select. Each option on a new line. e.g.:
Option 1
Option 2
Option 3
');
+ __('Options for select. Each option on a new line.')+' '+__('e.g.:')+'
'+__('Option 1')+'
'+__('Option 2')+'
'+__('Option 3')+'
';
} else if(doc.fieldtype == 'Dynamic Link') {
cur_frm.fields_dict['options_help'].disp_area.innerHTML =
__('Fieldname which will be the DocType for this link field.');
diff --git a/frappe/custom/doctype/customize_form/customize_form.json b/frappe/custom/doctype/customize_form/customize_form.json
index 2334905ac4..8b45d72288 100644
--- a/frappe/custom/doctype/customize_form/customize_form.json
+++ b/frappe/custom/doctype/customize_form/customize_form.json
@@ -1,136 +1,136 @@
{
- "autoname": "DL.####",
- "creation": "2013-01-29 17:55:08",
- "docstatus": 0,
- "doctype": "DocType",
+ "autoname": "DL.####",
+ "creation": "2013-01-29 17:55:08",
+ "docstatus": 0,
+ "doctype": "DocType",
"fields": [
{
- "fieldname": "doc_type",
- "fieldtype": "Link",
- "hidden": 0,
- "in_list_view": 1,
- "label": "Enter Form Type",
- "no_copy": 0,
- "options": "DocType",
- "permlevel": 0,
+ "fieldname": "doc_type",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "in_list_view": 1,
+ "label": "Enter Form Type",
+ "no_copy": 0,
+ "options": "DocType",
+ "permlevel": 0,
"search_index": 0
- },
+ },
{
- "depends_on": "doc_type",
- "fieldname": "properties",
- "fieldtype": "Section Break",
- "label": "",
+ "depends_on": "doc_type",
+ "fieldname": "properties",
+ "fieldtype": "Section Break",
+ "label": "",
"permlevel": 0
- },
+ },
{
- "fieldname": "default_print_format",
- "fieldtype": "Link",
- "in_list_view": 1,
- "label": "Default Print Format",
- "no_copy": 0,
- "options": "Print Format",
- "permlevel": 0,
+ "fieldname": "default_print_format",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Default Print Format",
+ "no_copy": 0,
+ "options": "Print Format",
+ "permlevel": 0,
"search_index": 0
- },
+ },
{
- "description": "Fields separated by comma (,) will be included in the
Search By list of Search dialog box",
- "fieldname": "search_fields",
- "fieldtype": "Data",
- "in_list_view": 1,
- "label": "Search Fields",
- "no_copy": 0,
- "permlevel": 0,
+ "description": "Fields separated by comma (,) will be included in the \"Search By\" list of Search dialog box",
+ "fieldname": "search_fields",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Search Fields",
+ "no_copy": 0,
+ "permlevel": 0,
"search_index": 0
- },
+ },
{
- "fieldname": "column_break_5",
- "fieldtype": "Column Break",
- "permlevel": 0,
+ "fieldname": "column_break_5",
+ "fieldtype": "Column Break",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "depends_on": "",
- "fieldname": "max_attachments",
- "fieldtype": "Int",
- "label": "Max Attachments",
- "no_copy": 0,
- "permlevel": 0,
+ "depends_on": "",
+ "fieldname": "max_attachments",
+ "fieldtype": "Int",
+ "label": "Max Attachments",
+ "no_copy": 0,
+ "permlevel": 0,
"search_index": 0
- },
+ },
{
- "fieldname": "allow_copy",
- "fieldtype": "Check",
- "label": "Hide Copy",
- "no_copy": 0,
- "permlevel": 0,
+ "fieldname": "allow_copy",
+ "fieldtype": "Check",
+ "label": "Hide Copy",
+ "no_copy": 0,
+ "permlevel": 0,
"search_index": 0
- },
+ },
{
- "depends_on": "doc_type",
- "fieldname": "section_break_8",
- "fieldtype": "Section Break",
- "permlevel": 0,
+ "depends_on": "doc_type",
+ "fieldname": "section_break_8",
+ "fieldtype": "Section Break",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "sort_field",
- "fieldtype": "Select",
- "label": "Sort Field",
+ "fieldname": "sort_field",
+ "fieldtype": "Select",
+ "label": "Sort Field",
"permlevel": 0
- },
+ },
{
- "fieldname": "column_break_10",
- "fieldtype": "Column Break",
- "permlevel": 0,
+ "fieldname": "column_break_10",
+ "fieldtype": "Column Break",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "sort_order",
- "fieldtype": "Select",
- "label": "Sort Order",
- "options": "ASC\nDESC",
+ "fieldname": "sort_order",
+ "fieldtype": "Select",
+ "label": "Sort Order",
+ "options": "ASC\nDESC",
"permlevel": 0
- },
+ },
{
- "depends_on": "doc_type",
- "description": "Customize Label, Print Hide, Default etc.",
- "fieldname": "fields_section_break",
- "fieldtype": "Section Break",
- "label": "Fields",
+ "depends_on": "doc_type",
+ "description": "Customize Label, Print Hide, Default etc.",
+ "fieldname": "fields_section_break",
+ "fieldtype": "Section Break",
+ "label": "Fields",
"permlevel": 0
- },
+ },
{
- "fieldname": "fields",
- "fieldtype": "Table",
- "label": "Fields",
- "no_copy": 0,
- "options": "Customize Form Field",
- "permlevel": 0,
+ "fieldname": "fields",
+ "fieldtype": "Table",
+ "label": "Fields",
+ "no_copy": 0,
+ "options": "Customize Form Field",
+ "permlevel": 0,
"search_index": 0
}
- ],
- "hide_toolbar": 1,
- "icon": "icon-glass",
- "idx": 1,
- "issingle": 1,
- "modified": "2015-03-25 06:18:19.010091",
- "modified_by": "Administrator",
- "module": "Custom",
- "name": "Customize Form",
- "owner": "Administrator",
+ ],
+ "hide_toolbar": 1,
+ "icon": "icon-glass",
+ "idx": 1,
+ "issingle": 1,
+ "modified": "2015-07-27 01:00:32.901851",
+ "modified_by": "Administrator",
+ "module": "Custom",
+ "name": "Customize Form",
+ "owner": "Administrator",
"permissions": [
{
- "create": 1,
- "email": 1,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 0,
- "role": "System Manager",
- "share": 1,
- "submit": 0,
+ "create": 1,
+ "email": 1,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 0,
+ "role": "System Manager",
+ "share": 1,
+ "submit": 0,
"write": 1
}
- ],
+ ],
"search_fields": "doc_type"
-}
\ No newline at end of file
+}
diff --git a/frappe/custom/doctype/customize_form_field/customize_form_field.json b/frappe/custom/doctype/customize_form_field/customize_form_field.json
index 539178832d..356fd1d1a0 100644
--- a/frappe/custom/doctype/customize_form_field/customize_form_field.json
+++ b/frappe/custom/doctype/customize_form_field/customize_form_field.json
@@ -1,304 +1,304 @@
{
- "allow_copy": 0,
- "autoname": "hash",
- "creation": "2013-02-22 01:27:32",
- "docstatus": 0,
- "doctype": "DocType",
+ "allow_copy": 0,
+ "autoname": "hash",
+ "creation": "2013-02-22 01:27:32",
+ "docstatus": 0,
+ "doctype": "DocType",
"fields": [
{
- "fieldname": "label_and_type",
- "fieldtype": "Section Break",
- "label": "Label and Type",
- "permlevel": 0,
+ "fieldname": "label_and_type",
+ "fieldtype": "Section Break",
+ "label": "Label and Type",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "label",
- "fieldtype": "Data",
- "hidden": 0,
- "in_list_view": 1,
- "label": "Label",
- "oldfieldname": "label",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "reqd": 0,
+ "fieldname": "label",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "in_list_view": 1,
+ "label": "Label",
+ "oldfieldname": "label",
+ "oldfieldtype": "Data",
+ "permlevel": 0,
+ "print_hide": 0,
+ "reqd": 0,
"search_index": 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,
- "print_hide": 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,
+ "print_hide": 0,
+ "reqd": 1,
"search_index": 1
- },
+ },
{
- "fieldname": "fieldname",
- "fieldtype": "Data",
- "hidden": 0,
- "in_list_view": 1,
- "label": "Name",
- "oldfieldname": "fieldname",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 1,
- "reqd": 0,
+ "fieldname": "fieldname",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "in_list_view": 1,
+ "label": "Name",
+ "oldfieldname": "fieldname",
+ "oldfieldtype": "Data",
+ "permlevel": 0,
+ "print_hide": 0,
+ "read_only": 1,
+ "reqd": 0,
"search_index": 1
- },
+ },
{
- "fieldname": "reqd",
- "fieldtype": "Check",
- "hidden": 0,
- "label": "Mandatory",
- "oldfieldname": "reqd",
- "oldfieldtype": "Check",
- "permlevel": 0,
- "print_hide": 0,
- "print_width": "50px",
- "reqd": 0,
- "search_index": 0,
+ "fieldname": "reqd",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "label": "Mandatory",
+ "oldfieldname": "reqd",
+ "oldfieldtype": "Check",
+ "permlevel": 0,
+ "print_hide": 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",
+ "fieldname": "in_list_view",
+ "fieldtype": "Check",
+ "label": "In List View",
"permlevel": 0
- },
+ },
{
- "fieldname": "column_break_7",
- "fieldtype": "Column Break",
- "permlevel": 0,
+ "fieldname": "column_break_7",
+ "fieldtype": "Column Break",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "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,
+ "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,
"precision": ""
- },
+ },
{
- "description": "For Links, enter the DocType as range.\nFor Select, enter list of Options, each on a new line.",
- "fieldname": "options",
- "fieldtype": "Text",
- "hidden": 0,
- "in_list_view": 1,
- "label": "Options",
- "oldfieldname": "options",
- "oldfieldtype": "Text",
- "permlevel": 0,
- "print_hide": 0,
- "reqd": 0,
+ "description": "For Links, enter the DocType as range.\nFor Select, enter list of Options, each on a new line.",
+ "fieldname": "options",
+ "fieldtype": "Text",
+ "hidden": 0,
+ "in_list_view": 1,
+ "label": "Options",
+ "oldfieldname": "options",
+ "oldfieldtype": "Text",
+ "permlevel": 0,
+ "print_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "fieldname": "permissions",
- "fieldtype": "Section Break",
- "label": "Permissions",
- "permlevel": 0,
+ "fieldname": "permissions",
+ "fieldtype": "Section Break",
+ "label": "Permissions",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "description": "This field will appear only if the fieldname defined here has value OR the rules are true (examples):
\nmyfield\neval:doc.myfield=='My Value'
\neval:doc.age>18",
- "fieldname": "depends_on",
- "fieldtype": "Data",
- "hidden": 0,
- "label": "Depends On",
- "oldfieldname": "depends_on",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
+ "description": "This field will appear only if the fieldname defined here has value OR the rules are true (examples): \nmyfield\neval:doc.myfield=='My Value'\neval:doc.age>18",
+ "fieldname": "depends_on",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "label": "Depends On",
+ "oldfieldname": "depends_on",
+ "oldfieldtype": "Data",
+ "permlevel": 0,
+ "print_hide": 0,
"reqd": 0
- },
+ },
{
- "default": "0",
- "fieldname": "permlevel",
- "fieldtype": "Int",
- "hidden": 0,
- "in_list_view": 1,
- "label": "Perm Level",
- "oldfieldname": "permlevel",
- "oldfieldtype": "Int",
- "permlevel": 0,
- "print_hide": 0,
- "reqd": 0,
+ "default": "0",
+ "fieldname": "permlevel",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "in_list_view": 1,
+ "label": "Perm Level",
+ "oldfieldname": "permlevel",
+ "oldfieldtype": "Int",
+ "permlevel": 0,
+ "print_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "fieldname": "hidden",
- "fieldtype": "Check",
- "hidden": 0,
- "label": "Hidden",
- "oldfieldname": "hidden",
- "oldfieldtype": "Check",
- "permlevel": 0,
- "print_hide": 0,
- "print_width": "50px",
- "reqd": 0,
- "search_index": 0,
+ "fieldname": "hidden",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "label": "Hidden",
+ "oldfieldname": "hidden",
+ "oldfieldtype": "Check",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_width": "50px",
+ "reqd": 0,
+ "search_index": 0,
"width": "50px"
- },
+ },
{
- "fieldname": "column_break_14",
- "fieldtype": "Column Break",
- "permlevel": 0,
+ "fieldname": "column_break_14",
+ "fieldtype": "Column Break",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "ignore_user_permissions",
- "fieldtype": "Check",
- "label": "Ignore User Permissions",
+ "fieldname": "ignore_user_permissions",
+ "fieldtype": "Check",
+ "label": "Ignore User Permissions",
"permlevel": 0
- },
+ },
{
- "fieldname": "allow_on_submit",
- "fieldtype": "Check",
- "hidden": 0,
- "label": "Allow on Submit",
- "oldfieldname": "allow_on_submit",
- "oldfieldtype": "Check",
- "permlevel": 0,
- "print_hide": 0,
+ "fieldname": "allow_on_submit",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "label": "Allow on Submit",
+ "oldfieldname": "allow_on_submit",
+ "oldfieldtype": "Check",
+ "permlevel": 0,
+ "print_hide": 0,
"reqd": 0
- },
+ },
{
- "fieldname": "report_hide",
- "fieldtype": "Check",
- "hidden": 0,
- "label": "Report Hide",
- "oldfieldname": "report_hide",
- "oldfieldtype": "Check",
- "permlevel": 0,
- "print_hide": 0,
+ "fieldname": "report_hide",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "label": "Report Hide",
+ "oldfieldname": "report_hide",
+ "oldfieldtype": "Check",
+ "permlevel": 0,
+ "print_hide": 0,
"reqd": 0
- },
+ },
{
- "fieldname": "display",
- "fieldtype": "Section Break",
- "label": "Display",
- "permlevel": 0,
+ "fieldname": "display",
+ "fieldtype": "Section Break",
+ "label": "Display",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "default",
- "fieldtype": "Text",
- "hidden": 0,
- "label": "Default",
- "oldfieldname": "default",
- "oldfieldtype": "Text",
- "permlevel": 0,
- "print_hide": 0,
- "reqd": 0,
+ "fieldname": "default",
+ "fieldtype": "Text",
+ "hidden": 0,
+ "label": "Default",
+ "oldfieldname": "default",
+ "oldfieldtype": "Text",
+ "permlevel": 0,
+ "print_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "fieldname": "in_filter",
- "fieldtype": "Check",
- "hidden": 0,
- "label": "In Filter",
- "oldfieldname": "in_filter",
- "oldfieldtype": "Check",
- "permlevel": 0,
- "print_hide": 0,
- "print_width": "50px",
- "reqd": 0,
+ "fieldname": "in_filter",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "label": "In Filter",
+ "oldfieldname": "in_filter",
+ "oldfieldtype": "Check",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_width": "50px",
+ "reqd": 0,
"width": "50px"
- },
+ },
{
- "fieldname": "column_break_21",
- "fieldtype": "Column Break",
- "permlevel": 0,
+ "fieldname": "column_break_21",
+ "fieldtype": "Column Break",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "description",
- "fieldtype": "Text",
- "hidden": 0,
- "label": "Description",
- "oldfieldname": "description",
- "oldfieldtype": "Text",
- "permlevel": 0,
- "print_hide": 0,
- "print_width": "300px",
- "reqd": 0,
+ "fieldname": "description",
+ "fieldtype": "Text",
+ "hidden": 0,
+ "label": "Description",
+ "oldfieldname": "description",
+ "oldfieldtype": "Text",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_width": "300px",
+ "reqd": 0,
"width": "300px"
- },
+ },
{
- "fieldname": "print_hide",
- "fieldtype": "Check",
- "hidden": 0,
- "label": "Print Hide",
- "oldfieldname": "print_hide",
- "oldfieldtype": "Check",
- "permlevel": 0,
- "print_hide": 0,
- "reqd": 0,
+ "fieldname": "print_hide",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "label": "Print Hide",
+ "oldfieldname": "print_hide",
+ "oldfieldtype": "Check",
+ "permlevel": 0,
+ "print_hide": 0,
+ "reqd": 0,
"search_index": 0
- },
+ },
{
- "description": "Print Width of the field, if the field is a column in a table",
- "fieldname": "print_width",
- "fieldtype": "Data",
- "label": "Print Width",
- "permlevel": 0,
- "print_width": "50px",
+ "description": "Print Width of the field, if the field is a column in a table",
+ "fieldname": "print_width",
+ "fieldtype": "Data",
+ "label": "Print Width",
+ "permlevel": 0,
+ "print_width": "50px",
"width": "50px"
- },
+ },
{
- "fieldname": "width",
- "fieldtype": "Data",
- "hidden": 0,
- "in_list_view": 1,
- "label": "Width",
- "oldfieldname": "width",
- "oldfieldtype": "Data",
- "permlevel": 0,
- "print_hide": 0,
- "print_width": "50px",
- "reqd": 0,
- "search_index": 0,
+ "fieldname": "width",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "in_list_view": 1,
+ "label": "Width",
+ "oldfieldname": "width",
+ "oldfieldtype": "Data",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_width": "50px",
+ "reqd": 0,
+ "search_index": 0,
"width": "50px"
- },
+ },
{
- "fieldname": "is_custom_field",
- "fieldtype": "Check",
- "hidden": 1,
- "label": "Is Custom Field",
- "permlevel": 0,
- "precision": "",
+ "fieldname": "is_custom_field",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "label": "Is Custom Field",
+ "permlevel": 0,
+ "precision": "",
"read_only": 1
}
- ],
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 1,
- "issingle": 0,
- "istable": 1,
- "modified": "2015-04-24 11:37:52.879004",
- "modified_by": "Administrator",
- "module": "Custom",
- "name": "Customize Form Field",
- "owner": "Administrator",
- "permissions": [],
+ ],
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 1,
+ "issingle": 0,
+ "istable": 1,
+ "modified": "2015-07-27 01:00:32.901851",
+ "modified_by": "Administrator",
+ "module": "Custom",
+ "name": "Customize Form Field",
+ "owner": "Administrator",
+ "permissions": [],
"read_only": 0
-}
\ No newline at end of file
+}
diff --git a/frappe/desk/query_report.py b/frappe/desk/query_report.py
index fe4d59df8d..18416fad6b 100644
--- a/frappe/desk/query_report.py
+++ b/frappe/desk/query_report.py
@@ -11,6 +11,7 @@ from frappe.modules import scrub, get_module_path
from frappe.utils import flt, cint, get_html_format
from frappe.translate import send_translations
import frappe.desk.reportview
+from frappe.permissions import get_role_permissions
def get_report_doc(report_name):
doc = frappe.get_doc("Report", report_name)
@@ -144,20 +145,35 @@ def get_filtered_data(ref_doctype, columns, data):
linked_doctypes = get_linked_doctypes(columns, data)
match_filters_per_doctype = get_user_match_filters(linked_doctypes, ref_doctype)
shared = frappe.share.get_shared(ref_doctype)
+ columns_dict = get_columns_dict(columns)
+
+ role_permissions = get_role_permissions(frappe.get_meta(ref_doctype))
+ if_owner = role_permissions.get("if_owner", {}).get("report")
if match_filters_per_doctype:
for row in data:
if shared and row[linked_doctypes[ref_doctype]] in shared:
result.append(row)
- elif has_match(row, linked_doctypes, match_filters_per_doctype):
+ elif has_match(row, linked_doctypes, match_filters_per_doctype, ref_doctype, if_owner, columns_dict):
result.append(row)
else:
result = list(data)
return result
-def has_match(row, linked_doctypes, doctype_match_filters):
+def has_match(row, linked_doctypes, doctype_match_filters, ref_doctype, if_owner, columns_dict):
+ """Returns True if after evaluating permissions for each linked doctype
+ - There is an owner match for the ref_doctype
+ - `and` There is a user permission match for all linked doctypes
+
+ Returns True if the row is empty
+
+ Note:
+ Each doctype could have multiple conflicting user permission doctypes.
+ Hence even if one of the sets allows a match, it is true.
+ This behavior is equivalent to the trickling of user permissions of linked doctypes to the ref doctype.
+ """
resultant_match = True
if not row:
@@ -167,20 +183,33 @@ def has_match(row, linked_doctypes, doctype_match_filters):
for doctype, filter_list in doctype_match_filters.items():
matched_for_doctype = False
- for match_filters in filter_list:
- match = True
- for dt, idx in linked_doctypes.items():
- if dt in match_filters and row[idx] not in match_filters[dt]:
- match = False
+ if doctype==ref_doctype and if_owner:
+ idx = linked_doctypes.get("User")
+ if (idx is not None
+ and row[idx]==frappe.session.user
+ and columns_dict[idx]==columns_dict.get("owner")):
+ # owner match is true
+ matched_for_doctype = True
+
+ if not matched_for_doctype:
+ for match_filters in filter_list:
+ match = True
+ for dt, idx in linked_doctypes.items():
+ # case handled above
+ if dt=="User" and columns_dict[idx]==columns_dict.get("owner"):
+ continue
+
+ if dt in match_filters and row[idx] not in match_filters[dt]:
+ match = False
+ break
+
+ # each doctype could have multiple conflicting user permission doctypes, hence using OR
+ # so that even if one of the sets allows a match, it is true
+ matched_for_doctype = matched_for_doctype or match
+
+ if matched_for_doctype:
break
- # each doctype could have multiple conflicting user permission doctypes, hence using OR
- # so that even if one of the sets allows a match, it is true
- matched_for_doctype = matched_for_doctype or match
-
- if matched_for_doctype:
- break
-
# each doctype's user permissions should match the row! hence using AND
resultant_match = resultant_match and matched_for_doctype
@@ -192,16 +221,16 @@ def has_match(row, linked_doctypes, doctype_match_filters):
def get_linked_doctypes(columns, data):
linked_doctypes = {}
- for idx, col in enumerate(columns):
- if isinstance(col, basestring):
- col = col.split(":")
- if len(col) > 1 and col[1].startswith("Link"):
- link_dt = col[1].split("/")[1]
- linked_doctypes[link_dt] = idx
+ columns_dict = get_columns_dict(columns)
- # dict
- elif col.get("fieldtype")=="Link" and col.get("options"):
- linked_doctypes[col["options"]] = col["fieldname"]
+ for idx, col in enumerate(columns):
+ df = columns_dict[idx]
+ if df.get("fieldtype")=="Link":
+ if isinstance(col, basestring):
+ linked_doctypes[df["options"]] = idx
+ else:
+ # dict
+ linked_doctypes[df["options"]] = df["fieldname"]
# remove doctype if column is empty
for doctype, key in linked_doctypes.items():
@@ -210,6 +239,35 @@ def get_linked_doctypes(columns, data):
return linked_doctypes
+def get_columns_dict(columns):
+ """Returns a dict with column docfield values as dict
+ The keys for the dict are both idx and fieldname,
+ so either index or fieldname can be used to search for a column's docfield properties
+ """
+ columns_dict = {}
+ for idx, col in enumerate(columns):
+ col_dict = {}
+
+ # string
+ if isinstance(col, basestring):
+ col = col.split(":")
+ if len(col) > 1:
+ if "/" in col[1]:
+ col_dict["fieldtype"], col_dict["options"] = col[1].split("/")
+ else:
+ col_dict["fieldtype"] = col[1]
+
+ col_dict["fieldname"] = col[0].lower()
+
+ # dict
+ else:
+ col_dict.update(col)
+
+ columns_dict[idx] = col_dict
+ columns_dict[col_dict["fieldname"]] = col_dict
+
+ return columns_dict
+
def get_user_match_filters(doctypes, ref_doctype):
match_filters = {}
diff --git a/frappe/email/smtp.py b/frappe/email/smtp.py
index 0fbf693095..714d64423d 100644
--- a/frappe/email/smtp.py
+++ b/frappe/email/smtp.py
@@ -55,7 +55,8 @@ def get_outgoing_email_account(raise_exception_not_set=True, append_to=None):
email_account = get_default_outgoing_email_account(raise_exception_not_set=raise_exception_not_set)
if not email_account and raise_exception_not_set:
- frappe.throw(_("Please setup default Email Account from Setup > Email > Email Account"))
+ frappe.throw(_("Please setup default Email Account from Setup > Email > Email Account"),
+ frappe.OutgoingEmailError)
frappe.local.outgoing_email_account[append_to or "default"] = email_account
diff --git a/frappe/hooks.py b/frappe/hooks.py
index a8efdb5539..eaa9c2512b 100644
--- a/frappe/hooks.py
+++ b/frappe/hooks.py
@@ -2,12 +2,35 @@ from __future__ import unicode_literals
app_name = "frappe"
app_title = "Frappe Framework"
app_publisher = "Frappe Technologies Pvt. Ltd."
-app_description = "Full Stack Web Application Framework in Python"
-app_icon = "octicon octicon-circuit-board"
-app_version = "5.1.3"
-app_color = "orange"
+app_description = """## Frappe Framework
-app_email = "support@frappe.io"
+Frappe is a full stack web application framework written in Python,
+Javascript, HTML/CSS with MySQL as the backend. It was built for ERPNext
+but is pretty generic and can be used to build database driven apps.
+
+The key differece in Frappe compared to other frameworks is that Frappe
+is that meta-data is also treated as data and is used to build front-ends
+very easily. Frappe comes with a full blown admin UI called the **Desk**
+that handles forms, navigation, lists, menus, permissions, file attachment
+and much more out of the box.
+
+Frappe also has a plug-in architecture that can be used to build plugins
+to ERPNext.
+
+### Links:
+
+- Project Home: [https://frappe.io](https://frappe.io)
+- Tutorial: [https://frappe.io/tutorial](https://frappe.io/tutorial)
+- GitHub: [https://github.com/frappe/frappe](https://github.com/frappe/frappe)
+- Forum: [https://discuss.erpnext.com](https://discuss.erpnext.com)
+"""
+
+app_icon = "octicon octicon-circuit-board"
+app_version = "5.1.4"
+app_color = "orange"
+github_link = "https://github.com/frappe/frappe"
+
+app_email = "info@frappe.io"
before_install = "frappe.utils.install.before_install"
after_install = "frappe.utils.install.after_install"
@@ -35,8 +58,7 @@ web_include_js = [
bootstrap = "assets/frappe/css/bootstrap.css"
web_include_css = [
- "assets/css/frappe-web.css",
- "website_theme.css"
+ "assets/css/frappe-web.css"
]
website_route_rules = [
{"from_route": "/blog", "to_route": "Blog Post"},
diff --git a/frappe/model/base_document.py b/frappe/model/base_document.py
index e4fdd72b68..8fddfe3a20 100644
--- a/frappe/model/base_document.py
+++ b/frappe/model/base_document.py
@@ -453,7 +453,7 @@ class BaseDocument(object):
return self._precision[cache_key][fieldname]
- def get_formatted(self, fieldname, doc=None, currency=None):
+ def get_formatted(self, fieldname, doc=None, currency=None, absolute_value=False):
from frappe.utils.formatters import format_value
df = self.meta.get_field(fieldname)
@@ -461,7 +461,10 @@ class BaseDocument(object):
from frappe.model.meta import get_default_df
df = get_default_df(fieldname)
- return format_value(self.get(fieldname), df=df, doc=doc or self, currency=currency)
+ val = self.get(fieldname)
+ if absolute_value and isinstance(val, (int, float)):
+ val = abs(self.get(fieldname))
+ return format_value(val, df=df, doc=doc or self, currency=currency)
def is_print_hide(self, fieldname, df=None, for_print=True):
"""Returns true if fieldname is to be hidden for print.
diff --git a/frappe/model/db_query.py b/frappe/model/db_query.py
index a20c17c43d..a1d21275dd 100644
--- a/frappe/model/db_query.py
+++ b/frappe/model/db_query.py
@@ -294,6 +294,10 @@ class DatabaseQuery(object):
self.add_user_permissions(user_permissions,
user_permission_doctypes=role_permissions.get("user_permission_doctypes").get("read"))
+ if role_permissions.get("if_owner", {}).get("read"):
+ self.match_conditions.append("`tab{0}`.owner = '{1}'".format(self.doctype,
+ frappe.db.escape(frappe.session.user)))
+
if as_condition:
conditions = ""
if self.match_conditions:
diff --git a/frappe/model/naming.py b/frappe/model/naming.py
index 3a7a4a7cb6..c23bd3d633 100644
--- a/frappe/model/naming.py
+++ b/frappe/model/naming.py
@@ -177,7 +177,7 @@ def append_number_if_name_exists(doc):
if frappe.db.exists(doc.doctype, doc.name):
last = frappe.db.sql("""select name from `tab{}`
where name regexp '{}-[[:digit:]]+'
- order by name desc limit 1""".format(doc.doctype, doc.name))
+ order by length(name) desc, name desc limit 1""".format(doc.doctype, doc.name))
if last:
count = str(cint(last[0][0].rsplit("-", 1)[1]) + 1)
diff --git a/frappe/modules/import_file.py b/frappe/modules/import_file.py
index 2ecad22f28..0aea4fd2ca 100644
--- a/frappe/modules/import_file.py
+++ b/frappe/modules/import_file.py
@@ -7,19 +7,19 @@ import frappe, os, json
from frappe.modules import get_module_path, scrub_dt_dn
from frappe.utils import get_datetime_str
-def import_files(module, dt=None, dn=None, force=False):
+def import_files(module, dt=None, dn=None, force=False, pre_process=None):
if type(module) is list:
out = []
for m in module:
- out.append(import_file(m[0], m[1], m[2], force=force))
+ out.append(import_file(m[0], m[1], m[2], force=force, pre_process=pre_process))
return out
else:
- return import_file(module, dt, dn, force=force)
+ return import_file(module, dt, dn, force=force, pre_process=pre_process)
-def import_file(module, dt, dn, force=False):
+def import_file(module, dt, dn, force=False, pre_process=None):
"""Sync a file from txt if modifed, return false if not updated"""
path = get_file_path(module, dt, dn)
- ret = import_file_by_path(path, force)
+ ret = import_file_by_path(path, force, pre_process=pre_process)
return ret
def get_file_path(module, dt, dn):
@@ -30,7 +30,7 @@ def get_file_path(module, dt, dn):
return path
-def import_file_by_path(path, force=False, data_import=False):
+def import_file_by_path(path, force=False, data_import=False, pre_process=None):
frappe.flags.in_import = True
try:
docs = read_doc_from_file(path)
@@ -51,7 +51,7 @@ def import_file_by_path(path, force=False, data_import=False):
original_modified = doc.get("modified")
- import_doc(doc, force=force, data_import=data_import)
+ import_doc(doc, force=force, data_import=data_import, pre_process=pre_process)
if original_modified:
# since there is a new timestamp on the file, update timestamp in
@@ -87,10 +87,12 @@ ignore_values = {
ignore_doctypes = ["Page Role", "DocPerm"]
-def import_doc(docdict, force=False, data_import=False):
+def import_doc(docdict, force=False, data_import=False, pre_process=None):
frappe.flags.in_import = True
docdict["__islocal"] = 1
doc = frappe.get_doc(docdict)
+ if pre_process:
+ pre_process(doc)
ignore = []
diff --git a/frappe/patches.txt b/frappe/patches.txt
index 412650279c..535f0c8feb 100644
--- a/frappe/patches.txt
+++ b/frappe/patches.txt
@@ -2,7 +2,7 @@ execute:frappe.db.sql("""update `tabPatch Log` set patch=replace(patch, '.4_0.',
frappe.patches.v5_0.convert_to_barracuda_and_utf8mb4
execute:frappe.reload_doc('core', 'doctype', 'doctype', force=True) #2014-01-24
execute:frappe.reload_doc('core', 'doctype', 'docfield', force=True) #2015-05-15
-execute:frappe.reload_doc('core', 'doctype', 'docperm') #2014-06-04
+execute:frappe.reload_doc('core', 'doctype', 'docperm') #2014-06-24
execute:frappe.reload_doc('core', 'doctype', 'page') #2013-13-26
execute:frappe.reload_doc('core', 'doctype', 'report') #2014-06-03
execute:frappe.reload_doc('core', 'doctype', 'version') #2014-02-21
diff --git a/frappe/permissions.py b/frappe/permissions.py
index c3183d2cd0..480a2ba2c3 100644
--- a/frappe/permissions.py
+++ b/frappe/permissions.py
@@ -17,7 +17,11 @@ def check_admin_or_system_manager(user=None):
frappe.throw(_("Not permitted"), frappe.PermissionError)
def has_permission(doctype, ptype="read", doc=None, verbose=False, user=None):
- """check if user has permission"""
+ """Returns True if user has permission `ptype` for given `doctype`.
+ If `doc` is passed, it also checks user, share and owner permissions.
+
+ Note: if Table DocType is passed, it always returns True.
+ """
if not user: user = frappe.session.user
if frappe.is_table(doctype):
@@ -65,6 +69,11 @@ def has_permission(doctype, ptype="read", doc=None, verbose=False, user=None):
if isinstance(doc, basestring):
doc = frappe.get_doc(meta.name, doc)
+ # if owner match, then return True
+ if doc.owner == frappe.session.user and role_permissions["if_owner"].get(ptype) and ptype!="create":
+ return True
+
+ # check if user permission
if role_permissions["apply_user_permissions"].get(ptype):
if not user_has_permission(doc, verbose=verbose, user=user,
user_permission_doctypes=role_permissions.get("user_permission_doctypes", {}).get(ptype) or []):
@@ -80,6 +89,7 @@ def has_permission(doctype, ptype="read", doc=None, verbose=False, user=None):
return True
def get_doc_permissions(doc, verbose=False, user=None):
+ """Returns a dict of evaluated permissions for given `doc` like `{"read":1, "write":1}`"""
if not user: user = frappe.session.user
if frappe.is_table(doc.doctype):
@@ -102,23 +112,62 @@ def get_doc_permissions(doc, verbose=False, user=None):
user_permission_doctypes=role_permissions.get("user_permission_doctypes", {}).get(ptype) or []):
role_permissions[ptype] = 0
- # update share permissions
- role_permissions.update(frappe.db.get_value("DocShare",
- {"share_doctype": doc.doctype, "share_name": doc.name, "user": user},
- ["read", "write", "share"], as_dict=True) or {})
+ # apply owner permissions on top of existing permissions
+ if doc.owner == frappe.session.user:
+ role_permissions.update(role_permissions.if_owner)
+
+ update_share_permissions(role_permissions, doc, user)
return role_permissions
+def update_share_permissions(role_permissions, doc, user):
+ """Updates share permissions on `role_permissions` for given doc, if shared"""
+ share_ptypes = ("read", "write", "share")
+ permissions_by_share = frappe.db.get_value("DocShare",
+ {"share_doctype": doc.doctype, "share_name": doc.name, "user": user},
+ share_ptypes, as_dict=True)
+
+ if permissions_by_share:
+ for ptype in share_ptypes:
+ if ptype:
+ role_permissions[ptype] = 1
+
def get_role_permissions(meta, user=None, verbose=False):
+ """Returns dict of evaluated role permissions like `{"read": True, "write":False}`
+
+ If user permissions are applicable, it adds a dict of user permissions like
+
+ {
+ // user permissions will apply on these rights
+ "apply_user_permissions": {"read": 1, "write": 1},
+
+ // doctypes that will be applicable for each right
+ "user_permission_doctypes": {
+ "read": [
+ // AND between "DocType 1" and "DocType 2"
+ ["DocType 1", "DocType 2"],
+
+ // OR
+
+ ["DocType 3"]
+
+ ]
+ }
+
+ "if_owner": {"read": 1, "write": 1}
+ }
+ """
if not user: user = frappe.session.user
cache_key = (meta.name, user)
if not frappe.local.role_permissions.get(cache_key):
- perms = frappe._dict({ "apply_user_permissions": {}, "user_permission_doctypes": {} })
+ perms = frappe._dict({ "apply_user_permissions": {}, "user_permission_doctypes": {}, "if_owner": {} })
user_roles = frappe.get_roles(user)
for p in meta.permissions:
if cint(p.permlevel)==0 and (p.role in user_roles):
+ # apply only for level 0
+
for ptype in rights:
perms[ptype] = perms.get(ptype, 0) or cint(p.get(ptype))
@@ -126,6 +175,10 @@ def get_role_permissions(meta, user=None, verbose=False):
perms["apply_user_permissions"][ptype] = (perms["apply_user_permissions"].get(ptype, 1)
and p.get("apply_user_permissions"))
+ # build if_owner dict if applicable for this right
+ if p.if_owner and p.get(ptype):
+ perms["if_owner"][ptype] = 1
+
if p.apply_user_permissions:
if p.user_permission_doctypes:
# set user_permission_doctypes in perms
diff --git a/frappe/public/css/form.css b/frappe/public/css/form.css
index 7f3d649951..a85f9ae799 100644
--- a/frappe/public/css/form.css
+++ b/frappe/public/css/form.css
@@ -32,6 +32,9 @@
margin: 0px;
padding: 15px;
}
+.form-section .form-section-heading {
+ margin: 25px 0px 15px 0px;
+}
.empty-section {
display: none !important;
}
diff --git a/frappe/public/css/website.css b/frappe/public/css/website.css
index 3608b07b5b..74a50bf87b 100644
--- a/frappe/public/css/website.css
+++ b/frappe/public/css/website.css
@@ -285,6 +285,7 @@ body {
}
.avatar-empty {
border: 1px dashed #d1d8dd;
+ border-radius: 4px;
}
.avatar-small {
margin-right: 5px;
diff --git a/frappe/public/images/favicon.png b/frappe/public/images/favicon.png
index 00d97cb834..62ff240fb2 100644
Binary files a/frappe/public/images/favicon.png and b/frappe/public/images/favicon.png differ
diff --git a/frappe/public/images/frappe.svg b/frappe/public/images/frappe.svg
deleted file mode 100644
index 6b6ea9df2b..0000000000
--- a/frappe/public/images/frappe.svg
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
-
-
diff --git a/frappe/public/js/frappe/form/layout.js b/frappe/public/js/frappe/form/layout.js
index c26269a163..e3c4417057 100644
--- a/frappe/public/js/frappe/form/layout.js
+++ b/frappe/public/js/frappe/form/layout.js
@@ -105,20 +105,6 @@ frappe.ui.form.Layout = Class.extend({
});
},
- make_column: function(df) {
- this.column = $('
| '+__("Make a new record")+' | '+ - __("new type of document")+' |
| '+__("List a document type")+' | '+ - __("document type..., e.g. customer")+' |
| '+__("Search in a document type")+' | '+ - __("text in document type")+' |
| '+__("Open a module or tool")+' | '+ - __("module name...")+' |
| '+__("Calculate")+' | '+ - __("e.g. (55 + 434) / 4 or =Math.sin(Math.PI/2)...")+' |
+{{ version(app.name) }} +{{ github_link(app, app.name, True) }} +
+ ++{{ version(app.name) }} +{{ github_link(app, app.name, True) }} +
+ +| + App Name + | +
+ {{ app.name }}
+ |
+
| + Publisher + | +
+ {{ app.publisher }}
+ |
+
| + Version + | +
+ {{ app.version }}
+ |
+
+{{ version(doctype) }} +{{ github_link(app, app.name + "/" + scrub(doc.module) + + "/doctype/" + scrub(doctype), True) }} +
{% if doc.issingle %}Single{% endif %} {% if doc.istable %}Child Table{% endif %} {% if not doc.issingle %} -Table Name: tab{{ name }}
Table Name: tab{{ doctype }}
{{ df.options }}{% endif %}
{% endif %}- Version {{ autodoc.get_version(name) }} -
-{% endmacro %} - {% macro render_class(obj) %}+{{ version(app.name) }} +{{ github_link(app, app.name, True) }} +
+ +Browse DocTypes by Module
+ ++{{ version(app.name) }} +{{ github_link(app, app.name + "/" + scrub(name), True) }} +
+ ++{{ version(app.name) }} +{{ github_link(app, title, True) }} +
+ ++{{ version(app.name) }} +{{ github_link(app, name.replace(".", "/") + ".py") }} +
+ +{{ automodule(name) }} + +{{ discuss_link() }} diff --git a/frappe/templates/base.html b/frappe/templates/base.html index c02a063309..2b301ec723 100644 --- a/frappe/templates/base.html +++ b/frappe/templates/base.html @@ -44,7 +44,7 @@ {% endif -%} - +[{\"title\":\"Jobs\", \"name\":\"jobs\"}]",
+ "description": "In JSON as [{\"title\":\"Jobs\", \"name\":\"jobs\"}]",
"fieldname": "breadcrumbs",
"fieldtype": "Small Text",
"label": "Breadcrumbs",
@@ -262,4 +262,4 @@
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "title"
-}
\ No newline at end of file
+}
diff --git a/frappe/website/doctype/web_page/web_page.json b/frappe/website/doctype/web_page/web_page.json
index f671e49593..e9fa1bc3ea 100644
--- a/frappe/website/doctype/web_page/web_page.json
+++ b/frappe/website/doctype/web_page/web_page.json
@@ -200,22 +200,41 @@
"icon": "icon-file-alt",
"idx": 1,
"max_attachments": 20,
- "modified": "2015-07-13 04:46:59.435179",
+ "modified": "2015-07-22 12:38:08.696692",
"modified_by": "Administrator",
"module": "Website",
"name": "Web Page",
"owner": "Administrator",
"permissions": [
{
+ "cancel": 0,
+ "create": 0,
+ "delete": 0,
+ "email": 0,
+ "permlevel": 0,
+ "print": 0,
+ "read": 1,
+ "report": 0,
+ "role": "Website Manager",
+ "share": 1,
+ "submit": 0,
+ "write": 0
+ },
+ {
+ "amend": 0,
+ "apply_user_permissions": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
+ "export": 1,
+ "import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
- "role": "Website Manager",
+ "role": "Guest",
+ "set_user_permissions": 0,
"share": 1,
"submit": 0,
"write": 1
diff --git a/frappe/website/doctype/website_settings/website_settings.json b/frappe/website/doctype/website_settings/website_settings.json
index 9df4654b72..ecb6f234bc 100644
--- a/frappe/website/doctype/website_settings/website_settings.json
+++ b/frappe/website/doctype/website_settings/website_settings.json
@@ -231,7 +231,7 @@
"permlevel": 0
},
{
- "description": "An icon file with .ico extension. Should be 16 x 16 px. Generated using a favicon generator. [favicon-generator.org]",
+ "description": "An icon file with .ico extension. Should be 16 x 16 px. Generated using a favicon generator. [favicon-generator.org]",
"fieldname": "favicon",
"fieldtype": "Attach",
"label": "FavIcon",
@@ -296,4 +296,4 @@
"submit": 0
}
]
-}
\ No newline at end of file
+}
diff --git a/frappe/website/doctype/website_settings/website_settings.py b/frappe/website/doctype/website_settings/website_settings.py
index fb5b34a83f..3f168edc35 100644
--- a/frappe/website/doctype/website_settings/website_settings.py
+++ b/frappe/website/doctype/website_settings/website_settings.py
@@ -118,8 +118,6 @@ def get_website_settings():
context.web_include_css = hooks.web_include_css or []
- add_website_theme(context)
-
via_hooks = frappe.get_hooks("website_context")
for key in via_hooks:
context[key] = via_hooks[key]
@@ -127,10 +125,12 @@ def get_website_settings():
and isinstance(context[key], (list, tuple)):
context[key] = context[key][0]
+ add_website_theme(context)
+
if not context.get("favicon"):
context["favicon"] = "/assets/frappe/images/favicon.png"
- if settings.favicon:
+ if settings.favicon and settings.favicon != "attach_files:":
context["favicon"] = settings.favicon
return context
diff --git a/frappe/website/doctype/website_theme/website_theme.json b/frappe/website/doctype/website_theme/website_theme.json
index 5b8293ebce..b01c2576ab 100644
--- a/frappe/website/doctype/website_theme/website_theme.json
+++ b/frappe/website/doctype/website_theme/website_theme.json
@@ -1,304 +1,304 @@
{
- "allow_copy": 0,
- "allow_import": 1,
- "allow_rename": 0,
- "autoname": "field:theme",
- "creation": "2015-02-18 12:46:38.168929",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Master",
+ "allow_copy": 0,
+ "allow_import": 1,
+ "allow_rename": 0,
+ "autoname": "field:theme",
+ "creation": "2015-02-18 12:46:38.168929",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Master",
"fields": [
{
- "allow_on_submit": 0,
- "fieldname": "theme",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Theme",
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 1,
+ "allow_on_submit": 0,
+ "fieldname": "theme",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Theme",
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 1,
"set_only_once": 0
- },
+ },
{
- "allow_on_submit": 0,
- "default": "Website",
- "fieldname": "module",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Module",
- "no_copy": 0,
- "options": "Module Def",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
+ "allow_on_submit": 0,
+ "default": "Website",
+ "fieldname": "module",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Module",
+ "no_copy": 0,
+ "options": "Module Def",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
"set_only_once": 0
- },
+ },
{
- "default": "1",
- "description": "This must be checked if the below style settings are applicable",
- "fieldname": "apply_style",
- "fieldtype": "Check",
- "hidden": 0,
- "label": "Apply Style",
- "permlevel": 0,
+ "default": "1",
+ "description": "This must be checked if the below style settings are applicable",
+ "fieldname": "apply_style",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "label": "Apply Style",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "default": "1",
- "fieldname": "custom",
- "fieldtype": "Check",
- "label": "Custom?",
- "permlevel": 0,
+ "default": "1",
+ "fieldname": "custom",
+ "fieldtype": "Check",
+ "label": "Custom?",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "allow_on_submit": 0,
- "fieldname": "column_break_2",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
+ "allow_on_submit": 0,
+ "fieldname": "column_break_2",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
"set_only_once": 0
- },
+ },
{
- "description": "Link to your Bootstrap theme",
- "fieldname": "bootstrap",
- "fieldtype": "Small Text",
- "label": "Link to Bootstrap CSS",
- "permlevel": 0,
+ "description": "Link to your Bootstrap theme",
+ "fieldname": "bootstrap",
+ "fieldtype": "Small Text",
+ "label": "Link to Bootstrap CSS",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "depends_on": "apply_style",
- "fieldname": "section_break_14",
- "fieldtype": "Section Break",
- "permlevel": 0,
+ "depends_on": "apply_style",
+ "fieldname": "section_break_14",
+ "fieldtype": "Section Break",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "default": "",
- "fieldname": "font_size",
- "fieldtype": "Select",
- "label": "Font Size",
- "options": "\n12px\n13px\n14px\n15px\n16px\n17px\n18px",
- "permlevel": 0,
+ "default": "",
+ "fieldname": "font_size",
+ "fieldtype": "Select",
+ "label": "Font Size",
+ "options": "\n12px\n13px\n14px\n15px\n16px\n17px\n18px",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "description": "Add the name of a Google Web Font e.g. \"Open Sans\"",
- "fieldname": "text_webfont",
- "fieldtype": "Data",
- "label": "Google Font (Text)",
- "permlevel": 0,
+ "description": "Add the name of a \"Google Web Font\" e.g. \"Open Sans\"",
+ "fieldname": "text_webfont",
+ "fieldtype": "Data",
+ "label": "Google Font (Text)",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "description": "Add the name of a Google Web Font e.g. \"Open Sans\"",
- "fieldname": "heading_webfont",
- "fieldtype": "Data",
- "label": "Google Font (Heading)",
- "permlevel": 0,
+ "description": "Add the name of a \"Google Web Font\" e.g. \"Open Sans\"",
+ "fieldname": "heading_webfont",
+ "fieldtype": "Data",
+ "label": "Google Font (Heading)",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "column_break_18",
- "fieldtype": "Column Break",
- "permlevel": 0,
+ "fieldname": "column_break_18",
+ "fieldtype": "Column Break",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "text_color",
- "fieldtype": "Data",
- "label": "Text Color",
- "permlevel": 0,
+ "fieldname": "text_color",
+ "fieldtype": "Data",
+ "label": "Text Color",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "link_color",
- "fieldtype": "Data",
- "label": "Link Color",
- "permlevel": 0,
+ "fieldname": "link_color",
+ "fieldtype": "Data",
+ "label": "Link Color",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "heading_style",
- "fieldtype": "Select",
- "label": "Heading Style",
- "options": "\nUPPERCASE\nTitle Case\nlowercase",
- "permlevel": 0,
+ "fieldname": "heading_style",
+ "fieldtype": "Select",
+ "label": "Heading Style",
+ "options": "\nUPPERCASE\nTitle Case\nlowercase",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "depends_on": "apply_style",
- "fieldname": "section_break_8",
- "fieldtype": "Section Break",
- "permlevel": 0,
+ "depends_on": "apply_style",
+ "fieldname": "section_break_8",
+ "fieldtype": "Section Break",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "top_bar_color",
- "fieldtype": "Data",
- "label": "Top Bar Color",
- "permlevel": 0,
+ "fieldname": "top_bar_color",
+ "fieldtype": "Data",
+ "label": "Top Bar Color",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "top_bar_text_color",
- "fieldtype": "Data",
- "label": "Top Bar Text Color",
- "permlevel": 0,
+ "fieldname": "top_bar_text_color",
+ "fieldtype": "Data",
+ "label": "Top Bar Text Color",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "no_sidebar",
- "fieldtype": "Check",
- "label": "Hide Sidebar",
- "permlevel": 0,
+ "fieldname": "no_sidebar",
+ "fieldtype": "Check",
+ "label": "Hide Sidebar",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "column_break_11",
- "fieldtype": "Column Break",
- "permlevel": 0,
+ "fieldname": "column_break_11",
+ "fieldtype": "Column Break",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "footer_color",
- "fieldtype": "Data",
- "label": "Footer Color",
- "permlevel": 0,
+ "fieldname": "footer_color",
+ "fieldtype": "Data",
+ "label": "Footer Color",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "footer_text_color",
- "fieldtype": "Data",
- "label": "Footer Text Color",
- "permlevel": 0,
+ "fieldname": "footer_text_color",
+ "fieldtype": "Data",
+ "label": "Footer Text Color",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "depends_on": "apply_style",
- "fieldname": "section_break_4",
- "fieldtype": "Section Break",
- "permlevel": 0,
+ "depends_on": "apply_style",
+ "fieldname": "section_break_4",
+ "fieldtype": "Section Break",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "background_color",
- "fieldtype": "Data",
- "label": "Background Color",
- "permlevel": 0,
+ "fieldname": "background_color",
+ "fieldtype": "Data",
+ "label": "Background Color",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "column_break_6",
- "fieldtype": "Column Break",
- "permlevel": 0,
+ "fieldname": "column_break_6",
+ "fieldtype": "Column Break",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "description": "If image is selected, color will be ignored.",
- "fieldname": "background_image",
- "fieldtype": "Attach Image",
- "label": "Background Image",
- "permlevel": 0,
+ "description": "If image is selected, color will be ignored.",
+ "fieldname": "background_image",
+ "fieldtype": "Attach Image",
+ "label": "Background Image",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "depends_on": "",
- "fieldname": "section_break_21",
- "fieldtype": "Section Break",
- "permlevel": 0,
+ "depends_on": "",
+ "fieldname": "section_break_21",
+ "fieldtype": "Section Break",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "depends_on": "apply_style",
- "description": "",
- "fieldname": "css",
- "fieldtype": "Code",
- "label": "Style using CSS",
- "permlevel": 0,
+ "depends_on": "apply_style",
+ "description": "",
+ "fieldname": "css",
+ "fieldtype": "Code",
+ "label": "Style using CSS",
+ "permlevel": 0,
"precision": ""
- },
+ },
{
- "fieldname": "js",
- "fieldtype": "Code",
- "label": "JavaScript",
- "permlevel": 0,
+ "fieldname": "js",
+ "fieldtype": "Code",
+ "label": "JavaScript",
+ "permlevel": 0,
"precision": ""
}
- ],
- "hide_heading": 0,
- "hide_toolbar": 0,
- "in_create": 0,
- "in_dialog": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 0,
- "modified": "2015-07-13 04:45:02.429785",
- "modified_by": "Administrator",
- "module": "Website",
- "name": "Website Theme",
- "name_case": "",
- "owner": "Administrator",
+ ],
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "in_create": 0,
+ "in_dialog": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "modified": "2015-07-27 01:00:32.901851",
+ "modified_by": "Administrator",
+ "module": "Website",
+ "name": "Website Theme",
+ "name_case": "",
+ "owner": "Administrator",
"permissions": [
{
- "create": 1,
- "delete": 1,
- "permlevel": 0,
- "read": 1,
- "role": "Website Manager",
+ "create": 1,
+ "delete": 1,
+ "permlevel": 0,
+ "read": 1,
+ "role": "Website Manager",
"write": 1
- },
+ },
{
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 1,
- "email": 0,
- "export": 1,
- "import": 1,
- "permlevel": 0,
- "print": 0,
- "read": 1,
- "report": 0,
- "role": "Administrator",
- "set_user_permissions": 0,
- "share": 0,
- "submit": 0,
+ "amend": 0,
+ "apply_user_permissions": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 0,
+ "export": 1,
+ "import": 1,
+ "permlevel": 0,
+ "print": 0,
+ "read": 1,
+ "report": 0,
+ "role": "Administrator",
+ "set_user_permissions": 0,
+ "share": 0,
+ "submit": 0,
"write": 1
}
- ],
- "read_only": 0,
- "read_only_onload": 0,
- "search_fields": "",
- "sort_field": "modified",
- "sort_order": "DESC",
+ ],
+ "read_only": 0,
+ "read_only_onload": 0,
+ "search_fields": "",
+ "sort_field": "modified",
+ "sort_order": "DESC",
"title_field": ""
-}
\ No newline at end of file
+}
diff --git a/frappe/website/doctype/website_theme/website_theme.py b/frappe/website/doctype/website_theme/website_theme.py
index 33601b0935..2cea0329f4 100644
--- a/frappe/website/doctype/website_theme/website_theme.py
+++ b/frappe/website/doctype/website_theme/website_theme.py
@@ -63,13 +63,20 @@ def use_theme(theme):
def add_website_theme(context):
bootstrap = frappe.get_hooks("bootstrap")[0]
- website_theme = get_active_theme()
- context.theme = website_theme and website_theme.as_dict() or frappe._dict()
- if website_theme:
- if website_theme.bootstrap:
- bootstrap = website_theme.bootstrap
+ web_include_css = context.web_include_css
+ context.theme = frappe._dict()
- context.no_sidebar = website_theme.no_sidebar
+ if not context.disable_website_theme:
+ website_theme = get_active_theme()
+ context.theme = website_theme and website_theme.as_dict() or frappe._dict()
+
+ if website_theme:
+ if website_theme.bootstrap:
+ bootstrap = website_theme.bootstrap
+
+ context.no_sidebar = website_theme.no_sidebar
+
+ context.web_include_css = ["website_theme.css"] + context.web_include_css
context.web_include_css = [bootstrap] + context.web_include_css
diff --git a/frappe/website/js/website.js b/frappe/website/js/website.js
index 4e4eb1d054..5adf938279 100644
--- a/frappe/website/js/website.js
+++ b/frappe/website/js/website.js
@@ -340,6 +340,9 @@ $.extend(frappe, {
// change id of current page
$(".page-container").attr("id", "page-" + data.path);
+ // set data-path value in body
+ $("body").attr("data-path", data.path);
+
// clear page-header-right
$(".page-header-right").html("");
diff --git a/frappe/workflow/doctype/workflow/workflow.json b/frappe/workflow/doctype/workflow/workflow.json
index 00244cdd2e..1d5b2232a8 100644
--- a/frappe/workflow/doctype/workflow/workflow.json
+++ b/frappe/workflow/doctype/workflow/workflow.json
@@ -1,100 +1,100 @@
{
- "allow_rename": 1,
- "autoname": "field:workflow_name",
- "creation": "2012-12-28 10:49:55",
- "description": "Defines workflow states and rules for a document.",
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Transaction",
+ "allow_rename": 1,
+ "autoname": "field:workflow_name",
+ "creation": "2012-12-28 10:49:55",
+ "description": "Defines workflow states and rules for a document.",
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Transaction",
"fields": [
{
- "fieldname": "workflow_name",
- "fieldtype": "Data",
- "in_list_view": 0,
- "label": "Workflow Name",
- "permlevel": 0,
- "read_only": 0,
+ "fieldname": "workflow_name",
+ "fieldtype": "Data",
+ "in_list_view": 0,
+ "label": "Workflow Name",
+ "permlevel": 0,
+ "read_only": 0,
"reqd": 1
- },
+ },
{
- "description": "DocType on which this Workflow is applicable.",
- "fieldname": "document_type",
- "fieldtype": "Link",
- "in_list_view": 0,
- "label": "Document Type",
- "options": "DocType",
- "permlevel": 0,
+ "description": "DocType on which this Workflow is applicable.",
+ "fieldname": "document_type",
+ "fieldtype": "Link",
+ "in_list_view": 0,
+ "label": "Document Type",
+ "options": "DocType",
+ "permlevel": 0,
"reqd": 1
- },
+ },
{
- "description": "If checked, all other workflows become inactive.",
- "fieldname": "is_active",
- "fieldtype": "Check",
- "in_list_view": 0,
- "label": "Is Active",
+ "description": "If checked, all other workflows become inactive.",
+ "fieldname": "is_active",
+ "fieldtype": "Check",
+ "in_list_view": 0,
+ "label": "Is Active",
"permlevel": 0
- },
+ },
{
- "description": "Different \"States\" this document can exist in. Like \"Open\", \"Pending Approval\" etc.",
- "fieldname": "states_head",
- "fieldtype": "Section Break",
- "label": "States",
+ "description": "Different \"States\" this document can exist in. Like \"Open\", \"Pending Approval\" etc.",
+ "fieldname": "states_head",
+ "fieldtype": "Section Break",
+ "label": "States",
"permlevel": 0
- },
+ },
{
- "description": "All possible Workflow States and roles of the workflow.