Merge branch 'develop'
This commit is contained in:
commit
dec7c6a348
60 changed files with 1915 additions and 1605 deletions
|
|
@ -1,2 +1,2 @@
|
|||
from __future__ import unicode_literals
|
||||
__version__ = "5.1.3"
|
||||
__version__ = "5.1.4"
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)""")
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
||||
|
|
|
|||
|
|
@ -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 <a href=\"https://gravatar.com/\">Gravatar.com</a>",
|
||||
"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 <a href=\"#Form/Customize Form/Customize Form\">Customize Form</a>.",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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"],
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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.: <br>Option 1<br>Option 2<br>Option 3<br>');
|
||||
__('Options for select. Each option on a new line.')+' '+__('e.g.:')+'<br>'+__('Option 1')+'<br>'+__('Option 2')+'<br>'+__('Option 3')+'<br>';
|
||||
} 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.');
|
||||
|
|
|
|||
|
|
@ -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<br /><b>Search By</b> 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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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): <br>\nmyfield\neval:doc.myfield=='My Value'<br>\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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 = {}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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"},
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 = []
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@
|
|||
margin: 0px;
|
||||
padding: 15px;
|
||||
}
|
||||
.form-section .form-section-heading {
|
||||
margin: 25px 0px 15px 0px;
|
||||
}
|
||||
.empty-section {
|
||||
display: none !important;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -285,6 +285,7 @@ body {
|
|||
}
|
||||
.avatar-empty {
|
||||
border: 1px dashed #d1d8dd;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.avatar-small {
|
||||
margin-right: 5px;
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 522 B |
|
|
@ -1,92 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="260px"
|
||||
height="260px"
|
||||
viewBox="0 0 260 260"
|
||||
enable-background="new 0 0 260 260"
|
||||
xml:space="preserve"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="frappe.svg"><metadata
|
||||
id="metadata73"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs71" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1160"
|
||||
inkscape:window-height="676"
|
||||
id="namedview69"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.8230769"
|
||||
inkscape:cx="130"
|
||||
inkscape:cy="130"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="text3365"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:snap-smooth-nodes="true" /><g
|
||||
id="g3"><g
|
||||
id="g5"
|
||||
transform="translate(5.5084746,2.2033898)"><g
|
||||
id="g7"
|
||||
transform="matrix(0.6988869,0,0,0.6988869,38.116279,42.59371)"><path
|
||||
d="m 223.463,82.762 c 27.129,55.638 0.525,91.039 -60.914,120.997 C 101.111,233.715 56.835,232.875 29.705,177.238 2.578,121.601 29.182,86.199 90.62,56.242 152.06,26.284 196.335,27.126 223.463,82.762 Z"
|
||||
id="path9"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#ffdd8c">
|
||||
|
||||
</path>
|
||||
<animateTransform
|
||||
attributeType="XML"
|
||||
attributeName="transform"
|
||||
begin="0s"
|
||||
dur="10s"
|
||||
type="rotate"
|
||||
from="0 125 135"
|
||||
to="360 125 135"
|
||||
additive="sum"
|
||||
repeatCount="indefinite" />
|
||||
|
||||
|
||||
|
||||
</g></g><g
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#223a4e;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="text3365"><path
|
||||
d="m 4.1839912,112.70592 0,-0.43946 q 0,-0.8789 0.4394531,-1.27441 0.4833985,-0.43945 1.6699219,-0.43945 l 7.0751958,0 0,-4.57032 q 0,-7.250972 3.076171,-10.986324 3.076172,-3.779296 8.833008,-3.779296 4.790039,0 7.119141,2.329101 0.966797,0.966797 0.966797,2.241211 0,0.65918 -0.307617,1.186523 -0.263672,0.527344 -0.57129,0.747071 -0.307617,0.219726 -0.395507,0.175781 -1.054688,-1.230469 -2.944336,-2.06543 -1.889649,-0.834961 -3.867188,-0.834961 -3.911133,0 -5.844726,2.72461 -1.889649,2.724614 -1.889649,8.525394 l 0,4.30664 9.448242,0 q 2.153321,0 2.153321,1.71386 l 0,0.43946 q 0,1.71386 -2.153321,1.71386 l -9.360351,0 0,36.91407 q 0,2.06543 -1.889649,2.06543 l -0.483398,0 q -1.889648,0 -1.889648,-2.06543 l 0,-36.91407 -7.0751958,0 q -1.1865234,0 -1.6699219,-0.3955 -0.4394531,-0.43946 -0.4394531,-1.31836 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:90px;font-family:Omnes;-inkscape-font-specification:Omnes;fill:#223a4e;fill-opacity:1"
|
||||
id="path3431" /><path
|
||||
d="m 37.450593,151.33385 0,-40.60547 q 0,-0.0439 0.175781,-0.13184 0.219727,-0.13183 0.571289,-0.21972 0.351563,-0.0879 0.703125,-0.0879 2.8125,0 2.8125,4.30664 l 0,5.31738 q 2.592774,-10.23926 11.777344,-10.23926 2.548828,0 4.21875,1.01074 1.713867,1.01075 1.713867,2.59278 0,0.74707 -0.307617,1.31836 -0.263672,0.52734 -0.571289,0.74707 -0.263672,0.21972 -0.395508,0.17578 -1.845703,-1.71387 -5.097656,-1.71387 -5.581055,0 -8.4375,5.09766 -2.8125,5.05371 -2.8125,13.97461 l 0,18.45703 q 0,2.06543 -1.889649,2.06543 l -0.483398,0 q -1.977539,0 -1.977539,-2.06543 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:90px;font-family:Omnes;-inkscape-font-specification:Omnes;fill:#223a4e;fill-opacity:1"
|
||||
id="path3433" /><path
|
||||
d="m 64.125397,142.32506 q 0,-7.16309 7.294922,-10.41504 7.338868,-3.2959 23.466797,-3.51563 l 0.922852,0 0,-2.15332 q 0,-5.97656 -3.47168,-9.27246 -3.427734,-3.33984 -9.580078,-3.33984 -5.273438,0 -8.964844,2.24121 -3.691406,2.19727 -5.537109,5.84473 -0.219727,0 -0.703125,-0.13184 -0.439453,-0.13184 -1.098633,-0.74707 -0.615234,-0.61523 -0.615234,-1.62598 0,-0.70312 0.659179,-1.88964 0.65918,-1.23047 1.757813,-2.24122 5.405273,-5.40527 14.765625,-5.40527 7.954101,0 12.480469,4.39453 4.526369,4.39453 4.526369,12.08496 l 0,26.80664 q 0,0.0439 -0.219729,0.17578 -0.219726,0.0879 -0.615234,0.17579 -0.351563,0.0879 -0.703125,0.0879 -2.680664,0 -2.680664,-4.30664 l 0,-4.43848 q -2.109375,4.21875 -6.635742,6.81152 -4.526368,2.54883 -10.283204,2.54883 -6.811523,0 -10.810546,-3.16406 -3.955079,-3.16406 -3.955079,-8.52539 z m 4.394532,0 q 0,3.77929 2.856445,5.97656 2.900391,2.15332 7.866211,2.15332 6.943359,0 11.733398,-4.1748 4.833985,-4.17481 4.833985,-10.23926 l 0,-4.21875 -1.186524,0 q -13.974609,0.26367 -20.039062,2.68066 -6.064453,2.41699 -6.064453,7.82227 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:90px;font-family:Omnes;-inkscape-font-specification:Omnes;fill:#223a4e;fill-opacity:1"
|
||||
id="path3435" /><path
|
||||
d="m 112.15762,168.42857 0,-57.70019 q 0,-0.0439 0.17579,-0.13184 0.21972,-0.13183 0.57128,-0.21972 0.35157,-0.0879 0.70313,-0.0879 2.8125,0 2.8125,4.30664 l 0,4.70214 q 5.71289,-9.62402 16.91894,-9.62402 8.61329,0 14.41407,6.19629 5.80078,6.15234 5.80078,15.86426 0,9.84375 -5.80078,16.08398 -5.75684,6.19629 -14.72168,6.19629 -6.06446,0 -10.41504,-2.76855 -4.35059,-2.76856 -6.1084,-6.76758 l 0,23.95019 q 0,2.06543 -1.88965,2.06543 l -0.4834,0 q -1.97754,0 -1.97754,-2.06543 z m 4.2627,-33.57422 q 0,6.41602 4.70215,10.89844 4.74609,4.48242 11.55761,4.48242 7.42676,0 11.99708,-5.09765 4.57031,-5.1416 4.57031,-13.40332 0,-7.91016 -4.70215,-13.09571 -4.6582,-5.18554 -11.68945,-5.18554 -5.93262,0 -10.15137,3.12011 -4.21875,3.07618 -6.28418,8.48145 l 0,9.7998 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:90px;font-family:Omnes;-inkscape-font-specification:Omnes;fill:#223a4e;fill-opacity:1"
|
||||
id="path3437" /><path
|
||||
d="m 163.13419,168.42857 0,-57.70019 q 0,-0.0439 0.17578,-0.13184 0.21972,-0.13183 0.57129,-0.21972 0.35156,-0.0879 0.70312,-0.0879 2.8125,0 2.8125,4.30664 l 0,4.70214 q 5.71289,-9.62402 16.91895,-9.62402 8.61328,0 14.41406,6.19629 5.80078,6.15234 5.80078,15.86426 0,9.84375 -5.80078,16.08398 -5.75684,6.19629 -14.72168,6.19629 -6.06445,0 -10.41504,-2.76855 -4.35059,-2.76856 -6.1084,-6.76758 l 0,23.95019 q 0,2.06543 -1.88965,2.06543 l -0.48339,0 q -1.97754,0 -1.97754,-2.06543 z m 4.26269,-33.57422 q 0,6.41602 4.70215,10.89844 4.74609,4.48242 11.55762,4.48242 7.42676,0 11.99707,-5.09765 4.57031,-5.1416 4.57031,-13.40332 0,-7.91016 -4.70215,-13.09571 -4.6582,-5.18554 -11.68945,-5.18554 -5.93262,0 -10.15137,3.12011 -4.21875,3.07618 -6.28418,8.48145 l 0,9.7998 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:90px;font-family:Omnes;-inkscape-font-specification:Omnes;fill:#223a4e;fill-opacity:1"
|
||||
id="path3439" /><path
|
||||
d="m 211.2543,131.99791 q 0,-6.28418 2.72461,-11.38184 2.72461,-5.09765 7.60254,-7.99804 4.87793,-2.94434 10.89844,-2.94434 8.78906,0 14.15039,5.75684 5.40527,5.71289 5.40527,15.02929 l 0,0.43946 q 0,0.92285 -0.43945,1.23047 -0.39551,0.30761 -1.45019,0.30761 l -34.67286,0 q 0.13184,7.91016 4.96582,12.83203 4.87793,4.87793 12.56836,4.87793 10.89844,0 15.24903,-8.52539 0.17578,-0.13183 0.74707,0.0879 0.61523,0.17578 1.18652,0.83496 0.57129,0.65918 0.57129,1.58204 0,0.74707 -0.70313,2.02148 -0.70312,1.27441 -2.02148,2.59277 -2.19727,2.19727 -6.1084,3.73536 -3.91113,1.53808 -8.9209,1.53808 -9.71191,0 -15.73242,-6.15234 -6.02051,-6.19629 -6.02051,-15.86426 z m 4.39453,-3.25195 31.86036,0 q -0.26368,-6.85547 -4.39453,-11.07422 -4.08692,-4.21875 -10.63477,-4.21875 -6.54785,0 -11.20606,4.26269 -4.61425,4.2627 -5.625,11.03028 z m 11.3379,-24.82911 q -0.13184,-0.17578 1.09863,-1.66992 1.23047,-1.49414 3.7793,-3.867185 2.54882,-2.416992 5.40527,-4.570312 2.63672,-1.977539 4.04297,-1.977539 0.83496,0 1.40625,0.527344 0.57129,0.483398 0.57129,1.274414 0,0.878906 -0.74707,1.757812 -0.70313,0.878906 -2.68067,2.373047 -2.94433,2.109375 -6.06445,3.691409 -3.07617,1.58203 -4.83399,2.15332 -1.75781,0.57129 -1.97753,0.30761 z"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:90px;font-family:Omnes;-inkscape-font-specification:Omnes;fill:#223a4e;fill-opacity:1"
|
||||
id="path3441" /></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 9.1 KiB |
|
|
@ -105,20 +105,6 @@ frappe.ui.form.Layout = Class.extend({
|
|||
});
|
||||
|
||||
},
|
||||
make_column: function(df) {
|
||||
this.column = $('<div class="form-column">\
|
||||
<form>\
|
||||
</form>\
|
||||
</div>').appendTo(this.section.body)
|
||||
.find("form")
|
||||
.on("submit", function() { return false; })
|
||||
|
||||
// distribute all columns equally
|
||||
var colspan = cint(12 / this.section.find(".form-column").length);
|
||||
this.section.find(".form-column").removeClass()
|
||||
.addClass("form-column")
|
||||
.addClass("col-sm-" + colspan);
|
||||
},
|
||||
make_field: function(df, colspan) {
|
||||
!this.section && this.make_section();
|
||||
!this.column && this.make_column();
|
||||
|
|
@ -181,7 +167,7 @@ frappe.ui.form.Layout = Class.extend({
|
|||
section.df = df;
|
||||
if(df) {
|
||||
if(df.label) {
|
||||
$('<div class="col-sm-12 text-muted"><h4>' + __(df.label) + '</h4></div>')
|
||||
$('<div class="col-sm-12"><h4 class="form-section-heading">' + __(df.label) + '</h4></div>')
|
||||
.appendTo(this.section);
|
||||
}
|
||||
if(df.description) {
|
||||
|
|
@ -198,24 +184,49 @@ frappe.ui.form.Layout = Class.extend({
|
|||
section.row = {
|
||||
wrapper: section
|
||||
};
|
||||
section.layout = me;
|
||||
section.refresh = function() {
|
||||
if(!this.df)
|
||||
return;
|
||||
|
||||
// hide if explictly hidden
|
||||
var hide = this.df.hidden || this.df.hidden_due_to_dependency;
|
||||
|
||||
// hide if no perm
|
||||
if(!hide && me.frm && !me.frm.get_perm(this.df.permlevel || 0, "read")) {
|
||||
hide = true;
|
||||
}
|
||||
|
||||
$(this).toggleClass("hide-control", !!hide);
|
||||
frappe.ui.section_refresh.apply(this);
|
||||
}
|
||||
this.column = null;
|
||||
section.refresh.call(section);
|
||||
return this.section;
|
||||
},
|
||||
make_column: function(df) {
|
||||
if(!df) df = {};
|
||||
|
||||
var column = $('<div class="form-column">\
|
||||
<form>\
|
||||
</form>\
|
||||
</div>').appendTo(this.section.body)
|
||||
.find("form")
|
||||
.on("submit", function() { return false; })
|
||||
|
||||
if(df.label) {
|
||||
$('<label class="control-label">'+ __(df.label)
|
||||
+'</label>').appendTo(column);
|
||||
}
|
||||
|
||||
// distribute all columns equally
|
||||
var colspan = cint(12 / this.section.find(".form-column").length);
|
||||
this.section.find(".form-column").removeClass()
|
||||
.addClass("form-column")
|
||||
.addClass("col-sm-" + colspan);
|
||||
|
||||
column.df = df;
|
||||
column.layout = this;
|
||||
|
||||
//this.fields_dict[df.fieldname] = column;
|
||||
if(df.fieldname) {
|
||||
this.fields_list.push(column);
|
||||
}
|
||||
|
||||
column.refresh = function() {
|
||||
frappe.ui.section_refresh.apply(this);
|
||||
}
|
||||
|
||||
this.column = column;
|
||||
},
|
||||
refresh_sections: function() {
|
||||
var cnt = 0;
|
||||
this.wrapper.find(".form-section:not(.hide-control)").each(function() {
|
||||
|
|
@ -385,4 +396,19 @@ frappe.ui.form.Layout = Class.extend({
|
|||
|
||||
this.refresh_section_count();
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
frappe.ui.section_refresh = function() {
|
||||
if(!this.df)
|
||||
return;
|
||||
|
||||
// hide if explictly hidden
|
||||
var hide = this.df.hidden || this.df.hidden_due_to_dependency;
|
||||
|
||||
// hide if no perm
|
||||
if(!hide && this.layout && this.layout.frm && !this.layout.frm.get_perm(this.df.permlevel || 0, "read")) {
|
||||
hide = true;
|
||||
}
|
||||
|
||||
$(this).toggleClass("hide-control", !!hide);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,6 +89,9 @@ $.extend(frappe.perm, {
|
|||
},
|
||||
|
||||
build_role_permissions: function(perm, meta) {
|
||||
// Returns a `dict` of evaluated Role Permissions
|
||||
// Apply User Permission and its DocTypes are used to display match rules in list view
|
||||
|
||||
$.each(meta.permissions || [], function(i, p) {
|
||||
// if user has this role
|
||||
if(user_roles.indexOf(p.role)!==-1) {
|
||||
|
|
@ -100,6 +103,7 @@ $.extend(frappe.perm, {
|
|||
$.each(frappe.perm.rights, function(i, key) {
|
||||
perm[permlevel][key] = perm[permlevel][key] || (p[key] || 0);
|
||||
|
||||
// NOTE: this data is required for displaying match rules in list view
|
||||
if (permlevel===0) {
|
||||
var apply_user_permissions = perm[permlevel].apply_user_permissions;
|
||||
var current_value = (apply_user_permissions[key]===undefined ?
|
||||
|
|
@ -108,6 +112,7 @@ $.extend(frappe.perm, {
|
|||
}
|
||||
});
|
||||
|
||||
// NOTE: this data is required for displaying match rules in list view
|
||||
if (permlevel===0 && cint(p.apply_user_permissions) && p.user_permission_doctypes) {
|
||||
// set user_permission_doctypes in perms
|
||||
var user_permission_doctypes = JSON.parse(p.user_permission_doctypes);
|
||||
|
|
@ -126,6 +131,10 @@ $.extend(frappe.perm, {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (permlevel===0 && p["if_owner"]) {
|
||||
perm[0]["if_owner"] = 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -177,6 +186,10 @@ $.extend(frappe.perm, {
|
|||
});
|
||||
}
|
||||
|
||||
if (perm[0].if_owner && perm[0].read) {
|
||||
match_rules.push({"Owner": user});
|
||||
}
|
||||
|
||||
return match_rules;
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -84,15 +84,15 @@ frappe.search = {
|
|||
onclick: function() {
|
||||
var txt = '<table class="table table-bordered">\
|
||||
<tr><td style="width: 50%">'+__("Make a new record")+'</td><td>'+
|
||||
__("<b>new</b> <i>type of document</i>")+'</td></tr>\
|
||||
__("new type of document")+'</td></tr>\
|
||||
<tr><td>'+__("List a document type")+'</td><td>'+
|
||||
__("<i>document type...</i>, e.g. <b>customer</b>")+'</td></tr>\
|
||||
__("document type..., e.g. customer")+'</td></tr>\
|
||||
<tr><td>'+__("Search in a document type")+'</td><td>'+
|
||||
__("<i>text</i> <b>in</b> <i>document type</i>")+'</td></tr>\
|
||||
__("text in document type")+'</td></tr>\
|
||||
<tr><td>'+__("Open a module or tool")+'</td><td>'+
|
||||
__("<i>module name...</i>")+'</td></tr>\
|
||||
__("module name...")+'</td></tr>\
|
||||
<tr><td>'+__("Calculate")+'</td><td>'+
|
||||
__("<i>e.g. <strong>(55 + 434) / 4</strong> or <strong>=Math.sin(Math.PI/2)</strong>...</i>")+'</td></tr>\
|
||||
__("e.g. (55 + 434) / 4 or =Math.sin(Math.PI/2)...")+'</td></tr>\
|
||||
</table>'
|
||||
msgprint(txt, "Search Help");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,17 +187,21 @@ frappe.views.ReportView = frappe.ui.Listing.extend({
|
|||
},
|
||||
|
||||
get_order_by: function() {
|
||||
var order_by = [];
|
||||
|
||||
// first
|
||||
var order_by = this.get_selected_table_and_column(this.sort_by_select)
|
||||
+ ' ' + this.sort_order_select.val();
|
||||
var sort_by_select = this.get_selected_table_and_column(this.sort_by_select);
|
||||
if (sort_by_select) {
|
||||
order_by.push(sort_by_select + " " + this.sort_order_select.val());
|
||||
}
|
||||
|
||||
// second
|
||||
if(this.sort_by_next_select.val()) {
|
||||
order_by += ', ' + this.get_selected_table_and_column(this.sort_by_next_select)
|
||||
+ ' ' + this.sort_order_next_select.val();
|
||||
order_by.push(this.get_selected_table_and_column(this.sort_by_next_select)
|
||||
+ ' ' + this.sort_order_next_select.val());
|
||||
}
|
||||
|
||||
return order_by;
|
||||
return order_by.join(", ");
|
||||
},
|
||||
|
||||
get_selected_table_and_column: function(select) {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@
|
|||
.form-section {
|
||||
margin: 0px;
|
||||
padding: 15px;
|
||||
|
||||
.form-section-heading {
|
||||
margin: 25px 0px 15px 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.empty-section {
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ def clear_sessions(user=None, keep_current=False):
|
|||
user = frappe.session.user
|
||||
|
||||
for sid in frappe.db.sql("""select sid from tabSessions where user=%s and device=%s""",
|
||||
(user, frappe.session.device or "desktop")):
|
||||
(user, frappe.session.data.device or "desktop")):
|
||||
if keep_current and frappe.session.sid==sid[0]:
|
||||
continue
|
||||
else:
|
||||
|
|
|
|||
11
frappe/templates/autodoc/api_home.html
Normal file
11
frappe/templates/autodoc/api_home.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<!-- title: {{ app.title }} API -->
|
||||
|
||||
{% from "templates/autodoc/macros.html" import github_link, version %}
|
||||
<p>
|
||||
{{ version(app.name) }}
|
||||
{{ github_link(app, app.name, True) }}
|
||||
</p>
|
||||
|
||||
<h3>Contents</h3>
|
||||
|
||||
{index}
|
||||
55
frappe/templates/autodoc/docs_home.html
Normal file
55
frappe/templates/autodoc/docs_home.html
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<!-- title: {{ app.title }} Documentation -->
|
||||
<!-- no-breadcrumbs -->
|
||||
|
||||
{% from "templates/autodoc/macros.html" import github_link, version, discuss_link %}
|
||||
<p>
|
||||
{{ version(app.name) }}
|
||||
{{ github_link(app, app.name, True) }}
|
||||
</p>
|
||||
|
||||
<table class="table table-bordered" style="max-width: 500px;">
|
||||
<tr>
|
||||
<td style="width: 40%">
|
||||
App Name
|
||||
</td>
|
||||
<td>
|
||||
<code>{{ app.name }}</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Publisher
|
||||
</td>
|
||||
<td>
|
||||
<code>{{ app.publisher }}</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Version
|
||||
</td>
|
||||
<td>
|
||||
<code>{{ app.version }}</code>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<hr>
|
||||
|
||||
{{ app.description }}
|
||||
|
||||
<hr>
|
||||
|
||||
<h3>Contents</h3>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="{{ '{{ pathname }}' }}/models">Models (DocTypes)</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ '{{ pathname }}' }}/api">Server-side API</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{{ discuss_link() }}
|
||||
|
||||
<!-- jinja --><!-- static -->
|
||||
|
|
@ -1,14 +1,21 @@
|
|||
{% from "templates/autodoc/macros.html" import automodule, version %}
|
||||
{% macro render_doctype(name) %}
|
||||
{% set doc = frappe.get_doc("DocType", name) %}
|
||||
{% set controller = autodoc.get_controller(name) %}
|
||||
{{ version(name) }}
|
||||
<!-- title: {{ doctype }} -->
|
||||
|
||||
{% from "templates/autodoc/macros.html" import automodule, version,
|
||||
github_link, doctype_link, discuss_link %}
|
||||
{% set doc = frappe.get_doc("DocType", doctype) %}
|
||||
{% set controller = autodoc.get_controller(doctype) %}
|
||||
|
||||
<p>
|
||||
{{ version(doctype) }}
|
||||
{{ github_link(app, app.name + "/" + scrub(doc.module)
|
||||
+ "/doctype/" + scrub(doctype), True) }}
|
||||
</p>
|
||||
|
||||
{% if doc.issingle %}<span class="label label-info">Single</span>{% endif %}
|
||||
{% if doc.istable %}<span class="label label-info">Child Table</span>{% endif %}
|
||||
|
||||
{% if not doc.issingle %}
|
||||
<p><b>Table Name:</b> <code>tab{{ name }}</code></p>
|
||||
<p><b>Table Name:</b> <code>tab{{ doctype }}</code></p>
|
||||
{% endif %}
|
||||
|
||||
{{ doc.description or "" }}
|
||||
|
|
@ -39,7 +46,7 @@
|
|||
</td>
|
||||
<td>{% if df.options and df.fieldtype not in ("HTML") %}
|
||||
{% if df.fieldtype in ("Table", "Link") %}
|
||||
<a href="{{ autodoc.get_doclink(df.options) or "#" }}">{{ df.options }}</a>
|
||||
{{ doctype_link(df.options) }}
|
||||
{% else %}<pre>{{ df.options }}</pre>{% endif %}
|
||||
{% endif %}</td>
|
||||
</tr>
|
||||
|
|
@ -54,26 +61,28 @@
|
|||
|
||||
{{ automodule(controller.__module__) }}
|
||||
{% set parents = frappe.get_list("DocField",
|
||||
{"options": name, "fieldtype": "Link"}, ["distinct parent"]) %}
|
||||
filters = {"options": doctype, "fieldtype": "Link"}, fields = ["distinct parent"]) %}
|
||||
{% if parents %}
|
||||
<h4>Linked In:</h4>
|
||||
<ul>
|
||||
{% for parent in parents %}
|
||||
<li><a href="{{ autodoc.get_doclink(parent.parent) }}">{{ parent.parent }}</a></li>
|
||||
<li>{{ doctype_link(parent.parent) }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% set parents = frappe.get_list("DocField",
|
||||
{"options": name, "fieldtype": "Table"}, ["parent"]) %}
|
||||
filters = {"options": doctype, "fieldtype": "Table"}, fields = ["parent"]) %}
|
||||
{% if parents %}
|
||||
<h4>Child Table Of</h4>
|
||||
<ul>
|
||||
{% for parent in parents %}
|
||||
<li><a href="{{ autodoc.get_doclink(parent.parent) }}">{{ parent.parent }}</a></li>
|
||||
<li>{{ doctype_link(parent.parent) }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% endmacro %}
|
||||
<!-- jinja --><!-- static -->
|
||||
|
||||
{{ discuss_link() }}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
{% macro automodule(name) %}
|
||||
{% set m = autodoc.automodule(name) %}
|
||||
{{ version(name) }}
|
||||
{% for obj in m.members %}
|
||||
{% if obj.type=="function" %}
|
||||
{{ render_function(obj, name) }}
|
||||
|
|
@ -10,12 +9,6 @@
|
|||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro version(name) %}
|
||||
<p>
|
||||
<span class="label label-default">Version {{ autodoc.get_version(name) }}</span>
|
||||
</p>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_class(obj) %}
|
||||
<h3 style="font-weight: normal;">Class <b>{{ obj.name }}</b></h3>
|
||||
{% if obj.bases %}
|
||||
|
|
@ -51,3 +44,26 @@
|
|||
{{ arg }}{% if default_idx >= 0 %}={{ args[3][default_idx] }}{% endif %}{% if not loop.last %}, {% endif %}
|
||||
{%- endfor %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro version(name) %}
|
||||
<a class="btn btn-default btn-sm" disabled style="margin-bottom: 10px;">
|
||||
Version {{ autodoc.get_version(name) }}</a>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro github_link(app, file_path, tree=False) %}
|
||||
<a class="btn btn-default btn-sm" href="{{ app.github_link }}/{{ "tree" if tree else "blob" }}/v{{ app.version }}/{{ file_path }}"
|
||||
target="_blank" style="margin-left: 10px; margin-bottom: 10px;"><i class="octicon octicon-mark-github"></i> Source</a>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro discuss_link() %}
|
||||
<br>
|
||||
<a href="https://discuss.erpnext.com" target="_blank">Discuss this on the forum</a>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro doctype_link(doctype) %}
|
||||
{% set module = frappe.db.get_value("DocType", doctype, "module") %}
|
||||
{% if doctype and module %}
|
||||
<a href="/{{'{{ pathname.split("/")[0] }}'}}/models/{{
|
||||
scrub(module) }}/{{ scrub(doctype) }}">{{ doctype }}</a>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
|
|
|||
13
frappe/templates/autodoc/models_home.html
Normal file
13
frappe/templates/autodoc/models_home.html
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<!-- title: {{ app.title }} Models (DocTypes) -->
|
||||
|
||||
{% from "templates/autodoc/macros.html" import github_link, version %}
|
||||
<p>
|
||||
{{ version(app.name) }}
|
||||
{{ github_link(app, app.name, True) }}
|
||||
</p>
|
||||
|
||||
<p>Browse DocTypes by Module</p>
|
||||
|
||||
<h3>Contents</h3>
|
||||
|
||||
{index}
|
||||
11
frappe/templates/autodoc/module_home.html
Normal file
11
frappe/templates/autodoc/module_home.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<!-- title: Module {{ name }} -->
|
||||
|
||||
{% from "templates/autodoc/macros.html" import github_link, version %}
|
||||
<p>
|
||||
{{ version(app.name) }}
|
||||
{{ github_link(app, app.name + "/" + scrub(name), True) }}
|
||||
</p>
|
||||
|
||||
<h3>DocTypes for {{ name }}</h3>
|
||||
|
||||
{index}
|
||||
11
frappe/templates/autodoc/package_index.html
Normal file
11
frappe/templates/autodoc/package_index.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<!-- title: {{ title }} -->
|
||||
|
||||
{% from "templates/autodoc/macros.html" import github_link, version %}
|
||||
<p>
|
||||
{{ version(app.name) }}
|
||||
{{ github_link(app, title, True) }}
|
||||
</p>
|
||||
|
||||
<h3>Package Contents</h3>
|
||||
|
||||
{index}
|
||||
12
frappe/templates/autodoc/pymodule.html
Normal file
12
frappe/templates/autodoc/pymodule.html
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<!-- title: {{ name }} -->
|
||||
|
||||
{%- from "templates/autodoc/macros.html" import automodule, github_link,
|
||||
version, discuss_link -%}
|
||||
<p>
|
||||
{{ version(app.name) }}
|
||||
{{ github_link(app, name.replace(".", "/") + ".py") }}
|
||||
</p>
|
||||
|
||||
{{ automodule(name) }}
|
||||
|
||||
{{ discuss_link() }}
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
</script>
|
||||
{% endif -%}
|
||||
</head>
|
||||
<body>
|
||||
<body data-path="{{ path }}">
|
||||
<div class="offcanvas-container">
|
||||
<div class="offcanvas">
|
||||
<div class="offcanvas-main-section">
|
||||
|
|
|
|||
|
|
@ -19,3 +19,4 @@
|
|||
</div>
|
||||
</div>
|
||||
{%- endif %}
|
||||
<!-- no-breadcrumbs -->
|
||||
|
|
|
|||
229
frappe/tests/test_permissions.py
Normal file
229
frappe/tests/test_permissions.py
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# MIT License. See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
"""Use blog post test to test user permissions logic"""
|
||||
|
||||
import frappe
|
||||
import frappe.defaults
|
||||
import unittest
|
||||
import json
|
||||
import frappe.model.meta
|
||||
from frappe.core.page.user_permissions.user_permissions import add, remove, get_permissions
|
||||
from frappe.permissions import clear_user_permissions_for_doctype, get_doc_permissions
|
||||
|
||||
test_records = frappe.get_test_records('Blog Post')
|
||||
|
||||
test_dependencies = ["User"]
|
||||
|
||||
class TestPermissions(unittest.TestCase):
|
||||
def setUp(self):
|
||||
frappe.clear_cache(doctype="Blog Post")
|
||||
|
||||
user = frappe.get_doc("User", "test1@example.com")
|
||||
user.add_roles("Website Manager")
|
||||
|
||||
user = frappe.get_doc("User", "test2@example.com")
|
||||
user.add_roles("Blogger")
|
||||
|
||||
frappe.set_user("test1@example.com")
|
||||
|
||||
def tearDown(self):
|
||||
frappe.set_user("Administrator")
|
||||
frappe.db.set_value("Blogger", "_Test Blogger 1", "user", None)
|
||||
|
||||
clear_user_permissions_for_doctype("Blog Category")
|
||||
clear_user_permissions_for_doctype("Blog Post")
|
||||
clear_user_permissions_for_doctype("Blogger")
|
||||
|
||||
frappe.db.sql("""update `tabDocPerm` set user_permission_doctypes=null
|
||||
where parent='Blog Post' and permlevel=0 and apply_user_permissions=1
|
||||
and `read`=1""")
|
||||
|
||||
frappe.db.sql("""update `tabDocPerm` set if_owner=0
|
||||
where parent='Blog Post' and permlevel=0 and permlevel=0 and role='Blogger'""")
|
||||
|
||||
def test_basic_permission(self):
|
||||
post = frappe.get_doc("Blog Post", "_test-blog-post")
|
||||
self.assertTrue(post.has_permission("read"))
|
||||
|
||||
def test_user_permissions_in_doc(self):
|
||||
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category 1",
|
||||
"test2@example.com")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
post = frappe.get_doc("Blog Post", "_test-blog-post")
|
||||
self.assertFalse(post.has_permission("read"))
|
||||
self.assertFalse(get_doc_permissions(post).get("read"))
|
||||
|
||||
post1 = frappe.get_doc("Blog Post", "_test-blog-post-1")
|
||||
self.assertTrue(post1.has_permission("read"))
|
||||
self.assertTrue(get_doc_permissions(post1).get("read"))
|
||||
|
||||
def test_user_permissions_in_report(self):
|
||||
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category 1", "test2@example.com")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
names = [d.name for d in frappe.get_list("Blog Post", fields=["name", "blog_category"])]
|
||||
|
||||
self.assertTrue("_test-blog-post-1" in names)
|
||||
self.assertFalse("_test-blog-post" in names)
|
||||
|
||||
def test_default_values(self):
|
||||
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category 1", "test2@example.com")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
doc = frappe.new_doc("Blog Post")
|
||||
self.assertEquals(doc.get("blog_category"), "_Test Blog Category 1")
|
||||
|
||||
def test_user_link_match_doc(self):
|
||||
blogger = frappe.get_doc("Blogger", "_Test Blogger 1")
|
||||
blogger.user = "test2@example.com"
|
||||
blogger.save()
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
post = frappe.get_doc("Blog Post", "_test-blog-post-2")
|
||||
self.assertTrue(post.has_permission("read"))
|
||||
|
||||
post1 = frappe.get_doc("Blog Post", "_test-blog-post-1")
|
||||
self.assertFalse(post1.has_permission("read"))
|
||||
|
||||
def test_user_link_match_report(self):
|
||||
blogger = frappe.get_doc("Blogger", "_Test Blogger 1")
|
||||
blogger.user = "test2@example.com"
|
||||
blogger.save()
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
names = [d.name for d in frappe.get_list("Blog Post", fields=["name", "owner"])]
|
||||
self.assertTrue("_test-blog-post-2" in names)
|
||||
self.assertFalse("_test-blog-post-1" in names)
|
||||
|
||||
def test_set_user_permissions(self):
|
||||
frappe.set_user("test1@example.com")
|
||||
add("test2@example.com", "Blog Post", "_test-blog-post")
|
||||
|
||||
def test_not_allowed_to_set_user_permissions(self):
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
# this user can't add user permissions
|
||||
self.assertRaises(frappe.PermissionError, add,
|
||||
"test2@example.com", "Blog Post", "_test-blog-post")
|
||||
|
||||
def test_read_if_explicit_user_permissions_are_set(self):
|
||||
self.test_set_user_permissions()
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
# user can only access permitted blog post
|
||||
doc = frappe.get_doc("Blog Post", "_test-blog-post")
|
||||
self.assertTrue(doc.has_permission("read"))
|
||||
|
||||
# and not this one
|
||||
doc = frappe.get_doc("Blog Post", "_test-blog-post-1")
|
||||
self.assertFalse(doc.has_permission("read"))
|
||||
|
||||
def test_not_allowed_to_remove_user_permissions(self):
|
||||
self.test_set_user_permissions()
|
||||
defname = get_permissions("test2@example.com", "Blog Post", "_test-blog-post")[0].name
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
# user cannot remove their own user permissions
|
||||
self.assertRaises(frappe.PermissionError, remove,
|
||||
"test2@example.com", defname, "Blog Post", "_test-blog-post")
|
||||
|
||||
def test_user_permissions_based_on_blogger(self):
|
||||
frappe.set_user("test2@example.com")
|
||||
doc = frappe.get_doc("Blog Post", "_test-blog-post-1")
|
||||
self.assertTrue(doc.has_permission("read"))
|
||||
|
||||
frappe.set_user("test1@example.com")
|
||||
add("test2@example.com", "Blog Post", "_test-blog-post")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
doc = frappe.get_doc("Blog Post", "_test-blog-post-1")
|
||||
self.assertFalse(doc.has_permission("read"))
|
||||
|
||||
doc = frappe.get_doc("Blog Post", "_test-blog-post")
|
||||
self.assertTrue(doc.has_permission("read"))
|
||||
|
||||
def test_set_only_once(self):
|
||||
blog_post = frappe.get_meta("Blog Post")
|
||||
blog_post.get_field("title").set_only_once = 1
|
||||
doc = frappe.get_doc("Blog Post", "_test-blog-post-1")
|
||||
doc.title = "New"
|
||||
self.assertRaises(frappe.CannotChangeConstantError, doc.save)
|
||||
blog_post.get_field("title").set_only_once = 0
|
||||
|
||||
def test_user_permission_doctypes(self):
|
||||
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category 1",
|
||||
"test2@example.com")
|
||||
frappe.permissions.add_user_permission("Blogger", "_Test Blogger 1",
|
||||
"test2@example.com")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
frappe.db.sql("""update `tabDocPerm` set user_permission_doctypes=%s
|
||||
where parent='Blog Post' and permlevel=0 and apply_user_permissions=1
|
||||
and `read`=1""", json.dumps(["Blogger"]))
|
||||
|
||||
frappe.model.meta.clear_cache("Blog Post")
|
||||
|
||||
doc = frappe.get_doc("Blog Post", "_test-blog-post")
|
||||
self.assertFalse(doc.has_permission("read"))
|
||||
|
||||
doc = frappe.get_doc("Blog Post", "_test-blog-post-2")
|
||||
self.assertTrue(doc.has_permission("read"))
|
||||
|
||||
frappe.model.meta.clear_cache("Blog Post")
|
||||
|
||||
def if_owner_setup(self):
|
||||
frappe.db.sql("""update `tabDocPerm` set if_owner=1
|
||||
where parent='Blog Post' and permlevel=0 and permlevel=0 and role='Blogger'""")
|
||||
|
||||
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category 1",
|
||||
"test2@example.com")
|
||||
frappe.permissions.add_user_permission("Blogger", "_Test Blogger 1",
|
||||
"test2@example.com")
|
||||
|
||||
frappe.db.sql("""update `tabDocPerm` set user_permission_doctypes=%s
|
||||
where parent='Blog Post' and permlevel=0 and apply_user_permissions=1
|
||||
and `read`=1""", json.dumps(["Blog Category"]))
|
||||
|
||||
frappe.model.meta.clear_cache("Blog Post")
|
||||
|
||||
def test_insert_if_owner_with_user_permissions(self):
|
||||
"""If `If Owner` is checked for a Role, check if that document is allowed to be read, updated, submitted, etc. except be created, even if the document is restricted based on User Permissions."""
|
||||
self.if_owner_setup()
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
doc = frappe.get_doc({
|
||||
"doctype": "Blog Post",
|
||||
"blog_category": "_Test Blog Category",
|
||||
"blogger": "_Test Blogger 1",
|
||||
"title": "_Test Blog Post Title",
|
||||
"content": "_Test Blog Post Content"
|
||||
})
|
||||
|
||||
self.assertRaises(frappe.PermissionError, doc.insert)
|
||||
|
||||
frappe.set_user("Administrator")
|
||||
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category",
|
||||
"test2@example.com")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
doc.insert()
|
||||
|
||||
frappe.set_user("Administrator")
|
||||
frappe.permissions.remove_user_permission("Blog Category", "_Test Blog Category",
|
||||
"test2@example.com")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
doc = frappe.get_doc(doc.doctype, doc.name)
|
||||
self.assertTrue(doc.has_permission("read"))
|
||||
self.assertTrue(doc.has_permission("write"))
|
||||
self.assertFalse(doc.has_permission("create"))
|
||||
|
|
@ -8,50 +8,9 @@ frappe.utils.autodoc
|
|||
Inspect elements of a given module and return its objects
|
||||
"""
|
||||
|
||||
import inspect, importlib, re, frappe, os, shutil
|
||||
import inspect, importlib, re, frappe
|
||||
from frappe.model.document import get_controller
|
||||
from markdown2 import markdown
|
||||
|
||||
def build(app):
|
||||
app_path = frappe.get_app_path(app)
|
||||
source = frappe.get_app_path(app, "src")
|
||||
dest = frappe.get_app_path(app, "www")
|
||||
for basepath, folders, files in os.walk(source):
|
||||
destpath = os.path.join(dest, os.path.relpath(basepath, source))
|
||||
|
||||
# make target dir if missing
|
||||
if not os.path.exists(destpath):
|
||||
os.makedirs(destpath)
|
||||
|
||||
# delete removed folders in source from dest
|
||||
for destfolder in os.listdir(destpath):
|
||||
if os.path.isdir(os.path.join(destpath, destfolder)):
|
||||
if destfolder not in folders:
|
||||
os.path.join(destpath, destfolder)
|
||||
shutil.rmtree(os.path.join(destpath, destfolder))
|
||||
|
||||
for fname in files:
|
||||
# delete file
|
||||
if os.path.exists(os.path.join(destpath, fname)):
|
||||
os.remove(os.path.join(destpath, fname))
|
||||
|
||||
print fname
|
||||
if fname.rsplit(".", 1)[-1] in ("md", "html"):
|
||||
# render template and build file
|
||||
with open(os.path.join(destpath, fname.rsplit(".", 1)[0] + ".html"), "w") as destfile:
|
||||
if fname.endswith(".md"):
|
||||
# convert markdown to html before rendering
|
||||
with open(os.path.join(basepath, fname), "r") as template_file:
|
||||
template = markdown(template_file.read())
|
||||
html = frappe.render_template(template, {}).encode("utf-8")
|
||||
destfile.write(html)
|
||||
else:
|
||||
template_path = os.path.relpath(os.path.join(basepath, fname), app_path)
|
||||
html = frappe.render_template(template_path, {}, is_path=True).encode("utf-8")
|
||||
destfile.write(html)
|
||||
else:
|
||||
# not a template, copy
|
||||
shutil.copyfile(os.path.join(basepath, fname), os.path.join(destpath, fname))
|
||||
|
||||
def automodule(name):
|
||||
"""Returns a list of attributes for given module string.
|
||||
|
|
@ -85,16 +44,22 @@ def automodule(name):
|
|||
"members": filter(None, attributes),
|
||||
}
|
||||
|
||||
installed = None
|
||||
def get_version(name):
|
||||
print name
|
||||
global installed
|
||||
|
||||
if not installed:
|
||||
installed = frappe.get_installed_apps()
|
||||
|
||||
def _for_module(m):
|
||||
return importlib.import_module(m.split(".")[0]).__version__
|
||||
|
||||
if "." in name or name=="frappe":
|
||||
if "." in name or name in installed:
|
||||
return _for_module(name)
|
||||
else:
|
||||
return _for_module(get_controller(name).__module__)
|
||||
|
||||
|
||||
def get_class_info(class_obj, module_name):
|
||||
members = []
|
||||
for attrname in dir(class_obj):
|
||||
|
|
@ -117,15 +82,14 @@ def get_class_info(class_obj, module_name):
|
|||
}
|
||||
|
||||
def get_function_info(value):
|
||||
docs = getattr(value, "__doc__", "")
|
||||
if docs:
|
||||
return {
|
||||
"name": value.__name__,
|
||||
"type": "function",
|
||||
"args": inspect.getargspec(value),
|
||||
"docs": parse(docs),
|
||||
"whitelisted": value in frappe.whitelisted
|
||||
}
|
||||
docs = getattr(value, "__doc__")
|
||||
return {
|
||||
"name": value.__name__,
|
||||
"type": "function",
|
||||
"args": inspect.getargspec(value),
|
||||
"docs": parse(docs) if docs else '<span class="text-muted">No docs</span>',
|
||||
"whitelisted": value in frappe.whitelisted
|
||||
}
|
||||
|
||||
def parse(docs):
|
||||
"""Parse __docs__ text into markdown. Will parse directives like `:param name:` etc"""
|
||||
|
|
@ -179,17 +143,3 @@ def strip_leading_tabs(docs):
|
|||
def automodel(doctype):
|
||||
"""return doctype template"""
|
||||
pass
|
||||
|
||||
def get_doclink(name):
|
||||
"""Returns `__doclink__` property of a module or DocType if exists"""
|
||||
if name=="[Select]": return ""
|
||||
|
||||
if "." in name:
|
||||
obj = frappe.get_attr(name)
|
||||
else:
|
||||
obj = get_controller(name)
|
||||
|
||||
if hasattr(obj, "__doclink__"):
|
||||
return obj.__doclink__
|
||||
else:
|
||||
return ""
|
||||
|
|
|
|||
|
|
@ -32,9 +32,10 @@ def get_allowed_functions_for_jenv():
|
|||
import frappe
|
||||
import frappe.utils
|
||||
import frappe.utils.data
|
||||
from frappe.utils.autodoc import automodule, get_doclink, get_version
|
||||
from frappe.utils.autodoc import automodule, get_version
|
||||
from frappe.model.document import get_controller
|
||||
from frappe.website.utils import get_shade
|
||||
from frappe.modules import scrub
|
||||
|
||||
datautils = {}
|
||||
for key, obj in frappe.utils.data.__dict__.items():
|
||||
|
|
@ -76,14 +77,14 @@ def get_allowed_functions_for_jenv():
|
|||
},
|
||||
"autodoc": {
|
||||
"get_version": get_version,
|
||||
"get_doclink": get_doclink,
|
||||
"automodule": automodule,
|
||||
"get_controller": get_controller
|
||||
},
|
||||
"get_visible_columns": \
|
||||
frappe.get_attr("frappe.templates.pages.print.get_visible_columns"),
|
||||
"_": frappe._,
|
||||
"get_shade": get_shade
|
||||
"get_shade": get_shade,
|
||||
"scrub": scrub
|
||||
}
|
||||
|
||||
def get_jloader():
|
||||
|
|
|
|||
|
|
@ -6,20 +6,50 @@ Call from command line:
|
|||
|
||||
"""
|
||||
|
||||
import os, json, frappe
|
||||
import os, json, frappe, markdown2, shutil
|
||||
|
||||
class setup_docs(object):
|
||||
def __init__(self, app, docs_app, path):
|
||||
"""Generate source templates for models reference and module API.
|
||||
|
||||
Must set globals `self.models_base_path`, `self.api_base_path` and `self.app_path`.
|
||||
def __init__(self):
|
||||
"""Generate source templates for models reference and module API
|
||||
and templates at `templates/autodoc`
|
||||
"""
|
||||
self.app = app
|
||||
self.app_path = frappe.get_app_path(app)
|
||||
if path[0]=="/": path = path[1:]
|
||||
path = frappe.get_app_path(docs_app, path)
|
||||
self.app = frappe.get_hooks("autodoc").get("for_app")[0]
|
||||
docs_app = frappe.get_hooks("autodoc").get("docs_app")[0]
|
||||
|
||||
hooks = frappe.get_hooks(app_name = self.app)
|
||||
self.app_title = hooks.get("app_title")[0]
|
||||
|
||||
self.app_path = frappe.get_app_path(self.app)
|
||||
path = frappe.get_app_path(docs_app, "www", "current")
|
||||
|
||||
print "Deleting current..."
|
||||
shutil.rmtree(path, ignore_errors = True)
|
||||
os.makedirs(path)
|
||||
|
||||
self.app_context = {
|
||||
"app": {
|
||||
"name": self.app,
|
||||
"title": self.app_title,
|
||||
"description": markdown2.markdown(hooks.get("app_description")[0]),
|
||||
"version": hooks.get("app_version")[0],
|
||||
"publisher": hooks.get("app_publisher")[0],
|
||||
"github_link": hooks.get("github_link")[0],
|
||||
}
|
||||
}
|
||||
|
||||
# make home page
|
||||
with open(os.path.join(path, "index.html"), "w") as home:
|
||||
home.write(frappe.render_template("templates/autodoc/docs_home.html",
|
||||
self.app_context))
|
||||
|
||||
# make folders
|
||||
self.models_base_path = os.path.join(path, "models")
|
||||
self.make_folder(self.models_base_path,
|
||||
template = "templates/autodoc/models_home.html")
|
||||
|
||||
self.api_base_path = os.path.join(path, "api")
|
||||
self.make_folder(self.api_base_path,
|
||||
template = "templates/autodoc/api_home.html")
|
||||
|
||||
for basepath, folders, files in os.walk(self.app_path):
|
||||
if "doctype" not in basepath:
|
||||
|
|
@ -28,7 +58,9 @@ class setup_docs(object):
|
|||
|
||||
module_folder = os.path.join(self.models_base_path, module)
|
||||
|
||||
self.make_folder(module_folder)
|
||||
self.make_folder(module_folder,
|
||||
template = "templates/autodoc/module_home.html",
|
||||
context = {"name": module})
|
||||
self.update_index_txt(module_folder)
|
||||
|
||||
if "doctype" in basepath:
|
||||
|
|
@ -70,35 +102,37 @@ class setup_docs(object):
|
|||
if not os.path.exists(module_doc_path):
|
||||
print "Writing " + module_doc_path
|
||||
with open(module_doc_path, "w") as f:
|
||||
f.write("""<h1>%(name)s</h1>
|
||||
|
||||
<!-- title: %(name)s -->
|
||||
{%%- from "templates/autodoc/macros.html" import automodule -%%}
|
||||
|
||||
{{ automodule("%(name)s") }}""" % {"name": self.app + "." + module_name})
|
||||
context = {"name": self.app + "." + module_name}
|
||||
context.update(self.app_context)
|
||||
f.write(frappe.render_template("templates/autodoc/pymodule.html",
|
||||
context))
|
||||
|
||||
self.update_index_txt(module_folder)
|
||||
|
||||
def make_folder(self, path):
|
||||
def make_folder(self, path, template=None, context=None):
|
||||
if not template:
|
||||
template = "templates/autodoc/package_index.html"
|
||||
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
|
||||
index_txt_path = os.path.join(path, "index.txt")
|
||||
if not os.path.exists(index_txt_path):
|
||||
index_txt_path = os.path.join(path, "index.txt")
|
||||
print "Writing " + index_txt_path
|
||||
with open(index_txt_path, "w") as f:
|
||||
f.write("")
|
||||
|
||||
index_md_path = os.path.join(path, "index.html")
|
||||
if not os.path.exists(index_md_path):
|
||||
name = os.path.basename(path)
|
||||
if name==".":
|
||||
name = self.app
|
||||
print "Writing " + index_md_path
|
||||
with open(index_md_path, "w") as f:
|
||||
f.write("""<h1>{0}</h1>
|
||||
<!-- title: {0} -->
|
||||
{{index}}""".format(name))
|
||||
index_html_path = os.path.join(path, "index.html")
|
||||
if not context:
|
||||
name = os.path.basename(path)
|
||||
if name==".":
|
||||
name = self.app
|
||||
context = {
|
||||
"title": name
|
||||
}
|
||||
context.update(self.app_context)
|
||||
print "Writing " + index_html_path
|
||||
with open(index_html_path, "w") as f:
|
||||
f.write(frappe.render_template(template, context))
|
||||
|
||||
def update_index_txt(self, path):
|
||||
index_txt_path = os.path.join(path, "index.txt")
|
||||
|
|
@ -126,12 +160,7 @@ class setup_docs(object):
|
|||
print "Writing " + model_path
|
||||
|
||||
with open(model_path, "w") as f:
|
||||
f.write("""<h1>%(doctype)s</h1>
|
||||
|
||||
<!-- title: %(doctype)s -->
|
||||
{%% from "templates/autodoc/doctype.html" import render_doctype %%}
|
||||
|
||||
{{ render_doctype("%(doctype)s") }}
|
||||
|
||||
<!-- jinja --><!-- static -->
|
||||
""" % {"doctype": doctype_real_name})
|
||||
context = {"doctype": doctype_real_name}
|
||||
context.update(self.app_context)
|
||||
f.write(frappe.render_template("templates/autodoc/doctype.html",
|
||||
context).encode("utf-8"))
|
||||
|
|
|
|||
|
|
@ -1,177 +1,9 @@
|
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# MIT License. See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
"""Use blog post test to test user permissions logic"""
|
||||
|
||||
import frappe
|
||||
import frappe.defaults
|
||||
import unittest
|
||||
import json
|
||||
import frappe.model.meta
|
||||
from frappe.core.page.user_permissions.user_permissions import add, remove, get_permissions
|
||||
from frappe.permissions import clear_user_permissions_for_doctype, get_doc_permissions
|
||||
|
||||
test_records = frappe.get_test_records('Blog Post')
|
||||
|
||||
test_dependencies = ["User"]
|
||||
class TestBlogPost(unittest.TestCase):
|
||||
def setUp(self):
|
||||
frappe.clear_cache(doctype="Blog Post")
|
||||
pass
|
||||
|
||||
user = frappe.get_doc("User", "test1@example.com")
|
||||
user.add_roles("Website Manager")
|
||||
|
||||
user = frappe.get_doc("User", "test2@example.com")
|
||||
user.add_roles("Blogger")
|
||||
|
||||
frappe.set_user("test1@example.com")
|
||||
|
||||
def tearDown(self):
|
||||
frappe.set_user("Administrator")
|
||||
frappe.db.set_value("Blogger", "_Test Blogger 1", "user", None)
|
||||
|
||||
clear_user_permissions_for_doctype("Blog Category")
|
||||
clear_user_permissions_for_doctype("Blog Post")
|
||||
clear_user_permissions_for_doctype("Blogger")
|
||||
|
||||
frappe.db.sql("""update `tabDocPerm` set user_permission_doctypes=null
|
||||
where parent='Blog Post' and permlevel=0 and apply_user_permissions=1
|
||||
and `read`=1""")
|
||||
|
||||
def test_basic_permission(self):
|
||||
post = frappe.get_doc("Blog Post", "_test-blog-post")
|
||||
self.assertTrue(post.has_permission("read"))
|
||||
|
||||
def test_user_permissions_in_doc(self):
|
||||
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category 1",
|
||||
"test2@example.com")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
post = frappe.get_doc("Blog Post", "_test-blog-post")
|
||||
self.assertFalse(post.has_permission("read"))
|
||||
self.assertFalse(get_doc_permissions(post).get("read"))
|
||||
|
||||
post1 = frappe.get_doc("Blog Post", "_test-blog-post-1")
|
||||
self.assertTrue(post1.has_permission("read"))
|
||||
self.assertTrue(get_doc_permissions(post1).get("read"))
|
||||
|
||||
def test_user_permissions_in_report(self):
|
||||
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category 1", "test2@example.com")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
names = [d.name for d in frappe.get_list("Blog Post", fields=["name", "blog_category"])]
|
||||
|
||||
self.assertTrue("_test-blog-post-1" in names)
|
||||
self.assertFalse("_test-blog-post" in names)
|
||||
|
||||
def test_default_values(self):
|
||||
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category 1", "test2@example.com")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
doc = frappe.new_doc("Blog Post")
|
||||
self.assertEquals(doc.get("blog_category"), "_Test Blog Category 1")
|
||||
|
||||
def test_user_link_match_doc(self):
|
||||
blogger = frappe.get_doc("Blogger", "_Test Blogger 1")
|
||||
blogger.user = "test2@example.com"
|
||||
blogger.save()
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
post = frappe.get_doc("Blog Post", "_test-blog-post-2")
|
||||
self.assertTrue(post.has_permission("read"))
|
||||
|
||||
post1 = frappe.get_doc("Blog Post", "_test-blog-post-1")
|
||||
self.assertFalse(post1.has_permission("read"))
|
||||
|
||||
def test_user_link_match_report(self):
|
||||
blogger = frappe.get_doc("Blogger", "_Test Blogger 1")
|
||||
blogger.user = "test2@example.com"
|
||||
blogger.save()
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
names = [d.name for d in frappe.get_list("Blog Post", fields=["name", "owner"])]
|
||||
self.assertTrue("_test-blog-post-2" in names)
|
||||
self.assertFalse("_test-blog-post-1" in names)
|
||||
|
||||
def test_set_user_permissions(self):
|
||||
frappe.set_user("test1@example.com")
|
||||
add("test2@example.com", "Blog Post", "_test-blog-post")
|
||||
|
||||
def test_not_allowed_to_set_user_permissions(self):
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
# this user can't add user permissions
|
||||
self.assertRaises(frappe.PermissionError, add,
|
||||
"test2@example.com", "Blog Post", "_test-blog-post")
|
||||
|
||||
def test_read_if_explicit_user_permissions_are_set(self):
|
||||
self.test_set_user_permissions()
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
# user can only access permitted blog post
|
||||
doc = frappe.get_doc("Blog Post", "_test-blog-post")
|
||||
self.assertTrue(doc.has_permission("read"))
|
||||
|
||||
# and not this one
|
||||
doc = frappe.get_doc("Blog Post", "_test-blog-post-1")
|
||||
self.assertFalse(doc.has_permission("read"))
|
||||
|
||||
def test_not_allowed_to_remove_user_permissions(self):
|
||||
self.test_set_user_permissions()
|
||||
defname = get_permissions("test2@example.com", "Blog Post", "_test-blog-post")[0].name
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
# user cannot remove their own user permissions
|
||||
self.assertRaises(frappe.PermissionError, remove,
|
||||
"test2@example.com", defname, "Blog Post", "_test-blog-post")
|
||||
|
||||
def test_user_permissions_based_on_blogger(self):
|
||||
frappe.set_user("test2@example.com")
|
||||
doc = frappe.get_doc("Blog Post", "_test-blog-post-1")
|
||||
self.assertTrue(doc.has_permission("read"))
|
||||
|
||||
frappe.set_user("test1@example.com")
|
||||
add("test2@example.com", "Blog Post", "_test-blog-post")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
doc = frappe.get_doc("Blog Post", "_test-blog-post-1")
|
||||
self.assertFalse(doc.has_permission("read"))
|
||||
|
||||
doc = frappe.get_doc("Blog Post", "_test-blog-post")
|
||||
self.assertTrue(doc.has_permission("read"))
|
||||
|
||||
def test_set_only_once(self):
|
||||
blog_post = frappe.get_meta("Blog Post")
|
||||
blog_post.get_field("title").set_only_once = 1
|
||||
doc = frappe.get_doc("Blog Post", "_test-blog-post-1")
|
||||
doc.title = "New"
|
||||
self.assertRaises(frappe.CannotChangeConstantError, doc.save)
|
||||
blog_post.get_field("title").set_only_once = 0
|
||||
|
||||
def test_user_permission_doctypes(self):
|
||||
frappe.permissions.add_user_permission("Blog Category", "_Test Blog Category 1",
|
||||
"test2@example.com")
|
||||
frappe.permissions.add_user_permission("Blogger", "_Test Blogger 1",
|
||||
"test2@example.com")
|
||||
|
||||
frappe.set_user("test2@example.com")
|
||||
|
||||
frappe.db.sql("""update `tabDocPerm` set user_permission_doctypes=%s
|
||||
where parent='Blog Post' and permlevel=0 and apply_user_permissions=1
|
||||
and `read`=1""", json.dumps(["Blogger"]))
|
||||
|
||||
frappe.model.meta.clear_cache("Blog Post")
|
||||
|
||||
doc = frappe.get_doc("Blog Post", "_test-blog-post")
|
||||
self.assertFalse(doc.has_permission("read"))
|
||||
|
||||
doc = frappe.get_doc("Blog Post", "_test-blog-post-2")
|
||||
self.assertTrue(doc.has_permission("read"))
|
||||
|
||||
frappe.model.meta.clear_cache("Blog Post")
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@
|
|||
"precision": ""
|
||||
},
|
||||
{
|
||||
"description": "In JSON as <pre>[{\"title\":\"Jobs\", \"name\":\"jobs\"}]</pre>",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@
|
|||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"description": "An icon file with .ico extension. Should be 16 x 16 px. Generated using a favicon generator. [<a href=\"http://favicon-generator.org/\" target=\"_blank\">favicon-generator.org</a>]",
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 <a href=\"https://www.google.com/fonts/\" target=\"_blank\">Google Web Font</a> 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 <a href=\"https://www.google.com/fonts/\" target=\"_blank\">Google Web Font</a> 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": ""
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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("");
|
||||
|
||||
|
|
|
|||
|
|
@ -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. <br>Docstatus Options: 0 is\"Saved\", 1 is \"Submitted\" and 2 is \"Cancelled\"",
|
||||
"fieldname": "states",
|
||||
"fieldtype": "Table",
|
||||
"label": "Document States",
|
||||
"options": "Workflow Document State",
|
||||
"permlevel": 0,
|
||||
"description": "All possible Workflow States and roles of the workflow. \nDocstatus Options: 0 is\"Saved\", 1 is \"Submitted\" and 2 is \"Cancelled\"",
|
||||
"fieldname": "states",
|
||||
"fieldtype": "Table",
|
||||
"label": "Document States",
|
||||
"options": "Workflow Document State",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "Rules for how states are transitions, like next state and which role is allowed to change state etc.",
|
||||
"fieldname": "transition_rules",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Transition Rules",
|
||||
"description": "Rules for how states are transitions, like next state and which role is allowed to change state etc.",
|
||||
"fieldname": "transition_rules",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Transition Rules",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"description": "Rules defining transition of state in the workflow.",
|
||||
"fieldname": "transitions",
|
||||
"fieldtype": "Table",
|
||||
"label": "Transitions",
|
||||
"options": "Workflow Transition",
|
||||
"permlevel": 0,
|
||||
"description": "Rules defining transition of state in the workflow.",
|
||||
"fieldname": "transitions",
|
||||
"fieldtype": "Table",
|
||||
"label": "Transitions",
|
||||
"options": "Workflow Transition",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"default": "workflow_state",
|
||||
"description": "Field that represents the Workflow State of the transaction (if field is not present, a new hidden Custom Field will be created)",
|
||||
"fieldname": "workflow_state_field",
|
||||
"fieldtype": "Data",
|
||||
"label": "Workflow State Field",
|
||||
"default": "workflow_state",
|
||||
"description": "Field that represents the Workflow State of the transaction (if field is not present, a new hidden Custom Field will be created)",
|
||||
"fieldname": "workflow_state_field",
|
||||
"fieldtype": "Data",
|
||||
"label": "Workflow State Field",
|
||||
"permlevel": 0
|
||||
}
|
||||
],
|
||||
"icon": "icon-random",
|
||||
"idx": 1,
|
||||
"modified": "2015-02-05 05:11:49.280959",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Workflow",
|
||||
"name": "Workflow",
|
||||
"owner": "Administrator",
|
||||
],
|
||||
"icon": "icon-random",
|
||||
"idx": 1,
|
||||
"modified": "2015-07-27 01:00:32.901851",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Workflow",
|
||||
"name": "Workflow",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
setup.py
2
setup.py
|
|
@ -1,6 +1,6 @@
|
|||
from setuptools import setup, find_packages
|
||||
|
||||
version = "5.1.3"
|
||||
version = "5.1.4"
|
||||
|
||||
with open("requirements.txt", "r") as f:
|
||||
install_requires = f.readlines()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue