Merge pull request #483 from frappe/model-cleanup

Model cleanup
This commit is contained in:
Anand Doshi 2014-04-10 11:39:13 +05:30
commit c7073cabab
386 changed files with 12607 additions and 15171 deletions

View file

@ -3,7 +3,6 @@ include requirements.txt
include *.json
include *.md
include *.py
include *.txt
recursive-include frappe *.css
recursive-include frappe *.dat
recursive-include frappe *.eot
@ -22,5 +21,4 @@ recursive-include frappe *.swf
recursive-include frappe *.ttf
recursive-include frappe *.woff
recursive-include frappe *.xml
recursive-include frappe *.txt
recursive-exclude * *.pyc

View file

@ -15,7 +15,6 @@ import os, sys, importlib, inspect
import json
import semantic_version
from frappe.core.doctype.print_format.print_format import get_html as get_print_html
from .exceptions import *
local = Local()
@ -53,13 +52,13 @@ def get_lang_dict(fortype, name=None):
return {}
from frappe.translate import get_dict
return get_dict(fortype, name)
def set_user_lang(user, user_language=None):
from frappe.translate import get_lang_dict
if not user_language:
user_language = db.get_value("User", user, "language")
if user_language:
lang_dict = get_lang_dict()
if user_language in lang_dict:
@ -89,16 +88,16 @@ def init(site, sites_path=None):
if not sites_path:
sites_path = '.'
local.error_log = []
local.site = site
local.sites_path = sites_path
local.site_path = os.path.join(sites_path, site)
local.message_log = []
local.debug_log = []
local.response = _dict({})
local.lang = "en"
local.request_method = request.method if request else None
local.response = _dict({"docs":[]})
local.conf = _dict(get_site_config())
local.initialised = True
local.flags = _dict({})
@ -111,33 +110,42 @@ def init(site, sites_path=None):
local.test_objects = {}
local.jenv = None
local.jloader =None
local.meta = {}
local.cache = {}
setup_module_map()
def connect(site=None, db_name=None):
from database import Database
if site:
init(site)
local.db = Database(user=db_name or local.conf.db_name)
local.form_dict = _dict()
local.session = _dict()
set_user("Administrator")
def get_site_config(sites_path=None, site_path=None):
config = {}
sites_path = sites_path or getattr(local, "sites_path", None)
site_path = site_path or getattr(local, "site_path", None)
if sites_path:
common_site_config = os.path.join(sites_path, "common_site_config.json")
if os.path.exists(common_site_config):
config.update(get_file_json(common_site_config))
if site_path:
site_config = os.path.join(site_path, "site_config.json")
if os.path.exists(site_config):
config.update(get_file_json(site_config))
return _dict(config)
def destroy():
"""closes connection and releases werkzeug local"""
if db:
db.close()
release_local(local)
_memc = None
@ -158,14 +166,14 @@ def errprint(msg):
from utils import cstr
if not request:
print cstr(msg)
error_log.append(cstr(msg))
def log(msg):
if not request:
if conf.get("logging") or False:
print repr(msg)
from utils import cstr
debug_log.append(cstr(msg))
@ -179,18 +187,18 @@ def msgprint(msg, small=0, raise_exception=0, as_table=False):
raise raise_exception, msg
else:
raise ValidationError, msg
if flags.mute_messages:
_raise_exception()
return
from utils import cstr
if as_table and type(msg) in (list, tuple):
msg = '<table border="1px" style="border-collapse: collapse" cellpadding="2px">' + ''.join(['<tr>'+''.join(['<td>%s</td>' % c for c in r])+'</tr>' for r in msg]) + '</table>'
if flags.print_messages:
print "Message: " + repr(msg)
message_log.append((small and '__small:' or '')+cstr(msg or ''))
_raise_exception()
@ -199,20 +207,13 @@ def throw(msg, exc=ValidationError):
def create_folder(path):
if not os.path.exists(path): os.makedirs(path)
def connect(site=None, db_name=None):
from database import Database
if site:
init(site)
local.db = Database(user=db_name or local.conf.db_name)
local.response = _dict()
local.form_dict = _dict()
local.session = _dict()
set_user("Administrator")
def set_user(username):
from frappe.utils.user import User
local.session["user"] = username
local.session.user = username
local.session.sid = username
local.cache = {}
local.session.data = {}
local.user = User(username)
local.restrictions = None
local.user_perms = {}
@ -233,23 +234,23 @@ guest_methods = []
def whitelist(allow_guest=False):
"""
decorator for whitelisting a function
Note: if the function is allowed to be accessed by a guest user,
it must explicitly be marked as allow_guest=True
for specific roles, set allow_roles = ['Administrator'] etc.
"""
def innerfn(fn):
global whitelisted, guest_methods
whitelisted.append(fn)
if allow_guest:
guest_methods.append(fn)
return fn
return innerfn
def only_for(roles):
if not isinstance(roles, (tuple, list)):
roles = (roles,)
@ -257,13 +258,13 @@ def only_for(roles):
myroles = set(get_roles())
if not roles.intersection(myroles):
raise PermissionError
def clear_cache(user=None, doctype=None):
"""clear cache"""
import frappe.sessions
if doctype:
import frappe.model.doctype
frappe.model.doctype.clear_cache(doctype)
import frappe.model.meta
frappe.model.meta.clear_cache(doctype)
reset_metadata_version()
elif user:
frappe.sessions.clear_cache(user)
@ -281,7 +282,7 @@ def get_roles(username=None):
return local.user.get_roles()
else:
return User(username).get_roles()
def has_permission(doctype, ptype="read", refdoc=None):
import frappe.permissions
return frappe.permissions.has_permission(doctype, ptype, refdoc)
@ -298,80 +299,46 @@ def clear_perms(doctype):
def reset_perms(doctype):
clear_perms(doctype)
reload_doc(db.get_value("DocType", doctype, "module"),
reload_doc(db.get_value("DocType", doctype, "module"),
"DocType", doctype, force=True)
def generate_hash(txt=None):
"""Generates random hash for session id"""
import hashlib, time
return hashlib.sha224((txt or "") + str(time.time())).hexdigest()
return hashlib.sha224((txt or "") + repr(time.time())).hexdigest()
def reset_metadata_version():
v = generate_hash()
cache().set_value("metadata_version", v)
return v
def get_obj(dt = None, dn = None, doc=None, doclist=None, with_children = True):
from frappe.model.code import get_obj
return get_obj(dt, dn, doc, doclist, with_children)
def doc(doctype=None, name=None, fielddata=None):
from frappe.model.doc import Document
return Document(doctype, name, fielddata)
def new_doc(doctype, parent_doc=None, parentfield=None):
from frappe.model.create_new import get_new_doc
return get_new_doc(doctype, parent_doc, parentfield)
def new_bean(doctype):
from frappe.model.create_new import get_new_doc
return bean([get_new_doc(doctype)])
def doclist(lst=None):
from frappe.model.doclist import DocList
return DocList(lst)
def bean(doctype=None, name=None, copy=None):
"""return an instance of the object, wrapped as a Bean (frappe.model.bean)"""
from frappe.model.bean import Bean
if copy:
return Bean(copy_doclist(copy))
else:
return Bean(doctype, name)
def set_value(doctype, docname, fieldname, value):
import frappe.client
return frappe.client.set_value(doctype, docname, fieldname, value)
def get_doclist(doctype, name=None):
return bean(doctype, name).doclist
def get_doc(arg1, arg2=None):
import frappe.model.document
return frappe.model.document.get_doc(arg1, arg2)
def get_doctype(doctype, processed=False):
import frappe.model.doctype
return frappe.model.doctype.get(doctype, processed)
def get_meta(doctype, cached=True):
import frappe.model.meta
return frappe.model.meta.get_meta(doctype, cached=cached)
def delete_doc(doctype=None, name=None, doclist = None, force=0, ignore_doctypes=None,
for_reload=False, ignore_permissions=False):
def delete_doc(doctype=None, name=None, force=0, ignore_doctypes=None, for_reload=False, ignore_permissions=False):
import frappe.model.delete_doc
if not ignore_doctypes:
ignore_doctypes = []
if isinstance(name, list):
for n in name:
frappe.model.delete_doc.delete_doc(doctype, n, doclist, force, ignore_doctypes,
for_reload, ignore_permissions)
frappe.model.delete_doc.delete_doc(doctype, n, force, ignore_doctypes, for_reload, ignore_permissions)
else:
frappe.model.delete_doc.delete_doc(doctype, name, doclist, force, ignore_doctypes,
for_reload, ignore_permissions)
frappe.model.delete_doc.delete_doc(doctype, name, force, ignore_doctypes, for_reload, ignore_permissions)
def reload_doc(module, dt=None, dn=None, force=False):
import frappe.modules
@ -397,21 +364,21 @@ def get_module_path(module, *joins):
def get_app_path(app_name, *joins):
return get_pymodule_path(app_name, *joins)
def get_site_path(*joins):
return os.path.join(local.site_path, *joins)
def get_pymodule_path(modulename, *joins):
joins = [scrub(part) for part in joins]
return os.path.join(os.path.dirname(get_module(scrub(modulename)).__file__), *joins)
def get_module_list(app_name):
return get_file_items(os.path.join(os.path.dirname(get_module(app_name).__file__), "modules.txt"))
def get_all_apps(with_frappe=False, with_internal_apps=True, sites_path=None):
if not sites_path:
sites_path = local.sites_path
apps = get_file_items(os.path.join(sites_path, "apps.txt"), raise_not_found=True)
if with_internal_apps:
apps.extend(get_file_items(os.path.join(local.site_path, "apps.txt")))
@ -440,7 +407,7 @@ def get_hooks(hook=None, app_name=None):
hooks = _dict(load_app_hooks(app_name))
else:
hooks = _dict(cache().get_value("app_hooks", load_app_hooks))
if hook:
return hooks.get(hook) or []
else:
@ -448,11 +415,11 @@ def get_hooks(hook=None, app_name=None):
def setup_module_map():
_cache = cache()
if conf.db_name:
local.app_modules = _cache.get_value("app_modules")
local.module_app = _cache.get_value("module_app")
if not local.app_modules:
local.module_app, local.app_modules = {}, {}
for app in get_all_apps(True):
@ -461,16 +428,16 @@ def setup_module_map():
for module in get_module_list(app):
local.module_app[module] = app
local.app_modules[app].append(module)
if conf.db_name:
_cache.set_value("app_modules", local.app_modules)
_cache.set_value("module_app", local.module_app)
def get_file_items(path, raise_not_found=False):
content = read_file(path, raise_not_found=raise_not_found)
if content:
return [p.strip() for p in content.splitlines() if p.strip() and not p.startswith("#")]
else:
else:
return []
def get_file_json(path):
@ -480,7 +447,7 @@ def get_file_json(path):
def read_file(path, raise_not_found=False):
from frappe.utils import cstr
if os.path.exists(path):
with open(path, "r") as f:
with open(path, "r") as f:
return cstr(f.read())
elif raise_not_found:
raise IOError("{} Not Found".format(path))
@ -491,7 +458,7 @@ def get_attr(method_string):
modulename = '.'.join(method_string.split('.')[:-1])
methodname = method_string.split('.')[-1]
return getattr(get_module(modulename), methodname)
def call(fn, *args, **kwargs):
if hasattr(fn, 'fnargs'):
fnargs = fn.fnargs
@ -506,7 +473,7 @@ def call(fn, *args, **kwargs):
def make_property_setter(args):
args = _dict(args)
bean([{
get_doc({
'doctype': "Property Setter",
'doctype_or_field': args.doctype_or_field or "DocField",
'doc_type': args.doctype,
@ -515,43 +482,31 @@ def make_property_setter(args):
'value': args.value,
'property_type': args.property_type or "Data",
'__islocal': 1
}]).save()
}).save()
def get_application_home_page(user='Guest'):
"""get home page for user"""
hpl = db.sql("""select home_page
from `tabDefault Home Page`
where parent='Control Panel'
and role in ('%s') order by idx asc limit 1""" % "', '".join(get_roles(user)))
if hpl:
return hpl[0][0]
else:
return db.get_value("Control Panel", None, "home_page")
def import_doclist(path, ignore_links=False, ignore_insert=False, insert=False):
def import_doc(path, ignore_links=False, ignore_insert=False, insert=False):
from frappe.core.page.data_import_tool import data_import_tool
data_import_tool.import_doclist(path, ignore_links=ignore_links, ignore_insert=ignore_insert, insert=insert)
data_import_tool.import_doc(path, ignore_links=ignore_links, ignore_insert=ignore_insert, insert=insert)
def copy_doclist(in_doclist):
new_doclist = []
parent_doc = None
for i, d in enumerate(in_doclist):
is_dict = False
if isinstance(d, dict):
is_dict = True
values = _dict(d.copy())
else:
values = _dict(d.fields.copy())
newd = new_doc(values.doctype, parent_doc=(None if i==0 else parent_doc), parentfield=values.parentfield)
newd.fields.update(values)
if i==0:
parent_doc = newd
new_doclist.append(newd.fields if is_dict else newd)
return doclist(new_doclist)
def copy_doc(doc):
import copy
if not isinstance(doc, dict):
d = doc.as_dict()
else:
d = doc
newdoc = get_doc(copy.deepcopy(d))
newdoc.name = None
newdoc.set("__islocal", 1)
newdoc.owner = None
newdoc.creation = None
for d in newdoc.get_all_children():
d.name = None
d.parent = None
d.set("__islocal", 1)
d.owner = None
d.creation = None
return newdoc
def compare(val1, condition, val2):
import frappe.utils
@ -565,7 +520,7 @@ def respond_as_web_page(title, html, success=None, http_status_code=None):
local.response['page_name'] = 'message.html'
if http_status_code:
local.response['http_status_code'] = http_status_code
def build_match_conditions(doctype, as_condition=True):
import frappe.widgets.reportview
return frappe.widgets.reportview.build_match_conditions(doctype, as_condition)
@ -577,7 +532,7 @@ def get_list(doctype, filters=None, fields=None, docstatus=None,
return frappe.model.db_query.DatabaseQuery(doctype).execute(filters=filters, fields=fields, docstatus=docstatus,
group_by=group_by, order_by=order_by, limit_start=limit_start, limit_page_length=limit_page_length,
as_list=as_list, debug=debug, ignore_permissions=ignore_permissions)
run_query = get_list
def get_jenv():
@ -594,34 +549,34 @@ def get_jenv():
"frappe.utils": frappe.utils,
"_": _
})
local.jenv = jenv
return local.jenv
def get_jloader():
if not local.jloader:
from jinja2 import ChoiceLoader, PackageLoader
apps = get_installed_apps()
apps.remove("frappe")
local.jloader = ChoiceLoader([PackageLoader(app, ".") \
for app in apps + ["frappe"]])
return local.jloader
def set_filters(jenv):
from frappe.utils import global_date_format
from frappe.website.utils import get_hex_shade
from markdown2 import markdown
from json import dumps
jenv.filters["global_date_format"] = global_date_format
jenv.filters["markdown"] = markdown
jenv.filters["json"] = dumps
jenv.filters["get_hex_shade"] = get_hex_shade
# load jenv_filters from hooks.txt
for app in get_all_apps(True):
for jenv_filter in (get_hooks(app_name=app).jenv_filter or []):
@ -630,14 +585,23 @@ def set_filters(jenv):
def get_template(path):
return get_jenv().get_template(path)
def get_website_route(doctype, name):
return db.get_value("Website Route", {"ref_doctype": doctype, "docname": name})
def add_version(doclist):
bean({
def add_version(doc):
get_doc({
"doctype": "Version",
"ref_doctype": doclist[0].get("doctype"),
"docname": doclist[0].get("name"),
"doclist_json": json.dumps([d.fields for d in doclist])
"ref_doctype": doc.doctype,
"docname": doc.name,
"doclist_json": json.dumps(doc.as_dict(), indent=1, sort_keys=True)
}).insert(ignore_permissions=True)
def get_test_records(doctype):
from frappe.modules import get_doctype_module, get_module_path
path = os.path.join(get_module_path(get_doctype_module(doctype)), "doctype", scrub(doctype), "test_records.json")
if os.path.exists(path):
with open(path, "r") as f:
return json.loads(f.read())
else:
return []

View file

@ -41,17 +41,17 @@ def handle():
elif call=="resource":
if "run_method" in frappe.local.form_dict:
bean = frappe.bean(doctype, name)
doc = frappe.get_doc(doctype, name)
if frappe.local.request.method=="GET":
if not bean.has_permission("read"):
if not doc.has_permission("read"):
frappe.throw("No Permission", frappe.PermissionError)
bean.run_method(frappe.local.form_dict.run_method, **frappe.local.form_dict)
doc.run_method(frappe.local.form_dict.run_method, **frappe.local.form_dict)
if frappe.local.request.method=="POST":
if not bean.has_permission("write"):
if not doc.has_permission("write"):
frappe.throw("No Permission", frappe.PermissionError)
bean.run_method(frappe.local.form_dict.run_method, **frappe.local.form_dict)
doc.run_method(frappe.local.form_dict.run_method, **frappe.local.form_dict)
frappe.db.commit()
else:
@ -63,7 +63,7 @@ def handle():
if frappe.local.request.method=="PUT":
frappe.local.response.update({
"doclist":frappe.client.save(frappe.local.form_dict.doclist)})
"doclist":frappe.client.save(frappe.local.form_dict)})
frappe.db.commit()
if frappe.local.request.method=="DELETE":
@ -79,7 +79,7 @@ def handle():
if frappe.local.request.method=="POST":
frappe.local.response.update({
"doclist": frappe.client.insert(frappe.local.form_dict.doclist)})
"doclist": frappe.client.insert(frappe.local.form_dict)})
frappe.db.commit()
else:
raise frappe.DoesNotExistError

View file

@ -68,7 +68,8 @@ def application(request):
frappe.DoesNotExistError,
frappe.DuplicateEntryError,
frappe.OutgoingEmailError,
frappe.ValidationError), e:
frappe.ValidationError,
frappe.UnsupportedMediaType), e:
if frappe.local.is_ajax:
response = frappe.utils.response.report_error(e.http_status_code)
@ -118,7 +119,7 @@ def serve(port=8000, profile=False, site=None, sites_path='.'):
from werkzeug.serving import run_simple
if profile:
application = ProfilerMiddleware(application)
application = ProfilerMiddleware(application, sort_by=('tottime', 'calls'))
if not os.environ.get('NO_STATICS'):
application = SharedDataMiddleware(application, {

View file

@ -1,5 +1,5 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# MIT License. See license.txt
from __future__ import unicode_literals
"""
@ -8,7 +8,6 @@ bootstrap client session
import frappe
import frappe.defaults
import frappe.model.doc
import frappe.widgets.page
import json
@ -20,21 +19,17 @@ def get_bootinfo():
# user
get_user(bootinfo)
# control panel
cp = frappe.model.doc.getsingle('Control Panel')
# system info
bootinfo['control_panel'] = frappe._dict(cp.copy())
bootinfo['sysdefaults'] = frappe.defaults.get_defaults()
bootinfo['server_date'] = frappe.utils.nowdate()
bootinfo["send_print_in_body_and_attachment"] = frappe.db.get_value("Outgoing Email Settings",
bootinfo["send_print_in_body_and_attachment"] = frappe.db.get_value("Outgoing Email Settings",
None, "send_print_in_body_and_attachment")
if frappe.session['user'] != 'Guest':
bootinfo['user_info'] = get_fullnames()
bootinfo['sid'] = frappe.session['sid'];
# home page
bootinfo.modules = {}
for app in frappe.get_installed_apps():
@ -45,11 +40,11 @@ def get_bootinfo():
bootinfo.module_app = frappe.local.module_app
bootinfo.hidden_modules = frappe.db.get_global("hidden_modules")
bootinfo.doctype_icons = dict(frappe.db.sql("""select name, icon from
bootinfo.doctype_icons = dict(frappe.db.sql("""select name, icon from
tabDocType where ifnull(icon,'')!=''"""))
bootinfo.doctype_icons.update(dict(frappe.db.sql("""select name, icon from
bootinfo.doctype_icons.update(dict(frappe.db.sql("""select name, icon from
tabPage where ifnull(icon,'')!=''""")))
add_home_page(bootinfo, doclist)
add_allowed_pages(bootinfo)
load_translations(bootinfo)
@ -58,23 +53,16 @@ def get_bootinfo():
# ipinfo
if frappe.session['data'].get('ipinfo'):
bootinfo['ipinfo'] = frappe.session['data']['ipinfo']
# add docs
bootinfo['docs'] = doclist
for method in hooks.boot_session or []:
frappe.get_attr(method)(bootinfo)
from frappe.model.utils import compress
bootinfo['docs'] = compress(bootinfo['docs'])
if bootinfo.lang:
bootinfo.lang = unicode(bootinfo.lang)
bootinfo.metadata_version = frappe.cache().get_value("metadata_version")
if not bootinfo.metadata_version:
bootinfo.metadata_version = frappe.reset_metadata_version()
return bootinfo
def load_conf_settings(bootinfo):
@ -86,25 +74,25 @@ def add_allowed_pages(bootinfo):
roles = frappe.get_roles()
bootinfo.page_info = dict(frappe.db.sql("""select distinct parent, modified from `tabPage Role`
where role in (%s)""" % ', '.join(['%s']*len(roles)), roles))
# pages where role is not set are also allowed
bootinfo.page_info.update(dict(frappe.db.sql("""select parent, modified
from `tabPage` where
(select count(*) from `tabPage Role`
from `tabPage` where
(select count(*) from `tabPage Role`
where `tabPage Role`.parent=tabPage.name) = 0""")))
def load_translations(bootinfo):
frappe.set_user_lang(frappe.session.user)
if frappe.lang != 'en':
bootinfo["__messages"] = frappe.get_lang_dict("include")
bootinfo["lang"] = frappe.lang
def get_fullnames():
"""map of user fullnames"""
ret = frappe.db.sql("""select name,
concat(ifnull(first_name, ''),
if(ifnull(last_name, '')!='', ' ', ''), ifnull(last_name, '')),
ret = frappe.db.sql("""select name,
concat(ifnull(first_name, ''),
if(ifnull(last_name, '')!='', ' ', ''), ifnull(last_name, '')),
user_image, gender, email
from tabUser where ifnull(enabled, 0)=1""", as_list=1)
d = {}
@ -113,7 +101,7 @@ def get_fullnames():
r[2] = '/assets/frappe/images/ui/avatar.png'
else:
r[2] = r[2]
d[r[0]]= {'fullname': r[1], 'image': r[2], 'gender': r[3],
'email': r[4] or r[0]}
@ -124,24 +112,24 @@ def get_startup_js():
for method in frappe.get_hooks().startup_js or []:
startup_js.append(frappe.get_attr(method)() or "")
return "\n".join(startup_js)
def get_user(bootinfo):
"""get user info"""
bootinfo['user'] = frappe.user.load_user()
def add_home_page(bootinfo, doclist):
def add_home_page(bootinfo, docs):
"""load home page"""
if frappe.session.user=="Guest":
return
home_page = frappe.get_application_home_page(frappe.session.user)
home_page = frappe.db.get_default("desktop:home_page")
try:
page_doclist = frappe.widgets.page.get(home_page)
page = frappe.widgets.page.get(home_page)
except (frappe.DoesNotExistError, frappe.PermissionError), e:
page_doclist = frappe.widgets.page.get('desktop')
bootinfo['home_page_html'] = page_doclist[0].content
bootinfo['home_page'] = page_doclist[0].name
doclist += page_doclist
frappe.message_log.pop()
page = frappe.widgets.page.get('desktop')
bootinfo['home_page'] = page.name
docs.append(page)

View file

@ -51,9 +51,9 @@ class SiteRouter(object):
def route_for_task(self, task, args=None, kwargs=None):
if hasattr(frappe.local, 'site'):
if kwargs and kwargs.get("event", "").endswith("_long"):
get_queue(frappe.local.site, LONGJOBS_PREFIX)
return get_queue(frappe.local.site, LONGJOBS_PREFIX)
else:
get_queue(frappe.local.site)
return get_queue(frappe.local.site)
return None

View file

@ -25,9 +25,9 @@ def main():
else:
parsed_args["sites_path"] = os.environ.get("SITES_PATH", ".")
sites_path = parsed_args.get("sites_path")
if not parsed_args.get("make_app"):
if parsed_args.get("site")=="all":
for site in get_sites(parsed_args["sites_path"]):
print "\nRunning", fn, "for", site
@ -35,20 +35,20 @@ def main():
args = parsed_args.copy()
args["site"] = site
frappe.init(site, sites_path=sites_path)
run(fn, args)
return run(fn, args)
else:
site = get_site(parsed_args)
if fn not in site_arg_optional and not site:
print 'site argument required'
exit(1)
return 1
elif site:
frappe.init(site, sites_path=sites_path)
else:
# site argument optional
frappe.init("", sites_path=sites_path)
run(fn, parsed_args)
return run(fn, parsed_args)
else:
run(fn, parsed_args)
return run(fn, parsed_args)
def cmd(fn):
def new_fn(*args, **kwargs):
@ -59,25 +59,39 @@ def cmd(fn):
# should not pass an argument more than once
if i >= len(args) and a in kwargs:
new_kwargs[a] = kwargs.get(a)
return fn(*args, **new_kwargs)
return new_fn
def run(fn, args):
import cProfile, pstats, StringIO
use_profiler = args.get("profile") and fn!="serve"
if use_profiler:
pr = cProfile.Profile()
pr.enable()
if isinstance(args.get(fn), (list, tuple)):
out = globals().get(fn)(*args.get(fn), **args)
else:
out = globals().get(fn)(**args)
if use_profiler:
pr.disable()
s = StringIO.StringIO()
ps = pstats.Stats(pr, stream=s).sort_stats('tottime', 'ncalls')
ps.print_stats()
print s.getvalue()
return out
def get_function(args):
for fn, val in args.items():
if (val or isinstance(val, list)) and globals().get(fn):
return fn
def get_sites(sites_path=None):
import os
if not sites_path:
@ -86,26 +100,28 @@ def get_sites(sites_path=None):
if not os.path.islink(os.path.join(sites_path, site))
and os.path.isdir(os.path.join(sites_path, site))
and not site in ('assets',)]
def setup_parser():
import argparse
parser = argparse.ArgumentParser(description="Run frappe utility functions")
setup_install(parser)
setup_utilities(parser)
setup_translation(parser)
setup_test(parser)
parser.add_argument("site", nargs="?")
# common
parser.add_argument("-f", "--force", default=False, action="store_true",
help="Force execution where applicable (look for [-f] in help)")
parser.add_argument("--quiet", default=True, action="store_false", dest="verbose",
parser.add_argument("--verbose", default=False, action="store_true",
help="Show verbose output (where applicable)")
parser.add_argument("--quiet", default=True, action="store_false",
help="Do not show verbose output (where applicable)")
return parser.parse_args()
def setup_install(parser):
parser.add_argument("--make_app", default=False, action="store_true",
help="Make a new application with boilerplate")
@ -119,11 +135,11 @@ def setup_install(parser):
help="Add these app(s) to Installed Apps")
parser.add_argument("--root-password", nargs=1,
help="Root password for new app")
parser.add_argument("--reinstall", default=False, action="store_true",
parser.add_argument("--reinstall", default=False, action="store_true",
help="Install a fresh app in db_name specified in conf.py")
parser.add_argument("--restore", metavar=("DB-NAME", "SQL-FILE"), nargs=2,
help="Restore from an sql file")
parser.add_argument("--add_system_manager", nargs="+",
parser.add_argument("--add_system_manager", nargs="+",
metavar=("EMAIL", "[FIRST-NAME] [LAST-NAME]"), help="Add a user with all roles")
def setup_test(parser):
@ -135,6 +151,8 @@ def setup_test(parser):
help="Run command for specified doctype")
parser.add_argument("-m", "--module", metavar="MODULE", nargs=1,
help="Run command for specified module")
parser.add_argument("--tests", metavar="TEST FUNCTION", nargs="*",
help="Run one or more specific test functions")
def setup_utilities(parser):
# update
@ -149,10 +167,10 @@ def setup_utilities(parser):
help="Reload all doctypes, pages, etc. using txt files [-f]")
parser.add_argument("--update_all_sites", nargs="*", metavar=("REMOTE", "BRANCH"),
help="Perform git pull, run patches, sync schema and rebuild files/translations")
parser.add_argument("--reload_doc", nargs=3,
parser.add_argument("--reload_doc", nargs=3,
metavar=('"MODULE"', '"DOCTYPE"', '"DOCNAME"'))
# build
parser.add_argument("-b", "--build", default=False, action="store_true",
help="Minify + concatenate JS and CSS files, build translations")
@ -160,7 +178,7 @@ def setup_utilities(parser):
help="Make copy of assets instead of symlinks")
parser.add_argument("-w", "--watch", default=False, action="store_true",
help="Watch and concatenate JS and CSS files as and when they change")
# misc
parser.add_argument("--backup", default=False, action="store_true",
help="Take backup of database in backup folder [--with_files]")
@ -189,12 +207,12 @@ def setup_utilities(parser):
parser.add_argument("--ipython", action="store_true", help="get ipython shell for a site")
parser.add_argument("--execute", help="execute a function", nargs=1, metavar="FUNCTION")
parser.add_argument("--get_site_status", action="store_true", help="Get site details")
parser.add_argument("--update_site_config", nargs=1,
metavar="site-CONFIG-JSON",
parser.add_argument("--update_site_config", nargs=1,
metavar="site-CONFIG-JSON",
help="Update site_config.json for a given site")
parser.add_argument("--port", default=8000, type=int, help="port for development server")
parser.add_argument("--use", action="store_true", help="Set current site for development.")
# clear
parser.add_argument("--clear_web", default=False, action="store_true",
help="Clear website cache")
@ -206,37 +224,37 @@ def setup_utilities(parser):
help="Clear cache, doctype cache and defaults")
parser.add_argument("--reset_perms", default=False, action="store_true",
help="Reset permissions for all doctypes")
# scheduler
parser.add_argument("--run_scheduler", default=False, action="store_true",
help="Trigger scheduler")
parser.add_argument("--celery", nargs="*", help="Run Celery Commands")
parser.add_argument("--run_scheduler_event", nargs=1,
parser.add_argument("--run_scheduler_event", nargs=1,
metavar="all | daily | weekly | monthly",
help="Run a scheduler event")
# replace
parser.add_argument("--replace", nargs=3,
parser.add_argument("--replace", nargs=3,
metavar=("SEARCH-REGEX", "REPLACE-BY", "FILE-EXTN"),
help="Multi-file search-replace [-f]")
# import/export
parser.add_argument("--export_doc", nargs=2, metavar=('"DOCTYPE"', '"DOCNAME"'))
parser.add_argument("--export_doclist", nargs=3, metavar=("DOCTYPE", "NAME", "PATH"),
parser.add_argument("--export_doclist", nargs=3, metavar=("DOCTYPE", "NAME", "PATH"),
help="""Export doclist as json to the given path, use '-' as name for Singles.""")
parser.add_argument("--export_csv", nargs=2, metavar=("DOCTYPE", "PATH"),
parser.add_argument("--export_csv", nargs=2, metavar=("DOCTYPE", "PATH"),
help="""Dump DocType as csv""")
parser.add_argument("--export_fixtures", default=False, action="store_true",
parser.add_argument("--export_fixtures", default=False, action="store_true",
help="""Export fixtures""")
parser.add_argument("--import_doclist", nargs=1, metavar="PATH",
help="""Import (insert/update) doclist. If the argument is a directory, all files ending with .json are imported""")
parser.add_argument("--import_doc", nargs=1, metavar="PATH",
help="""Import (insert/update) doclist. If the argument is a directory, all files ending with .json are imported""")
def setup_translation(parser):
parser.add_argument("--build_message_files", default=False, action="store_true",
help="Build message files for translation.")
parser.add_argument("--get_untranslated", nargs=2, metavar=("LANG-CODE", "TARGET-FILE-PATH"),
help="""Get untranslated strings for lang.""")
parser.add_argument("--update_translations", nargs=3,
parser.add_argument("--update_translations", nargs=3,
metavar=("LANG-CODE", "UNTRANSLATED-FILE-PATH", "TRANSLATED-FILE-PATH"),
help="""Update translated strings.""")
@ -254,8 +272,10 @@ def use(sites_path):
# install
@cmd
def install(db_name, root_login="root", root_password=None, source_sql=None,
admin_password = 'admin', verbose=True, force=False, site_config=None, reinstall=False):
admin_password = 'admin', verbose=True, force=False, site_config=None, reinstall=False, quiet=False):
from frappe.installer import install_db, install_app, make_site_dirs
verbose = verbose or not quiet
install_db(root_login=root_login, root_password=root_password, db_name=db_name, source_sql=source_sql,
admin_password = admin_password, verbose=verbose, force=force, site_config=site_config, reinstall=reinstall)
make_site_dirs()
@ -263,7 +283,8 @@ def install(db_name, root_login="root", root_password=None, source_sql=None,
frappe.destroy()
@cmd
def install_app(app_name, verbose=False):
def install_app(app_name, verbose=True, quiet=False):
verbose = verbose or not quiet
from frappe.installer import install_app
frappe.connect()
install_app(app_name, verbose=verbose)
@ -280,11 +301,21 @@ def add_to_installed_apps(*apps):
frappe.destroy()
@cmd
def reinstall(verbose=True):
def reinstall(verbose=True, quiet=False):
verbose = verbose or not quiet
try:
frappe.connect()
frappe.clear_cache()
except:
pass
finally:
frappe.db.close()
install(db_name=frappe.conf.db_name, verbose=verbose, force=True, reinstall=True)
@cmd
def restore(db_name, source_sql, verbose=True, force=False):
def restore(db_name, source_sql, verbose=True, force=False, quiet=False):
verbose = verbose or not quiet
install(db_name, source_sql=source_sql, verbose=verbose, force=force)
@cmd
@ -294,7 +325,7 @@ def add_system_manager(email, first_name=None, last_name=None):
frappe.utils.user.add_system_manager(email, first_name, last_name)
frappe.db.commit()
frappe.destroy()
# utilities
@cmd
@ -310,35 +341,37 @@ def update(remote=None, branch=None, reload_gunicorn=False):
subprocess.check_output("killall -HUP gunicorn".split())
@cmd
def latest(verbose=True, rebuild_website_config=True):
def latest(verbose=True, rebuild_website_config=True, quiet=False):
import frappe.modules.patch_handler
import frappe.model.sync
from frappe.website import rebuild_config
from frappe.utils.fixtures import sync_fixtures
import frappe.translate
from frappe.website import statics
verbose = verbose or not quiet
frappe.connect()
try:
# run patches
frappe.local.patch_log_list = []
frappe.modules.patch_handler.run_all()
if verbose:
print "\n".join(frappe.local.patch_log_list)
# sync
frappe.model.sync.sync_all()
frappe.model.sync.sync_all(verbose=verbose)
sync_fixtures()
statics.sync().start()
# build website config if any changes in templates etc.
if rebuild_website_config:
rebuild_config()
statics.sync().start()
sync_fixtures()
frappe.translate.clear_cache()
except frappe.modules.patch_handler.PatchError, e:
print "\n".join(frappe.local.patch_log_list)
raise
@ -346,10 +379,11 @@ def latest(verbose=True, rebuild_website_config=True):
frappe.destroy()
@cmd
def sync_all(force=False):
def sync_all(force=False, verbose=True, quiet=False):
import frappe.model.sync
verbose = verbose or not quiet
frappe.connect()
frappe.model.sync.sync_all(force=force)
frappe.model.sync.sync_all(force=force, verbose=verbose)
frappe.destroy()
@cmd
@ -360,14 +394,15 @@ def patch(patch_module, force=False):
frappe.modules.patch_handler.run_single(patch_module, force=force)
print "\n".join(frappe.local.patch_log_list)
frappe.destroy()
@cmd
def update_all_sites(remote=None, branch=None, verbose=True):
def update_all_sites(remote=None, branch=None, verbose=True, quiet=False):
verbose = verbose or not quiet
pull(remote, branch)
# maybe there are new framework changes, any consequences?
reload(frappe)
build()
for site in get_sites():
frappe.init(site)
@ -392,8 +427,9 @@ def watch():
frappe.build.watch(True)
@cmd
def backup(with_files=False, verbose=True, backup_path_db=None, backup_path_files=None):
def backup(with_files=False, verbose=True, backup_path_db=None, backup_path_files=None, quiet=False):
from frappe.utils.backups import scheduled_backup
verbose = verbose or not quiet
frappe.connect()
odb = scheduled_backup(ignore_files=not with_files, backup_path_db=backup_path_db, backup_path_files=backup_path_files)
if verbose:
@ -441,7 +477,7 @@ def domain(host_url=None):
def make_conf(db_name=None, db_password=None, site_config=None):
from frappe.install_lib.install import make_conf
make_conf(db_name=db_name, db_password=db_password, site_config=site_config)
@cmd
def make_custom_server_script(doctype):
from frappe.core.doctype.custom_script.custom_script import make_custom_server_script_file
@ -470,7 +506,7 @@ def build_sitemap():
frappe.connect()
rebuild_config()
frappe.destroy()
@cmd
def sync_statics():
from frappe.website import statics
@ -478,7 +514,7 @@ def sync_statics():
statics.sync_statics()
frappe.db.commit()
frappe.destroy()
@cmd
def reset_perms():
frappe.connect()
@ -499,7 +535,7 @@ def execute(method):
@cmd
def celery(arg):
import frappe
import frappe
import commands, os
python = commands.getoutput('which python')
os.execv(python, [python, "-m", "frappe.celery_app"] + arg.split())
@ -511,14 +547,14 @@ def run_scheduler_event(event, force=False):
frappe.connect()
frappe.utils.scheduler.trigger(frappe.local.site, event, now=force)
frappe.destroy()
# replace
@cmd
def replace(search_regex, replacement, extn, force=False):
print search_regex, replacement, extn
replace_code('.', search_regex, replacement, extn, force=force)
# import/export
# import/export
@cmd
def export_doc(doctype, docname):
import frappe.modules
@ -532,7 +568,7 @@ def export_doclist(doctype, name, path):
frappe.connect()
data_import_tool.export_json(doctype, name, path)
frappe.destroy()
@cmd
def export_csv(doctype, path):
from frappe.core.page.data_import_tool import data_import_tool
@ -548,12 +584,12 @@ def export_fixtures():
frappe.destroy()
@cmd
def import_doclist(path, force=False):
def import_doc(path, force=False):
from frappe.core.page.data_import_tool import data_import_tool
frappe.connect()
data_import_tool.import_doclist(path, overwrite=force)
data_import_tool.import_doc(path, overwrite=force)
frappe.destroy()
# translation
@cmd
def build_message_files():
@ -589,11 +625,11 @@ def get_remote_and_branch(remote=None, branch=None):
if not (remote and branch):
if not frappe.conf.branch:
raise Exception("Please specify remote and branch")
remote = remote or "origin"
branch = branch or frappe.conf.branch
frappe.destroy()
return remote, branch
@cmd
@ -629,7 +665,7 @@ def set_admin_password(admin_password):
@cmd
def mysql():
import frappe
import frappe
import commands, os
msq = commands.getoutput('which mysql')
os.execv(msq, [msq, '-u', frappe.conf.db_name, '-p'+frappe.conf.db_password, frappe.conf.db_name, '-h', frappe.conf.db_host or "localhost", "-A"])
@ -637,7 +673,7 @@ def mysql():
@cmd
def python(site):
import frappe
import frappe
import commands, os
python = commands.getoutput('which python')
if site:
@ -660,33 +696,21 @@ def smtp_debug_server():
os.execv(python, [python, '-m', "smtpd", "-n", "-c", "DebuggingServer", "localhost:25"])
@cmd
def run_tests(app=None, module=None, doctype=None, verbose=False, profile=False):
def run_tests(app=None, module=None, doctype=None, verbose=False, quiet=True, tests=()):
import frappe.test_runner
verbose = verbose or not quiet
def _run():
ret = frappe.test_runner.main(app and app[0], module and module[0], doctype and doctype[0], verbose)
if len(ret.failures) > 0 or len(ret.errors) > 0:
exit(1)
ret = frappe.test_runner.main(app and app[0], module and module[0], doctype and doctype[0], verbose,
tests=tests)
if profile:
import cProfile, pstats, StringIO
pr = cProfile.Profile()
pr.enable()
_run()
pr.disable()
s = StringIO.StringIO()
sortby = 'cumulative'
ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
ps.print_stats()
print s.getvalue()
else:
_run()
if len(ret.failures) > 0 or len(ret.errors) > 0:
return 1
@cmd
def serve(port=8000, profile=False, sites_path='.', site=None):
import frappe.app
frappe.app.serve(port=port, profile=profile, site=frappe.local.site, sites_path=sites_path)
@cmd
def request(args):
import frappe.handler
@ -696,12 +720,12 @@ def request(args):
frappe.local.form_dict = frappe._dict([a.split("=") for a in args.split("?")[-1].split("&")])
else:
frappe.local.form_dict = frappe._dict()
if args.startswith("/api/method"):
frappe.local.form_dict.cmd = args.split("?")[0].split("/")[-1]
frappe.handler.execute_cmd(frappe.form_dict.cmd)
print frappe.response
frappe.destroy()
@ -722,7 +746,7 @@ def replace_code(start, txt1, txt2, extn, search=None, force=False):
fpath = os.path.join(wt[0], fn)
with open(fpath, 'r') as f:
content = f.read()
if re.search(search, content):
res = search_replace_with_prompt(fpath, txt1, txt2, force)
if res == 'skip':
@ -757,13 +781,15 @@ def search_replace_with_prompt(fpath, txt1, txt2, force=False):
print colored('Updated', 'green')
@cmd
def get_site_status(verbose=False):
def get_site_status(verbose=False, quiet=True):
import frappe
import frappe.utils
from frappe.utils.user import get_system_managers
from frappe.core.doctype.user.user import get_total_users, get_active_users, \
get_website_users, get_active_website_users
verbose = verbose or not quiet
import json
frappe.connect()
ret = {
@ -777,40 +803,39 @@ def get_site_status(verbose=False):
'disk_usage': frappe.utils.get_disk_usage(),
'working_directory': frappe.local.site_path
}
# country, timezone, industry
control_panel_details = frappe.db.get_value("Control Panel", "Control Panel",
["country", "time_zone", "industry"], as_dict=True)
if control_panel_details:
ret.update(control_panel_details)
for key in ["country", "time_zone", "industry"]:
ret[key] = frappe.db.get_default(key)
# basic usage/progress analytics
for doctype in ("Company", "Customer", "Item", "Quotation", "Sales Invoice",
"Journal Voucher", "Stock Ledger Entry"):
key = doctype.lower().replace(" ", "_") + "_exists"
ret[key] = 1 if frappe.db.count(doctype) else 0
frappe.destroy()
if verbose:
print json.dumps(ret, indent=1, sort_keys=True)
return ret
@cmd
def update_site_config(site_config, verbose=False):
def update_site_config(site_config, verbose=False, quiet=True):
import json
verbose = verbose or not quiet
if isinstance(site_config, basestring):
site_config = json.loads(site_config)
config = frappe.get_site_config()
config.update(site_config)
site_config_path = os.path.join(frappe.local.site_path, "site_config.json")
with open(site_config_path, "w") as f:
json.dump(config, f, indent=1, sort_keys=True)
frappe.destroy()
@cmd
@ -836,14 +861,14 @@ def bump(repo, bump_type):
elif version_type == 'patch':
v.patch += 1
return unicode(v)
def add_tag(repo_path, version):
import git
repo = git.Repo(repo_path)
repo.index.add(['config.json'])
repo.index.commit('bumped to version {}'.format(version))
repo.create_tag('v' + version, repo.head)
def update_framework_requirement(version):
with open('app/config.json') as f:
config = json.load(f)
@ -875,7 +900,9 @@ def bump(repo, bump_type):
update_framework_requirement(new_version)
bump('app', bump_type)
if __name__=="__main__":
main()
out = main()
if out and out==1:
exit(1)

View file

@ -14,7 +14,7 @@ def get(doctype, name=None, filters=None):
name = frappe.db.get_value(doctype, json.loads(filters))
if not name:
raise Exception, "No document found for given filters"
return [d.fields for d in frappe.bean(doctype, name).doclist]
return frappe.get_doc(doctype, name).as_dict()
@frappe.whitelist()
def get_value(doctype, fieldname, filters=None, as_dict=True, debug=False):
@ -32,16 +32,16 @@ def set_value(doctype, name, fieldname, value):
doc = frappe.db.get_value(doctype, name, ["parenttype", "parent"], as_dict=True)
if doc and doc.parent:
bean = frappe.bean(doc.parenttype, doc.parent)
child = bean.doclist.getone({"doctype": doctype, "name": name})
child.fields[fieldname] = value
doc = frappe.get_doc(doc.parenttype, doc.parent)
child = doc.getone({"doctype": doctype, "name": name})
child.set(fieldname, value)
else:
bean = frappe.bean(doctype, name)
bean.doc.fields[fieldname] = value
doc = frappe.get_doc(doctype, name)
doc.set(fieldname, value)
bean.save()
doc.save()
return [d.fields for d in bean.doclist]
return doc.as_dict()
@frappe.whitelist()
def insert(doclist):
@ -54,21 +54,21 @@ def insert(doclist):
if doclist[0].get("parent") and doclist[0].get("parenttype"):
# inserting a child record
d = doclist[0]
bean = frappe.bean(d["parenttype"], d["parent"])
bean.doclist.append(d)
bean.save()
doc = frappe.get_doc(d["parenttype"], d["parent"])
doc.append(d)
doc.save()
return [d]
else:
bean = frappe.bean(doclist).insert()
return [d.fields for d in bean.doclist]
doc = frappe.get_doc(doclist).insert()
return doc.as_dict()
@frappe.whitelist()
def save(doclist):
if isinstance(doclist, basestring):
doclist = json.loads(doclist)
bean = frappe.bean(doclist).save()
return [d.fields for d in bean.doclist]
doc = frappe.get_doc(doclist).save()
return doc.as_dict()
@frappe.whitelist()
def rename_doc(doctype, old_name, new_name, merge=False):
@ -80,17 +80,17 @@ def submit(doclist):
if isinstance(doclist, basestring):
doclist = json.loads(doclist)
doclistobj = frappe.bean(doclist)
doclistobj = frappe.get_doc(doclist)
doclistobj.submit()
return [d.fields for d in doclist]
return doclist.as_dict()
@frappe.whitelist()
def cancel(doctype, name):
wrapper = frappe.bean(doctype, name)
wrapper = frappe.get_doc(doctype, name)
wrapper.cancel()
return [d.fields for d in wrapper.doclist]
return wrapper.as_dict()
@frappe.whitelist()
def delete(doctype, name):
@ -104,11 +104,9 @@ def set_default(key, value, parent=None):
@frappe.whitelist()
def make_width_property_setter():
doclist = json.loads(frappe.form_dict.doclist)
if doclist[0]["doctype"]=="Property Setter" and doclist[0]["property"]=="width":
bean = frappe.bean(doclist)
bean.ignore_permissions = True
bean.insert()
doc = json.loads(frappe.form_dict)
if doc["doctype"]=="Property Setter" and doc["property"]=="width":
frappe.get_doc(doc).insert(ignore_permissions = True)
@frappe.whitelist()
def bulk_update(docs):
@ -119,9 +117,9 @@ def bulk_update(docs):
ddoc = {key: val for key, val in doc.iteritems() if key not in ['doctype', 'docname']}
doctype = doc['doctype']
docname = doc['docname']
bean = frappe.bean(doctype, docname)
bean.doc.update(ddoc)
bean.save()
doc = frappe.get_doc(doctype, docname)
doc.update(ddoc)
doc.save()
except:
failed_docs.append({
'doc': doc,

View file

@ -101,6 +101,17 @@ data = [
},
]
},
{
"label": _("Printing and Branding"),
"icon": "icon-print",
"items": [
{
"type": "doctype",
"name": "Print Format",
"description": _("Customized HTML Templates for printing transctions.")
},
]
},
{
"label": _("Customize"),
"icon": "icon-glass",

View file

@ -0,0 +1,74 @@
{
"creation": "2012-08-02 15:17:28.000000",
"description": "Bulk Email records.",
"docstatus": 0,
"doctype": "DocType",
"document_type": "System",
"fields": [
{
"fieldname": "sender",
"fieldtype": "Data",
"label": "Sender",
"permlevel": 0
},
{
"fieldname": "recipient",
"fieldtype": "Data",
"label": "Recipient",
"permlevel": 0
},
{
"fieldname": "message",
"fieldtype": "Long Text",
"label": "Message",
"permlevel": 0
},
{
"fieldname": "status",
"fieldtype": "Data",
"label": "Status",
"permlevel": 0
},
{
"fieldname": "error",
"fieldtype": "Text",
"label": "Error",
"permlevel": 0
},
{
"fieldname": "ref_doctype",
"fieldtype": "Link",
"label": "Reference DocType",
"options": "DocType",
"permlevel": 0,
"read_only": 1,
"reqd": 0
},
{
"fieldname": "ref_docname",
"fieldtype": "Data",
"label": "Reference DocName",
"permlevel": 0,
"read_only": 1,
"reqd": 0
}
],
"icon": "icon-envelope",
"idx": 1,
"in_create": 1,
"modified": "2014-02-12 21:11:05.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Bulk Email",
"owner": "Administrator",
"permissions": [
{
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"role": "System Manager"
}
],
"read_only": 1
}

View file

@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
from frappe.model.document import Document
class BulkEmail(Document):
pass

View file

@ -1,93 +0,0 @@
[
{
"creation": "2012-08-02 15:17:28",
"docstatus": 0,
"modified": "2014-02-12 21:11:05",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"description": "Bulk Email records.",
"doctype": "DocType",
"document_type": "System",
"icon": "icon-envelope",
"in_create": 1,
"module": "Core",
"name": "__common__",
"read_only": 1
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "Bulk Email",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"doctype": "DocPerm",
"email": 1,
"name": "__common__",
"parent": "Bulk Email",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"print": 1,
"read": 1,
"role": "System Manager"
},
{
"doctype": "DocType",
"name": "Bulk Email"
},
{
"doctype": "DocField",
"fieldname": "sender",
"fieldtype": "Data",
"label": "Sender"
},
{
"doctype": "DocField",
"fieldname": "recipient",
"fieldtype": "Data",
"label": "Recipient"
},
{
"doctype": "DocField",
"fieldname": "message",
"fieldtype": "Long Text",
"label": "Message"
},
{
"doctype": "DocField",
"fieldname": "status",
"fieldtype": "Data",
"label": "Status"
},
{
"doctype": "DocField",
"fieldname": "error",
"fieldtype": "Text",
"label": "Error"
},
{
"doctype": "DocField",
"fieldname": "ref_doctype",
"fieldtype": "Link",
"label": "Reference DocType",
"options": "DocType",
"read_only": 1,
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "ref_docname",
"fieldtype": "Data",
"label": "Reference DocName",
"read_only": 1,
"reqd": 1
},
{
"doctype": "DocPerm"
}
]

View file

@ -0,0 +1,118 @@
{
"autoname": "CWR/.#####",
"creation": "2012-08-08 10:40:11.000000",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "comment",
"fieldtype": "Text",
"label": "Comment",
"no_copy": 0,
"oldfieldname": "comment",
"oldfieldtype": "Text",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "comment_by",
"fieldtype": "Data",
"label": "Comment By",
"no_copy": 0,
"oldfieldname": "comment_by",
"oldfieldtype": "Data",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "comment_by_fullname",
"fieldtype": "Data",
"label": "Comment By Fullname",
"no_copy": 0,
"oldfieldname": "comment_by_fullname",
"oldfieldtype": "Data",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "comment_date",
"fieldtype": "Date",
"label": "Comment Date",
"no_copy": 0,
"oldfieldname": "comment_date",
"oldfieldtype": "Date",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "comment_time",
"fieldtype": "Data",
"label": "Comment Time",
"no_copy": 0,
"oldfieldname": "comment_time",
"oldfieldtype": "Data",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "comment_doctype",
"fieldtype": "Data",
"label": "Comment Doctype",
"no_copy": 0,
"oldfieldname": "comment_doctype",
"oldfieldtype": "Data",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "comment_docname",
"fieldtype": "Data",
"label": "Comment Docname",
"no_copy": 0,
"oldfieldname": "comment_docname",
"oldfieldtype": "Data",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "post_topic",
"fieldtype": "Data",
"label": "Post Topic",
"no_copy": 0,
"oldfieldname": "post_topic",
"oldfieldtype": "Data",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "unsubscribed",
"fieldtype": "Check",
"label": "Unsubscribed",
"permlevel": 0
}
],
"icon": "icon-comments",
"idx": 1,
"issingle": 0,
"modified": "2014-01-24 13:00:20.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Comment",
"owner": "Administrator",
"permissions": [
{
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"submit": 0,
"write": 1
}
],
"title_field": "comment"
}

View file

@ -5,39 +5,42 @@ from __future__ import unicode_literals
import frappe, json
from frappe.website.render import clear_cache
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
from frappe.model.document import Document
class Comment(Document):
def validate(self):
if frappe.db.sql("""select count(*) from tabComment where comment_doctype=%s
and comment_docname=%s""", (self.doc.doctype, self.doc.name))[0][0] >= 50:
and comment_docname=%s""", (self.doctype, self.name))[0][0] >= 50:
frappe.msgprint("Max Comments reached!", raise_exception=True)
def on_update(self):
self.update_comment_in_doc()
def update_comment_in_doc(self):
if self.doc.comment_doctype and self.doc.comment_docname and self.doc.comment:
if self.comment_doctype and self.comment_docname and self.comment:
try:
_comments = self.get_comments_from_parent()
updated = False
for c in _comments:
if c.get("name")==self.doc.name:
c["comment"] = self.doc.comment
if c.get("name")==self.name:
c["comment"] = self.comment
updated = True
if not updated:
_comments.append({
"comment": self.doc.comment,
"by": self.doc.comment_by or self.doc.owner,
"name":self.doc.name
"comment": self.comment,
"by": self.comment_by or self.owner,
"name":self.name
})
self.update_comments_in_parent(_comments)
except Exception, e:
if e.args[0]==1054:
if frappe.flags.in_test:
return
from frappe.model.db_schema import add_column
add_column(self.doc.comment_doctype, "_comments", "Text")
add_column(self.comment_doctype, "_comments", "Text")
self.update_comment_in_doc()
elif e.args[0]==1146:
# no table
@ -46,18 +49,18 @@ class DocType:
raise
def get_comments_from_parent(self):
_comments = frappe.db.get_value(self.doc.comment_doctype,
self.doc.comment_docname, "_comments") or "[]"
_comments = frappe.db.get_value(self.comment_doctype,
self.comment_docname, "_comments") or "[]"
return json.loads(_comments)
def update_comments_in_parent(self, _comments):
# use sql, so that we do not mess with the timestamp
frappe.db.sql("""update `tab%s` set `_comments`=%s where name=%s""" % (self.doc.comment_doctype,
"%s", "%s"), (json.dumps(_comments), self.doc.comment_docname))
frappe.db.sql("""update `tab%s` set `_comments`=%s where name=%s""" % (self.comment_doctype,
"%s", "%s"), (json.dumps(_comments), self.comment_docname))
# clear parent cache if route exists:
route = frappe.db.get_value("Website Route", {"ref_doctype": self.doc.comment_doctype,
"docname": self.doc.comment_docname})
route = frappe.db.get_value("Website Route", {"ref_doctype": self.comment_doctype,
"docname": self.comment_docname})
if route:
clear_cache(route)
@ -65,7 +68,7 @@ class DocType:
def on_trash(self):
_comments = self.get_comments_from_parent()
for c in _comments:
if c.get("name")==self.doc.name:
if c.get("name")==self.name:
_comments.remove(c)
self.update_comments_in_parent(_comments)

View file

@ -1,137 +0,0 @@
[
{
"creation": "2012-08-08 10:40:11",
"docstatus": 0,
"modified": "2014-01-24 13:00:20",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"autoname": "CWR/.#####",
"doctype": "DocType",
"icon": "icon-comments",
"issingle": 0,
"module": "Core",
"name": "__common__",
"title_field": "comment"
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "Comment",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"cancel": 0,
"create": 1,
"delete": 1,
"doctype": "DocPerm",
"email": 1,
"name": "__common__",
"parent": "Comment",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"submit": 0,
"write": 1
},
{
"doctype": "DocType",
"name": "Comment"
},
{
"doctype": "DocField",
"fieldname": "comment",
"fieldtype": "Text",
"label": "Comment",
"no_copy": 0,
"oldfieldname": "comment",
"oldfieldtype": "Text",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "comment_by",
"fieldtype": "Data",
"label": "Comment By",
"no_copy": 0,
"oldfieldname": "comment_by",
"oldfieldtype": "Data",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "comment_by_fullname",
"fieldtype": "Data",
"label": "Comment By Fullname",
"no_copy": 0,
"oldfieldname": "comment_by_fullname",
"oldfieldtype": "Data",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "comment_date",
"fieldtype": "Date",
"label": "Comment Date",
"no_copy": 0,
"oldfieldname": "comment_date",
"oldfieldtype": "Date",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "comment_time",
"fieldtype": "Data",
"label": "Comment Time",
"no_copy": 0,
"oldfieldname": "comment_time",
"oldfieldtype": "Data",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "comment_doctype",
"fieldtype": "Data",
"label": "Comment Doctype",
"no_copy": 0,
"oldfieldname": "comment_doctype",
"oldfieldtype": "Data",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "comment_docname",
"fieldtype": "Data",
"label": "Comment Docname",
"no_copy": 0,
"oldfieldname": "comment_docname",
"oldfieldtype": "Data",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "post_topic",
"fieldtype": "Data",
"label": "Post Topic",
"no_copy": 0,
"oldfieldname": "post_topic",
"oldfieldtype": "Data",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "unsubscribed",
"fieldtype": "Check",
"label": "Unsubscribed"
},
{
"doctype": "DocPerm"
}
]

View file

@ -9,7 +9,7 @@ import frappe, unittest, json
# class TestComment(unittest.TestCase):
# def setUp(self):
# self.cleanup()
# self.test_rec = frappe.bean({
# self.test_rec = frappe.get_doc({
# "doctype":"Event",
# "subject":"__Comment Test Event",
# "event_type": "Private",
@ -29,21 +29,21 @@ import frappe, unittest, json
# frappe.db.sql("""alter table `tabEvent` drop column `_comments`""")
#
# def test_add_comment(self):
# self.comment = frappe.bean({
# self.comment = frappe.get_doc({
# "doctype":"Comment",
# "comment_doctype": self.test_rec.doc.doctype,
# "comment_docname": self.test_rec.doc.name,
# "comment_doctype": self.test_rec.doctype,
# "comment_docname": self.test_rec.name,
# "comment": "__Test Comment"
# }).insert()
#
# test_rec = frappe.doc(self.test_rec.doc.doctype, self.test_rec.doc.name)
# test_rec = frappe.get_doc(self.test_rec.doctype, self.test_rec.name)
# _comments = json.loads(test_rec.get("_comments"))
# self.assertTrue(_comments[0].get("comment")=="__Test Comment")
#
# def test_remove_comment(self):
# self.test_add_comment()
# frappe.delete_doc("Comment", self.comment.doc.name)
# test_rec = frappe.doc(self.test_rec.doc.doctype, self.test_rec.doc.name)
# frappe.delete_doc("Comment", self.comment.name)
# test_rec = frappe.get_doc(self.test_rec.doctype, self.test_rec.name)
# _comments = json.loads(test_rec.get("_comments"))
# self.assertEqual(len(_comments), 0)
#

View file

@ -0,0 +1,233 @@
{
"allow_attach": 1,
"allow_import": 1,
"autoname": "naming_series:",
"creation": "2013-01-29 10:47:14.000000",
"description": "Keep a track of all communications",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Master",
"fields": [
{
"default": "COMM-",
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 1,
"label": "Series",
"options": "COMM-",
"permlevel": 0
},
{
"fieldname": "sent_or_received",
"fieldtype": "Select",
"label": "Sent or Received",
"options": "Sent\nReceived",
"permlevel": 0,
"reqd": 1
},
{
"fieldname": "subject",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Subject",
"permlevel": 0,
"reqd": 1
},
{
"fieldname": "content",
"fieldtype": "Text Editor",
"label": "Content",
"permlevel": 0,
"reqd": 0,
"width": "400"
},
{
"fieldname": "section_break1",
"fieldtype": "Section Break",
"options": "simple",
"permlevel": 0
},
{
"fieldname": "category",
"fieldtype": "Select",
"label": "Category",
"options": "\nSales\nComplaint\nHelp\nSuggestion\nMiscellaneous\nSent Mail",
"permlevel": 0,
"reqd": 0
},
{
"fieldname": "column_break2",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"fieldname": "next_communication_date",
"fieldtype": "Date",
"label": "Next Communcation On",
"permlevel": 0
},
{
"fieldname": "action",
"fieldtype": "Select",
"label": "Action",
"options": "\nCreated Opportunity\nSent Quotation\nCreated Support Ticket\nCreated Customer Issue\nNo Action\nSent Mail",
"permlevel": 0,
"reqd": 0
},
{
"fieldname": "additional_info",
"fieldtype": "Section Break",
"label": "Additional Info",
"permlevel": 0
},
{
"fieldname": "recipients",
"fieldtype": "Data",
"label": "Recipients",
"permlevel": 0
},
{
"fieldname": "sender",
"fieldtype": "Data",
"label": "Sender",
"permlevel": 0
},
{
"fieldname": "communication_medium",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Communication Medium",
"options": "\nChat\nPhone\nEmail\nSMS\nVisit\nOther",
"permlevel": 0
},
{
"fieldname": "phone_no",
"fieldtype": "Data",
"label": "Phone No.",
"permlevel": 0
},
{
"fieldname": "section_break2",
"fieldtype": "Section Break",
"options": "simple",
"permlevel": 0
},
{
"fieldname": "column_break4",
"fieldtype": "Column Break",
"label": "By",
"permlevel": 0
},
{
"default": "__user",
"fieldname": "user",
"fieldtype": "Link",
"label": "User",
"options": "User",
"permlevel": 0,
"read_only": 1
},
{
"fieldname": "column_break5",
"fieldtype": "Column Break",
"label": "On",
"permlevel": 0
},
{
"default": "Today",
"fieldname": "communication_date",
"fieldtype": "Datetime",
"label": "Date",
"permlevel": 0
},
{
"fieldname": "_user_tags",
"fieldtype": "Data",
"hidden": 1,
"label": "User Tags",
"no_copy": 1,
"permlevel": 0,
"print_hide": 1
}
],
"icon": "icon-comment",
"idx": 1,
"in_dialog": 0,
"issingle": 0,
"modified": "2014-01-24 13:01:25.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Communication",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Support Team",
"submit": 0,
"write": 1
},
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Sales Manager",
"submit": 0,
"write": 1
},
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Sales User",
"submit": 0,
"write": 1
},
{
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Support Manager",
"submit": 0,
"write": 1
},
{
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"submit": 0,
"write": 1
}
],
"title_field": "subject"
}

View file

@ -12,17 +12,15 @@ from frappe.utils.email_lib.email_body import get_email
from frappe.utils.email_lib.smtp import send
from frappe.utils import scrub_urls
class DocType():
def __init__(self, doc, doclist=None):
self.doc = doc
self.doclist = doclist
def get_parent_bean(self):
return frappe.bean(self.doc.parenttype, self.doc.parent)
from frappe.model.document import Document
class Communication(Document):
def get_parent_doc(self):
return frappe.get_doc(self.parenttype, self.parent)
def update_parent(self):
"""update status of parent Lead or Contact based on who is replying"""
observer = self.get_parent_bean().get_attr("on_communication")
observer = self.get_parent_doc().get_attr("on_communication")
if observer:
observer()
@ -60,8 +58,8 @@ def _make(doctype=None, name=None, content=None, subject=None, sent_or_received
if isinstance(sender, (tuple, list)) and len(sender)==2:
sender = formataddr(sender)
comm = frappe.new_bean('Communication')
d = comm.doc
comm = frappe.new_doc('Communication')
d = comm
d.subject = subject
d.content = content
d.sent_or_received = sent_or_received
@ -69,7 +67,7 @@ def _make(doctype=None, name=None, content=None, subject=None, sent_or_received
d.recipients = recipients
# add as child
sent_via = frappe.get_obj(doctype, name)
sent_via = frappe.get_doc(doctype, name)
d.parent = name
d.parenttype = doctype
d.parentfield = "communications"
@ -83,7 +81,7 @@ def _make(doctype=None, name=None, content=None, subject=None, sent_or_received
comm.insert()
if send_email:
d = comm.doc
d = comm
send_comm_email(d, name, sent_via, print_html, attachments, send_me_a_copy)
@frappe.whitelist()
@ -149,10 +147,10 @@ def set_portal_link(sent_via, comm):
if is_signup_enabled() and hasattr(sent_via, "get_portal_page"):
portal_page = sent_via.get_portal_page()
if portal_page:
is_valid_recipient = cstr(sent_via.doc.email or sent_via.doc.email_id or
sent_via.doc.contact_email) in comm.recipients
is_valid_recipient = cstr(sent_via.email or sent_via.email_id or
sent_via.contact_email) in comm.recipients
if is_valid_recipient:
url = "%s/%s?name=%s" % (get_url(), portal_page, urllib.quote(sent_via.doc.name))
url = "%s/%s?name=%s" % (get_url(), portal_page, urllib.quote(sent_via.name))
footer = """<!-- Portal Link --><hr>
<a href="%s" target="_blank">View this on our website</a>""" % url

View file

@ -1,216 +0,0 @@
[
{
"creation": "2013-01-29 10:47:14",
"docstatus": 0,
"modified": "2014-01-24 13:01:25",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_attach": 1,
"allow_import": 1,
"autoname": "naming_series:",
"description": "Keep a track of all communications",
"doctype": "DocType",
"document_type": "Master",
"icon": "icon-comment",
"in_dialog": 0,
"issingle": 0,
"module": "Core",
"name": "__common__",
"title_field": "subject"
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "Communication",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"cancel": 0,
"create": 1,
"delete": 1,
"doctype": "DocPerm",
"email": 1,
"name": "__common__",
"parent": "Communication",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"submit": 0,
"write": 1
},
{
"doctype": "DocType",
"name": "Communication"
},
{
"default": "COMM-",
"doctype": "DocField",
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 1,
"label": "Series",
"options": "COMM-"
},
{
"doctype": "DocField",
"fieldname": "sent_or_received",
"fieldtype": "Select",
"label": "Sent or Received",
"options": "Sent\nReceived",
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "subject",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Subject",
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "content",
"fieldtype": "Text Editor",
"label": "Content",
"reqd": 0,
"width": "400"
},
{
"doctype": "DocField",
"fieldname": "section_break1",
"fieldtype": "Section Break",
"options": "simple"
},
{
"doctype": "DocField",
"fieldname": "category",
"fieldtype": "Select",
"label": "Category",
"options": "\nSales\nComplaint\nHelp\nSuggestion\nMiscellaneous\nSent Mail",
"reqd": 0
},
{
"doctype": "DocField",
"fieldname": "column_break2",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"fieldname": "next_communication_date",
"fieldtype": "Date",
"label": "Next Communcation On"
},
{
"doctype": "DocField",
"fieldname": "action",
"fieldtype": "Select",
"label": "Action",
"options": "\nCreated Opportunity\nSent Quotation\nCreated Support Ticket\nCreated Customer Issue\nNo Action\nSent Mail",
"reqd": 0
},
{
"doctype": "DocField",
"fieldname": "additional_info",
"fieldtype": "Section Break",
"label": "Additional Info"
},
{
"doctype": "DocField",
"fieldname": "recipients",
"fieldtype": "Data",
"label": "Recipients"
},
{
"doctype": "DocField",
"fieldname": "sender",
"fieldtype": "Data",
"label": "Sender"
},
{
"doctype": "DocField",
"fieldname": "communication_medium",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Communication Medium",
"options": "\nChat\nPhone\nEmail\nSMS\nVisit\nOther"
},
{
"doctype": "DocField",
"fieldname": "phone_no",
"fieldtype": "Data",
"label": "Phone No."
},
{
"doctype": "DocField",
"fieldname": "section_break2",
"fieldtype": "Section Break",
"options": "simple"
},
{
"doctype": "DocField",
"fieldname": "column_break4",
"fieldtype": "Column Break",
"label": "By"
},
{
"default": "__user",
"doctype": "DocField",
"fieldname": "user",
"fieldtype": "Link",
"label": "User",
"options": "User",
"read_only": 1
},
{
"doctype": "DocField",
"fieldname": "column_break5",
"fieldtype": "Column Break",
"label": "On"
},
{
"default": "Today",
"doctype": "DocField",
"fieldname": "communication_date",
"fieldtype": "Datetime",
"label": "Date"
},
{
"doctype": "DocField",
"fieldname": "_user_tags",
"fieldtype": "Data",
"hidden": 1,
"label": "User Tags",
"no_copy": 1,
"print_hide": 1
},
{
"amend": 0,
"doctype": "DocPerm",
"role": "Support Team"
},
{
"amend": 0,
"doctype": "DocPerm",
"role": "Sales Manager"
},
{
"amend": 0,
"doctype": "DocPerm",
"role": "Sales User"
},
{
"doctype": "DocPerm",
"role": "Support Manager"
},
{
"doctype": "DocPerm",
"role": "System Manager"
}
]

View file

@ -1 +0,0 @@
(deprecated) Single DocType where global variables used to be stored.

View file

@ -1,4 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
from __future__ import unicode_literals

View file

@ -1,18 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
from __future__ import unicode_literals
import frappe
from frappe import form, msgprint
import frappe.defaults
class DocType:
def __init__(self, doc, doclist):
self.doc = doc
self.doclist = doclist
def on_update(self):
# clear cache on save
frappe.cache().delete_value('time_zone')
frappe.clear_cache()

View file

@ -1,226 +0,0 @@
[
{
"creation": "2013-01-10 16:34:01",
"docstatus": 0,
"modified": "2013-12-20 19:23:02",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_copy": 0,
"doctype": "DocType",
"hide_heading": 0,
"hide_toolbar": 0,
"in_create": 1,
"issingle": 1,
"istable": 0,
"module": "Core",
"name": "__common__",
"read_only": 0
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "Control Panel",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"cancel": 0,
"create": 1,
"doctype": "DocPerm",
"email": 1,
"export": 0,
"import": 0,
"name": "__common__",
"parent": "Control Panel",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"print": 1,
"read": 1,
"report": 0,
"role": "Administrator",
"submit": 0,
"write": 1
},
{
"doctype": "DocType",
"name": "Control Panel"
},
{
"doctype": "DocField",
"fieldname": "general",
"fieldtype": "Section Break",
"label": "General"
},
{
"doctype": "DocField",
"fieldname": "date_format",
"fieldtype": "Select",
"label": "Date Format",
"options": "yyyy-mm-dd\ndd-mm-yyyy\ndd/mm/yyyy\nmm/dd/yyyy\nmm-dd-yyyy"
},
{
"doctype": "DocField",
"fieldname": "currency_format",
"fieldtype": "Select",
"label": "Currency Format",
"options": "Millions\nLacs"
},
{
"doctype": "DocField",
"fieldname": "password_expiry_days",
"fieldtype": "Int",
"label": "Password Expires in (days)"
},
{
"description": "Format: hh:mm example for one hour expiry set as 01:00. \nMax expiry will be 72 hours. Default is 24 hours",
"doctype": "DocField",
"fieldname": "session_expiry",
"fieldtype": "Data",
"label": "Session Expires in (time)"
},
{
"doctype": "DocField",
"fieldname": "column_break0",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"fieldname": "title",
"fieldtype": "Data",
"label": "Title"
},
{
"doctype": "DocField",
"fieldname": "account_id",
"fieldtype": "Data",
"label": "Account Id"
},
{
"doctype": "DocField",
"fieldname": "company_name",
"fieldtype": "Data",
"label": "Company Name"
},
{
"doctype": "DocField",
"fieldname": "industry",
"fieldtype": "Data",
"label": "Industry"
},
{
"doctype": "DocField",
"fieldname": "time_zone",
"fieldtype": "Data",
"label": "Time Zone"
},
{
"doctype": "DocField",
"fieldname": "country",
"fieldtype": "Data",
"label": "Country"
},
{
"doctype": "DocField",
"fieldname": "total_sms_sent",
"fieldtype": "Int",
"label": "Total SMS Sent",
"read_only": 1
},
{
"doctype": "DocField",
"fieldname": "mail_server",
"fieldtype": "Section Break",
"label": "Mail Server"
},
{
"description": "Email Id where users will send support request e.g. support@example.com",
"doctype": "DocField",
"fieldname": "support_email_id",
"fieldtype": "Data",
"label": "Support Email Id"
},
{
"doctype": "DocField",
"fieldname": "letter_head_image",
"fieldtype": "Data",
"label": "Letter Head Image"
},
{
"doctype": "DocField",
"fieldname": "column_break1",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"fieldname": "mail_footer",
"fieldtype": "Text",
"label": "Mail Footer"
},
{
"doctype": "DocField",
"fieldname": "defaults",
"fieldtype": "Section Break",
"label": "Defaults"
},
{
"doctype": "DocField",
"fieldname": "system_defaults",
"fieldtype": "Table",
"hidden": 0,
"label": "System Defaults",
"options": "DefaultValue",
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "banner",
"fieldtype": "Section Break",
"label": "Banner"
},
{
"doctype": "DocField",
"fieldname": "client_name",
"fieldtype": "Text",
"label": "Banner HTML"
},
{
"doctype": "DocField",
"fieldname": "startup",
"fieldtype": "Section Break",
"label": "Startup"
},
{
"doctype": "DocField",
"fieldname": "custom_startup_code",
"fieldtype": "Code",
"label": "Custom Startup Code"
},
{
"doctype": "DocField",
"fieldname": "home_pages",
"fieldtype": "Section Break",
"label": "Home Pages"
},
{
"doctype": "DocField",
"fieldname": "home_page",
"fieldtype": "Link",
"label": "Home Page",
"options": "Page"
},
{
"doctype": "DocField",
"fieldname": "default_home_pages",
"fieldtype": "Table",
"label": "Default Home Pages",
"options": "Default Home Page"
},
{
"doctype": "DocPerm"
}
]

View file

@ -0,0 +1,294 @@
{
"creation": "2013-01-10 16:34:01.000000",
"description": "Adds a custom field to a DocType",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "dt",
"fieldtype": "Link",
"in_filter": 1,
"in_list_view": 1,
"label": "Document",
"no_copy": 0,
"oldfieldname": "dt",
"oldfieldtype": "Link",
"options": "DocType",
"permlevel": 0,
"reqd": 1,
"search_index": 1
},
{
"fieldname": "label",
"fieldtype": "Data",
"in_filter": 1,
"label": "Label",
"no_copy": 1,
"oldfieldname": "label",
"oldfieldtype": "Data",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "label_help",
"fieldtype": "HTML",
"label": "Label Help",
"oldfieldtype": "HTML",
"permlevel": 0
},
{
"description": "Select the label after which you want to insert new field.",
"fieldname": "insert_after",
"fieldtype": "Select",
"label": "Insert After",
"no_copy": 1,
"oldfieldname": "insert_after",
"oldfieldtype": "Select",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "fieldtype",
"fieldtype": "Select",
"in_filter": 1,
"in_list_view": 1,
"label": "Field Type",
"no_copy": 0,
"oldfieldname": "fieldtype",
"oldfieldtype": "Select",
"options": "Button\nCheck\nCode\nColumn Break\nCurrency\nData\nDate\nDatetime\nFloat\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime",
"permlevel": 0,
"reqd": 1,
"search_index": 0
},
{
"fieldname": "options_help",
"fieldtype": "HTML",
"label": "Options Help",
"oldfieldtype": "HTML",
"permlevel": 0
},
{
"fieldname": "options",
"fieldtype": "Text",
"in_list_view": 1,
"label": "Options",
"no_copy": 0,
"oldfieldname": "options",
"oldfieldtype": "Text",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "description",
"fieldtype": "Text",
"label": "Field Description",
"no_copy": 0,
"oldfieldname": "description",
"oldfieldtype": "Text",
"permlevel": 0,
"print_width": "300px",
"search_index": 0,
"width": "300px"
},
{
"fieldname": "fieldname",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Fieldname",
"no_copy": 1,
"oldfieldname": "fieldname",
"oldfieldtype": "Data",
"permlevel": 0,
"read_only": 1,
"search_index": 0
},
{
"fieldname": "properties",
"fieldtype": "Column Break",
"label": "Properties",
"oldfieldtype": "Column Break",
"permlevel": 0,
"print_width": "50%",
"width": "50%"
},
{
"default": "0",
"fieldname": "permlevel",
"fieldtype": "Int",
"label": "Permission Level",
"no_copy": 0,
"oldfieldname": "permlevel",
"oldfieldtype": "Int",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "reqd",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Is Mandatory Field",
"no_copy": 0,
"oldfieldname": "reqd",
"oldfieldtype": "Check",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "read_only",
"fieldtype": "Check",
"label": "Read Only",
"permlevel": 0
},
{
"depends_on": "eval:doc.fieldtype===\"Link\"",
"fieldname": "ignore_restrictions",
"fieldtype": "Check",
"label": "Ignore Restrictions",
"permlevel": 0
},
{
"fieldname": "width",
"fieldtype": "Data",
"label": "Width",
"no_copy": 0,
"oldfieldname": "width",
"oldfieldtype": "Data",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "default",
"fieldtype": "Text",
"label": "Default Value",
"no_copy": 0,
"oldfieldname": "default",
"oldfieldtype": "Text",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "hidden",
"fieldtype": "Check",
"label": "Hidden",
"permlevel": 0
},
{
"fieldname": "depends_on",
"fieldtype": "Data",
"label": "Depends On",
"permlevel": 0
},
{
"fieldname": "print_hide",
"fieldtype": "Check",
"label": "Print Hide",
"no_copy": 0,
"oldfieldname": "print_hide",
"oldfieldtype": "Check",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "print_width",
"fieldtype": "Data",
"hidden": 1,
"label": "Print Width",
"no_copy": 1,
"permlevel": 0,
"print_hide": 1
},
{
"fieldname": "no_copy",
"fieldtype": "Check",
"label": "No Copy",
"no_copy": 0,
"oldfieldname": "no_copy",
"oldfieldtype": "Check",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "allow_on_submit",
"fieldtype": "Check",
"label": "Allow on Submit",
"no_copy": 0,
"oldfieldname": "allow_on_submit",
"oldfieldtype": "Check",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "in_filter",
"fieldtype": "Check",
"label": "In Report Filter",
"no_copy": 0,
"oldfieldname": "in_filter",
"oldfieldtype": "Check",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "in_list_view",
"fieldtype": "Check",
"label": "In List View",
"permlevel": 0
},
{
"fieldname": "report_hide",
"fieldtype": "Check",
"label": "Report Hide",
"no_copy": 0,
"oldfieldname": "report_hide",
"oldfieldtype": "Check",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "search_index",
"fieldtype": "Check",
"hidden": 1,
"label": "Index",
"no_copy": 1,
"permlevel": 0,
"print_hide": 1
}
],
"icon": "icon-glass",
"idx": 1,
"modified": "2014-01-20 17:48:31.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Custom Field",
"owner": "Administrator",
"permissions": [
{
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Administrator",
"submit": 0,
"write": 1
},
{
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"submit": 0,
"write": 1
}
],
"search_fields": "dt,label,fieldtype,options"
}

View file

@ -6,60 +6,59 @@ import frappe
from frappe.utils import cint, cstr
from frappe import _
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
from frappe.model.document import Document
class CustomField(Document):
def autoname(self):
self.set_fieldname()
self.doc.name = self.doc.dt + "-" + self.doc.fieldname
self.name = self.dt + "-" + self.fieldname
def set_fieldname(self):
if not self.doc.fieldname:
if not self.doc.label:
if not self.fieldname:
if not self.label:
frappe.throw(_("Label is mandatory"))
# remove special characters from fieldname
self.doc.fieldname = filter(lambda x: x.isdigit() or x.isalpha() or '_',
cstr(self.doc.label).lower().replace(' ','_'))
self.fieldname = filter(lambda x: x.isdigit() or x.isalpha() or '_',
cstr(self.label).lower().replace(' ','_'))
def validate(self):
from frappe.model.doctype import get
temp_doclist = get(self.doc.dt).get_parent_doclist()
# set idx
if not self.doc.idx:
max_idx = max(d.idx for d in temp_doclist if d.doctype=='DocField')
self.doc.idx = cint(max_idx) + 1
if not self.idx:
self.idx = len(frappe.get_meta(self.dt).get("fields")) + 1
if not self.fieldname:
frappe.throw(_("Fieldname not set for Custom Field"))
def on_update(self):
# validate field
from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype
validate_fields_for_doctype(self.doc.dt)
validate_fields_for_doctype(self.dt)
frappe.clear_cache(doctype=self.doc.dt)
frappe.clear_cache(doctype=self.dt)
# create property setter to emulate insert after
self.create_property_setter()
# update the schema
from frappe.model.db_schema import updatedb
updatedb(self.doc.dt)
if not frappe.flags.in_test:
from frappe.model.db_schema import updatedb
updatedb(self.dt)
def on_trash(self):
# delete property setter entries
frappe.db.sql("""\
DELETE FROM `tabProperty Setter`
WHERE doc_type = %s
AND field_name = %s""",
(self.doc.dt, self.doc.fieldname))
(self.dt, self.fieldname))
frappe.clear_cache(doctype=self.doc.dt)
frappe.clear_cache(doctype=self.dt)
def create_property_setter(self):
if not self.doc.insert_after: return
idx_label_list, field_list = get_fields_label(self.doc.dt, 0)
label_index = idx_label_list.index(self.doc.insert_after)
if not self.insert_after: return
idx_label_list, field_list = get_fields_label(self.dt, 0)
label_index = idx_label_list.index(self.insert_after)
if label_index==-1: return
prev_field = field_list[label_index]
@ -67,11 +66,11 @@ class DocType:
DELETE FROM `tabProperty Setter`
WHERE doc_type = %s
AND field_name = %s
AND property = 'previous_field'""", (self.doc.dt, self.doc.fieldname))
AND property = 'previous_field'""", (self.dt, self.fieldname))
frappe.make_property_setter({
"doctype":self.doc.dt,
"fieldname": self.doc.fieldname,
"doctype":self.dt,
"fieldname": self.fieldname,
"property": "previous_field",
"value": prev_field
})
@ -84,16 +83,13 @@ def get_fields_label(dt=None, form=1):
"""
import frappe
from frappe.utils import cstr
import frappe.model.doctype
fieldname = None
if not dt:
dt = frappe.form_dict.get('doctype')
fieldname = frappe.form_dict.get('fieldname')
if not dt: return ""
doclist = frappe.model.doctype.get(dt)
docfields = sorted(doclist.get({"parent": dt, "doctype": "DocField"}),
key=lambda d: d.idx)
docfields = frappe.get_meta(dt).get("fields")
if fieldname:
idx_label_list = [cstr(d.label) or cstr(d.fieldname) or cstr(d.fieldtype)
@ -114,7 +110,7 @@ def create_custom_field_if_values_exist(doctype, df):
frappe.db.sql("""select count(*) from `tab{doctype}`
where ifnull({fieldname},'')!=''""".format(doctype=doctype, fieldname=df.fieldname))[0][0] and \
not frappe.db.get_value("Custom Field", {"dt": doctype, "fieldname": df.fieldname}):
frappe.bean({
frappe.get_doc({
"doctype":"Custom Field",
"dt": doctype,
"permlevel": df.permlevel or 0,

View file

@ -1,304 +0,0 @@
[
{
"creation": "2013-01-10 16:34:01",
"docstatus": 0,
"modified": "2014-01-20 17:48:31",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"description": "Adds a custom field to a DocType",
"doctype": "DocType",
"icon": "icon-glass",
"module": "Core",
"name": "__common__",
"search_fields": "dt,label,fieldtype,options"
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "Custom Field",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"cancel": 0,
"create": 1,
"delete": 1,
"doctype": "DocPerm",
"email": 1,
"name": "__common__",
"parent": "Custom Field",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"submit": 0,
"write": 1
},
{
"doctype": "DocType",
"name": "Custom Field"
},
{
"doctype": "DocField",
"fieldname": "dt",
"fieldtype": "Link",
"in_filter": 1,
"in_list_view": 1,
"label": "Document",
"no_copy": 0,
"oldfieldname": "dt",
"oldfieldtype": "Link",
"options": "DocType",
"reqd": 1,
"search_index": 1
},
{
"doctype": "DocField",
"fieldname": "label",
"fieldtype": "Data",
"in_filter": 1,
"label": "Label",
"no_copy": 1,
"oldfieldname": "label",
"oldfieldtype": "Data",
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "label_help",
"fieldtype": "HTML",
"label": "Label Help",
"oldfieldtype": "HTML"
},
{
"description": "Select the label after which you want to insert new field.",
"doctype": "DocField",
"fieldname": "insert_after",
"fieldtype": "Select",
"label": "Insert After",
"no_copy": 1,
"oldfieldname": "insert_after",
"oldfieldtype": "Select",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "fieldtype",
"fieldtype": "Select",
"in_filter": 1,
"in_list_view": 1,
"label": "Field Type",
"no_copy": 0,
"oldfieldname": "fieldtype",
"oldfieldtype": "Select",
"options": "Button\nCheck\nCode\nColumn Break\nCurrency\nData\nDate\nDatetime\nFloat\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime",
"reqd": 1,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "options_help",
"fieldtype": "HTML",
"label": "Options Help",
"oldfieldtype": "HTML"
},
{
"doctype": "DocField",
"fieldname": "options",
"fieldtype": "Text",
"in_list_view": 1,
"label": "Options",
"no_copy": 0,
"oldfieldname": "options",
"oldfieldtype": "Text",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "description",
"fieldtype": "Text",
"label": "Field Description",
"no_copy": 0,
"oldfieldname": "description",
"oldfieldtype": "Text",
"print_width": "300px",
"search_index": 0,
"width": "300px"
},
{
"doctype": "DocField",
"fieldname": "fieldname",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Fieldname",
"no_copy": 1,
"oldfieldname": "fieldname",
"oldfieldtype": "Data",
"read_only": 1,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "properties",
"fieldtype": "Column Break",
"label": "Properties",
"oldfieldtype": "Column Break",
"print_width": "50%",
"width": "50%"
},
{
"default": "0",
"doctype": "DocField",
"fieldname": "permlevel",
"fieldtype": "Int",
"label": "Permission Level",
"no_copy": 0,
"oldfieldname": "permlevel",
"oldfieldtype": "Int",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "reqd",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Is Mandatory Field",
"no_copy": 0,
"oldfieldname": "reqd",
"oldfieldtype": "Check",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "read_only",
"fieldtype": "Check",
"label": "Read Only"
},
{
"depends_on": "eval:doc.fieldtype===\"Link\"",
"doctype": "DocField",
"fieldname": "ignore_restrictions",
"fieldtype": "Check",
"label": "Ignore Restrictions"
},
{
"doctype": "DocField",
"fieldname": "width",
"fieldtype": "Data",
"label": "Width",
"no_copy": 0,
"oldfieldname": "width",
"oldfieldtype": "Data",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "default",
"fieldtype": "Text",
"label": "Default Value",
"no_copy": 0,
"oldfieldname": "default",
"oldfieldtype": "Text",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "hidden",
"fieldtype": "Check",
"label": "Hidden"
},
{
"doctype": "DocField",
"fieldname": "depends_on",
"fieldtype": "Data",
"label": "Depends On"
},
{
"doctype": "DocField",
"fieldname": "print_hide",
"fieldtype": "Check",
"label": "Print Hide",
"no_copy": 0,
"oldfieldname": "print_hide",
"oldfieldtype": "Check",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "print_width",
"fieldtype": "Data",
"hidden": 1,
"label": "Print Width",
"no_copy": 1,
"print_hide": 1
},
{
"doctype": "DocField",
"fieldname": "no_copy",
"fieldtype": "Check",
"label": "No Copy",
"no_copy": 0,
"oldfieldname": "no_copy",
"oldfieldtype": "Check",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "allow_on_submit",
"fieldtype": "Check",
"label": "Allow on Submit",
"no_copy": 0,
"oldfieldname": "allow_on_submit",
"oldfieldtype": "Check",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "in_filter",
"fieldtype": "Check",
"label": "In Report Filter",
"no_copy": 0,
"oldfieldname": "in_filter",
"oldfieldtype": "Check",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "in_list_view",
"fieldtype": "Check",
"label": "In List View"
},
{
"doctype": "DocField",
"fieldname": "report_hide",
"fieldtype": "Check",
"label": "Report Hide",
"no_copy": 0,
"oldfieldname": "report_hide",
"oldfieldtype": "Check",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "search_index",
"fieldtype": "Check",
"hidden": 1,
"label": "Index",
"no_copy": 1,
"print_hide": 1
},
{
"doctype": "DocPerm",
"role": "Administrator"
},
{
"doctype": "DocPerm",
"role": "System Manager"
}
]

View file

@ -0,0 +1,74 @@
{
"autoname": "CustomScript.####",
"creation": "2013-01-10 16:34:01.000000",
"description": "Adds a custom script (client or server) to a DocType",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "dt",
"fieldtype": "Link",
"label": "DocType",
"oldfieldname": "dt",
"oldfieldtype": "Link",
"options": "DocType",
"permlevel": 0
},
{
"default": "Client",
"fieldname": "script_type",
"fieldtype": "Select",
"hidden": 1,
"label": "Script Type",
"oldfieldname": "script_type",
"oldfieldtype": "Select",
"options": "Client",
"permlevel": 0,
"read_only": 1
},
{
"fieldname": "script",
"fieldtype": "Code",
"label": "Script",
"oldfieldname": "script",
"oldfieldtype": "Code",
"options": "Script",
"permlevel": 0
}
],
"icon": "icon-glass",
"idx": 1,
"modified": "2014-01-20 17:48:31.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Custom Script",
"owner": "Administrator",
"permissions": [
{
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"submit": 0,
"write": 1
},
{
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Administrator",
"submit": 0,
"write": 1
}
]
}

View file

@ -4,16 +4,16 @@ from __future__ import unicode_literals
import frappe
from frappe.utils import cstr
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
from frappe.model.document import Document
class CustomScript(Document):
def autoname(self):
self.doc.name = self.doc.dt + "-" + self.doc.script_type
self.name = self.dt + "-" + self.script_type
def on_update(self):
frappe.clear_cache(doctype=self.doc.dt)
frappe.clear_cache(doctype=self.dt)
def on_trash(self):
frappe.clear_cache(doctype=self.doc.dt)
frappe.clear_cache(doctype=self.dt)

View file

@ -1,84 +0,0 @@
[
{
"creation": "2013-01-10 16:34:01",
"docstatus": 0,
"modified": "2014-01-20 17:48:31",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"autoname": "CustomScript.####",
"description": "Adds a custom script (client or server) to a DocType",
"doctype": "DocType",
"icon": "icon-glass",
"module": "Core",
"name": "__common__"
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "Custom Script",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"cancel": 0,
"create": 1,
"delete": 1,
"doctype": "DocPerm",
"email": 1,
"name": "__common__",
"parent": "Custom Script",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"submit": 0,
"write": 1
},
{
"doctype": "DocType",
"name": "Custom Script"
},
{
"doctype": "DocField",
"fieldname": "dt",
"fieldtype": "Link",
"label": "DocType",
"oldfieldname": "dt",
"oldfieldtype": "Link",
"options": "DocType"
},
{
"default": "Client",
"doctype": "DocField",
"fieldname": "script_type",
"fieldtype": "Select",
"hidden": 1,
"label": "Script Type",
"oldfieldname": "script_type",
"oldfieldtype": "Select",
"options": "Client",
"read_only": 1
},
{
"doctype": "DocField",
"fieldname": "script",
"fieldtype": "Code",
"label": "Script",
"oldfieldname": "script",
"oldfieldtype": "Code",
"options": "Script"
},
{
"doctype": "DocPerm",
"role": "System Manager"
},
{
"doctype": "DocPerm",
"role": "Administrator"
}
]

View file

@ -1,102 +1,87 @@
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
$(cur_frm.wrapper).on("grid-row-render", function(e, grid_row) {
if(grid_row.doc && grid_row.doc.fieldtype=="Section Break") {
$(grid_row.row).css({"font-weight": "bold"});
}
})
frappe.provide("frappe.customize_form");
cur_frm.cscript.doc_type = function() {
return cur_frm.call({
method: "get",
doc: cur_frm.doc,
callback: function(r) {
cur_frm.refresh();
frappe.ui.form.on("Customize Form", "onload", function(frm) {
frappe.customize_form.add_fields_help(frm);
frm.set_query("doc_type", function() {
return {
filters: [
['DocType', 'issingle', '=', 0],
['DocType', 'in_create', '=', 0],
['DocType', 'name', 'not in', 'DocType, DocField, DocPerm, User, Role, UserRole, \
Page, Page Role, Module Def, Print Format, Report, Customize Form, \
Customize Form Field']
]
};
});
$(frm.wrapper).on("grid-row-render", function(e, grid_row) {
if(grid_row.doc && grid_row.doc.fieldtype=="Section Break") {
$(grid_row.row).css({"font-weight": "bold"});
}
});
}
});
cur_frm.cscript.onload = function(doc, dt, dn) {
cur_frm.fields_dict.fields.grid.cannot_add_rows = true;
cur_frm.add_fields_help();
}
cur_frm.fields_dict.doc_type.get_query = function(doc, dt, dn) {
return{
filters:[
['DocType', 'issingle', '=', 0],
['DocType', 'in_create', '=', 0],
['DocType', 'name', 'not in', 'DocType, DocField, DocPerm, User, Role, UserRole,\
Page, Page Role, Module Def, Print Format, Report, Customize Form, Customize Form Field']
]
frappe.ui.form.on("Customize Form", "doc_type", function(frm) {
if(frm.doc.doc_type) {
return frm.call({
method: "fetch_to_customize",
doc: frm.doc,
callback: function(r) {
frm.refresh();
}
});
}
}
});
cur_frm.cscript.refresh = function() {
cur_frm.disable_save();
cur_frm.frm_head.appframe.iconbar.clear("1");
cur_frm.appframe.set_title_right("Update", function() {
if(cur_frm.doc.doc_type) {
return cur_frm.call({
doc: cur_frm.doc,
method: "post",
callback: function(r) {
if(!r.exc && r.server_messages) {
cur_frm.script_manager.trigger("doc_type");
cur_frm.frm_head.set_label(['Updated', 'label-success']);
frappe.ui.form.on("Customize Form", "refresh", function(frm) {
frm.disable_save();
frm.frm_head.appframe.iconbar.clear("1");
if(frm.doc.doc_type) {
frm.appframe.set_title_right("Update", function() {
if(frm.doc.doc_type) {
return frm.call({
doc: frm.doc,
method: "save_customization",
callback: function(r) {
if(!r.exc) {
frappe.customize_form.clear_locals_and_refresh(frm);
}
}
}
});
}
});
});
}
});
cur_frm.add_custom_button('Refresh Form', function() {
cur_frm.script_manager.trigger("doc_type");
}, "icon-refresh");
frm.add_custom_button('Refresh Form', function() {
frm.script_manager.trigger("doc_type");
}, "icon-refresh");
cur_frm.add_custom_button('Reset to defaults', function() {
cur_frm.confirm('This will <b>remove the customizations</b> defined for this form.<br /><br />'
+ 'Are you sure you want to <i>reset to defaults</i>?', cur_frm.doc, cur_frm.doctype, cur_frm.docname);
}, "icon-eraser");
if(!cur_frm.doc.doc_type) {
var frm_head = cur_frm.frm_head.appframe;
$(frm_head.buttons['Update']).prop('disabled', true);
$(frm_head.buttons['Refresh Form']).prop('disabled', true);
$(frm_head.buttons['Reset to defaults']).prop('disabled', true);
frm.add_custom_button('Reset to defaults', function() {
frappe.customize_form.confirm('This will <b>remove the customizations</b> defined for this form.<br /><br />'
+ 'Are you sure you want to <i>reset to defaults</i>?', frm);
}, "icon-eraser");
}
cur_frm.cscript.hide_allow_attach(cur_frm.doc);
// if(!frm.doc.doc_type) {
// var frm_head = frm.frm_head.appframe;
// $(frm_head.buttons['Update']).prop('disabled', true);
// $(frm_head.buttons['Refresh Form']).prop('disabled', true);
// $(frm_head.buttons['Reset to defaults']).prop('disabled', true);
// }
if(frappe.route_options) {
frappe.model.set_value("Customize Form", null, "doc_type", frappe.route_options.doctype)
frappe.route_options = null;
}
}
});
cur_frm.cscript.hide_allow_attach = function(doc) {
var allow_attach_list = ['Website Settings', 'Web Page', 'Timesheet', 'Ticket',
'Support Ticket', 'Supplier', 'Style Settings', 'Stock Reconciliation',
'Stock Entry', 'Serial No', 'Sales Order', 'Sales Invoice',
'Quotation', 'Question', 'Purchase Receipt', 'Purchase Order',
'Project', 'User', 'Production Order', 'Product', 'Print Format',
'Price List', 'Purchase Invoice', 'Page', 'Module Def',
'Maintenance Visit', 'Maintenance Schedule', 'Letter Head',
'Leave Application', 'Lead', 'Journal Voucher', 'Item', 'Material Request',
'Expense Claim', 'Opportunity', 'Employee', 'Delivery Note',
'Customer Issue', 'Customer', 'Contact Us Settings', 'Company',
'Blog Post', 'BOM', 'About Us Settings', 'Batch'];
frappe.customize_form.confirm = function(msg, frm) {
if(!frm.doc.doc_type) return;
if(inList(allow_attach_list, doc.doc_type)) {
unhide_field('allow_attach');
} else {
hide_field('allow_attach');
}
}
cur_frm.confirm = function(msg, doc, dt, dn) {
var d = new frappe.ui.Dialog({
title: 'Reset To Defaults',
width: 500
@ -110,16 +95,15 @@ cur_frm.confirm = function(msg, doc, dt, dn) {
$y(button_wrapper, {paddingTop: '15px'});
var proceed_btn = $btn(button_wrapper, 'Proceed', function() {
return cur_frm.call({
doc: cur_frm.doc,
method: "delete",
return frm.call({
doc: frm.doc,
method: "reset_to_defaults",
callback: function(r) {
if(r.exc) {
msgprint(r.exc);
} else {
cur_frm.confirm.dialog.hide();
cur_frm.refresh();
cur_frm.frm_head.set_label(['Saved', 'label-success']);
frappe.customize_form.confirm.dialog.hide();
frappe.customize_form.clear_locals_and_refresh(frm);
}
}
});
@ -128,19 +112,26 @@ cur_frm.confirm = function(msg, doc, dt, dn) {
$y(proceed_btn, {marginRight: '20px', fontWeight: 'bold'});
var cancel_btn = $btn(button_wrapper, 'Cancel', function() {
cur_frm.confirm.dialog.hide();
frappe.customize_form.confirm.dialog.hide();
});
$(cancel_btn).addClass('btn-small btn-info');
$y(cancel_btn, {fontWeight: 'bold'});
cur_frm.confirm.dialog = d;
frappe.customize_form.confirm.dialog = d;
d.show();
}
frappe.customize_form.clear_locals_and_refresh = function(frm) {
// clear doctype from locals
frappe.model.clear_doc("DocType", frm.doc.doc_type);
delete frappe.meta.docfield_copy[frm.doc.doc_type];
frm.refresh();
}
cur_frm.add_fields_help = function() {
$(cur_frm.grids[0].parent).before(
frappe.customize_form.add_fields_help = function(frm) {
$(frm.grids[0].parent).before(
'<div style="padding: 10px">\
<a id="fields_help" class="link_type">Help</a>\
</div>');
@ -223,7 +214,7 @@ cur_frm.add_fields_help = function() {
<tr>\
<td></td>\
<td><a class='link_type' \
onclick='cur_frm.fields_help_dialog.hide()'\
onclick='frappe.customize_form.fields_help_dialog.hide()'\
style='color:grey'>Press Esc to close</a>\
</td>\
</tr>\
@ -235,7 +226,7 @@ cur_frm.add_fields_help = function() {
d.show();
cur_frm.fields_help_dialog = d;
frappe.customize_form.fields_help_dialog = d;
});
}

View file

@ -0,0 +1,133 @@
{
"autoname": "DL.####",
"creation": "2013-01-29 17:55:08.000000",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "doc_type",
"fieldtype": "Link",
"hidden": 0,
"label": "Enter Form Type",
"no_copy": 0,
"options": "DocType",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "properties",
"fieldtype": "Section Break",
"label": "Properties",
"permlevel": 0
},
{
"fieldname": "column_break0",
"fieldtype": "Column Break",
"permlevel": 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",
"label": "Search Fields",
"no_copy": 0,
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "default_print_format",
"fieldtype": "Link",
"label": "Default Print Format",
"no_copy": 0,
"options": "Print Format",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "column_break1",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"fieldname": "allow_print",
"fieldtype": "Check",
"label": "Hide Print",
"no_copy": 0,
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "allow_email",
"fieldtype": "Check",
"label": "Hide Email",
"no_copy": 0,
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "allow_copy",
"fieldtype": "Check",
"label": "Hide Copy",
"no_copy": 0,
"permlevel": 0,
"search_index": 0
},
{
"description": "Note: maximum attachment size = 1mb",
"fieldname": "allow_attach",
"fieldtype": "Check",
"label": "Allow Attach",
"no_copy": 0,
"permlevel": 0,
"search_index": 0
},
{
"depends_on": "eval:cint(doc.allow_attach)",
"fieldname": "max_attachments",
"fieldtype": "Int",
"label": "Max Attachments",
"no_copy": 0,
"permlevel": 0,
"search_index": 0
},
{
"description": "Customize Label, Print Hide, Default etc.",
"fieldname": "fields_section_break",
"fieldtype": "Section Break",
"label": "Fields",
"permlevel": 0
},
{
"fieldname": "customize_form_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": "2014-01-15 16:16:22.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Customize Form",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 0,
"role": "System Manager",
"submit": 0,
"write": 1
}
],
"search_fields": "doc_type"
}

View file

@ -7,345 +7,237 @@ from __future__ import unicode_literals
Thus providing a better UI from user perspective
"""
import frappe, json
from frappe import _
from frappe.utils import cstr
class DocType:
def __init__(self, doc, doclist=[]):
self.doc, self.doclist = doc, doclist
self.doctype_properties = [
'search_fields',
'default_print_format',
'read_only_onload',
'allow_print',
'allow_email',
'allow_copy',
'allow_attach',
'max_attachments'
]
self.docfield_properties = [
'idx',
'label',
'fieldtype',
'fieldname',
'options',
'permlevel',
'width',
'print_width',
'reqd',
'ignore_restrictions',
'in_filter',
'in_list_view',
'hidden',
'print_hide',
'report_hide',
'allow_on_submit',
'depends_on',
'description',
'default',
'name',
]
from frappe.model.document import Document
from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype
self.property_restrictions = {
'fieldtype': [['Currency', 'Float'], ['Small Text', 'Data'], ['Text', 'Text Editor', 'Code']],
}
def get(self):
"""
Gets DocFields applied with Property Setter customizations via Customize Form Field
"""
self.clear()
if self.doc.doc_type:
from frappe.model.doc import addchild
for d in self.get_ref_doclist():
if d.doctype=='DocField':
new = addchild(self.doc, 'fields', 'Customize Form Field',
self.doclist)
self.set(
{
'list': self.docfield_properties,
'doc' : d,
'doc_to_set': new
}
)
elif d.doctype=='DocType':
self.set({ 'list': self.doctype_properties, 'doc': d })
def get_ref_doclist(self):
"""
* Gets doclist of type self.doc.doc_type
* Applies property setter properties on the doclist
* returns the modified doclist
"""
from frappe.model.doctype import get
ref_doclist = get(self.doc.doc_type)
ref_doclist = frappe.doclist([ref_doclist[0]]
+ ref_doclist.get({"parent": self.doc.doc_type}))
return ref_doclist
def clear(self):
"""
Clear fields in the doc
"""
# Clear table before adding new doctype's fields
self.doclist = self.doc.clear_table(self.doclist, 'fields')
self.set({ 'list': self.doctype_properties, 'value': None })
class CustomizeForm(Document):
doctype_properties = {
'search_fields': 'Data',
'default_print_format': 'Data',
'read_only_onload': 'Check',
'allow_print': 'Check',
'allow_email': 'Check',
'allow_copy': 'Check',
'allow_attach': 'Check',
'max_attachments': 'Int'
}
docfield_properties = {
'idx': 'Int',
'label': 'Data',
'fieldtype': 'Select',
'options': 'Text',
'permlevel': 'Int',
'width': 'Data',
'print_width': 'Data',
'reqd': 'Check',
'ignore_restrictions': 'Check',
'in_filter': 'Check',
'in_list_view': 'Check',
'hidden': 'Check',
'print_hide': 'Check',
'report_hide': 'Check',
'allow_on_submit': 'Check',
'depends_on': 'Data',
'description': 'Text',
'default': 'Text'
}
allowed_fieldtype_change = (('Currency', 'Float'), ('Small Text', 'Data'),
('Text', 'Text Editor', 'Code'))
def on_update(self):
frappe.db.sql("delete from tabSingles where doctype='Customize Form'")
frappe.db.sql("delete from `tabCustomize Form Field`")
def fetch_to_customize(self):
self.clear_existing_doc()
if not self.doc_type:
return
meta = frappe.get_meta(self.doc_type)
def set(self, args):
"""
Set a list of attributes of a doc to a value
or to attribute values of a doc passed
args can contain:
* list --> list of attributes to set
* doc_to_set --> defaults to self.doc
* value --> to set all attributes to one value eg. None
* doc --> copy attributes from doc to doc_to_set
"""
if not 'doc_to_set' in args:
args['doc_to_set'] = self.doc
if 'list' in args:
if 'value' in args:
for f in args['list']:
args['doc_to_set'].fields[f] = None
elif 'doc' in args:
for f in args['list']:
args['doc_to_set'].fields[f] = args['doc'].fields.get(f)
else:
frappe.msgprint("Please specify args['list'] to set", raise_exception=1)
def post(self):
"""
Save diff between Customize Form Bean and DocType Bean as property setter entries
"""
if self.doc.doc_type:
from frappe.model import doc
from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype
this_doclist = frappe.doclist([self.doc] + self.doclist)
ref_doclist = self.get_ref_doclist()
dt_doclist = doc.get('DocType', self.doc.doc_type)
# get a list of property setter docs
self.idx_dirty = False
diff_list = self.diff(this_doclist, ref_doclist, dt_doclist)
if self.idx_dirty:
self.make_idx_property_setter(this_doclist, diff_list)
self.set_properties(diff_list)
validate_fields_for_doctype(self.doc.doc_type)
frappe.clear_cache(doctype=self.doc.doc_type)
frappe.msgprint("Updated")
def diff(self, new_dl, ref_dl, dt_dl):
"""
Get difference between new_dl doclist and ref_dl doclist
then check how it differs from dt_dl i.e. default doclist
"""
import re
self.defaults = self.get_defaults()
diff_list = []
for new_d in new_dl:
for ref_d in ref_dl:
if ref_d.doctype == 'DocField' and new_d.name == ref_d.name:
for prop in self.docfield_properties:
# do not set forbidden properties like idx
if prop=="idx":
if ref_d.idx != new_d.idx:
self.idx_dirty = True
continue
# check if its custom field:
if ref_d.get("__custom_field"):
# update custom field
if self.has_property_changed(ref_d, new_d, prop):
# using set_value not bean because validations are called
# in the end anyways
frappe.db.set_value("Custom Field", ref_d.name, prop, new_d.get(prop))
else:
d = self.prepare_to_set(prop, new_d, ref_d, dt_dl)
if d: diff_list.append(d)
break
# doctype properties
for property in self.doctype_properties:
self.set(property, meta.get(property))
for d in meta.get("fields"):
new_d = {"fieldname": d.fieldname, "is_custom_field": d.get("is_custom_field"), "name": d.name}
for property in self.docfield_properties:
new_d[property] = d.get(property)
self.append("customize_form_fields", new_d)
elif ref_d.doctype == 'DocType' and new_d.doctype == 'Customize Form':
for prop in self.doctype_properties:
d = self.prepare_to_set(prop, new_d, ref_d, dt_dl)
if d: diff_list.append(d)
break
return diff_list
def get_defaults(self):
"""
Get fieldtype and default value for properties of a field
"""
df_defaults = frappe.db.sql("""
SELECT fieldname, fieldtype, `default`, label
FROM `tabDocField`
WHERE parent='DocField' or parent='DocType'""", as_dict=1)
# NOTE doc is sent to clientside by run_method
def clear_existing_doc(self):
doc_type = self.doc_type
defaults = {}
for d in df_defaults:
defaults[d['fieldname']] = d
defaults['idx'] = {'fieldname' : 'idx', 'fieldtype' : 'Int', 'default' : 1, 'label' : 'idx'}
defaults['previous_field'] = {'fieldname' : 'previous_field', 'fieldtype' : 'Data', 'default' : None, 'label' : 'Previous Field'}
return defaults
def has_property_changed(self, ref_d, new_d, prop):
return new_d.fields.get(prop) != ref_d.fields.get(prop) \
and not \
( \
new_d.fields.get(prop) in [None, 0] \
and ref_d.fields.get(prop) in [None, 0] \
) and not \
( \
new_d.fields.get(prop) in [None, ''] \
and ref_d.fields.get(prop) in [None, ''] \
)
for fieldname in self.meta.get_valid_columns():
self.set(fieldname, None)
for df in self.meta.get_table_fields():
self.set(df.fieldname, [])
self.doc_type = doc_type
self.name = "Customize Form"
def prepare_to_set(self, prop, new_d, ref_d, dt_doclist, delete=0):
"""
Prepares docs of property setter
sets delete property if it is required to be deleted
"""
# Check if property has changed compared to when it was loaded
if self.has_property_changed(ref_d, new_d, prop):
#frappe.msgprint("new: " + str(new_d.fields[prop]) + " | old: " + str(ref_d.fields[prop]))
# Check if the new property is same as that in original doctype
# If yes, we need to delete the property setter entry
for dt_d in dt_doclist:
if dt_d.name == ref_d.name \
and (new_d.fields.get(prop) == dt_d.fields.get(prop) \
or \
( \
new_d.fields.get(prop) in [None, 0] \
and dt_d.fields.get(prop) in [None, 0] \
) or \
( \
new_d.fields.get(prop) in [None, ''] \
and dt_d.fields.get(prop) in [None, ''] \
)):
delete = 1
break
def save_customization(self):
if not self.doc_type:
return
value = new_d.fields.get(prop)
if prop in self.property_restrictions:
allow_change = False
for restrict_list in self.property_restrictions.get(prop):
if value in restrict_list and \
ref_d.fields.get(prop) in restrict_list:
allow_change = True
break
if not allow_change:
frappe.msgprint("""\
You cannot change '%s' of '%s' from '%s' to '%s'.
%s can only be changed among %s.
<i>Ignoring this change and saving.</i>""" % \
(self.defaults.get(prop, {}).get("label") or prop,
new_d.fields.get("label") or new_d.fields.get("idx"),
ref_d.fields.get(prop), value,
self.defaults.get(prop, {}).get("label") or prop,
" -or- ".join([", ".join(r) for r in \
self.property_restrictions.get(prop)])), raise_exception=True)
return None
# If the above conditions are fulfilled,
# create a property setter doc, but dont save it yet.
from frappe.model.doc import Document
d = Document('Property Setter')
d.doctype_or_field = ref_d.doctype=='DocField' and 'DocField' or 'DocType'
d.doc_type = self.doc.doc_type
d.field_name = ref_d.fieldname
d.property = prop
d.value = value
d.property_type = self.defaults[prop]['fieldtype']
#d.default_value = self.defaults[prop]['default']
if delete: d.delete = 1
if d.select_item:
d.select_item = self.remove_forbidden(d.select_item)
# return the property setter doc
return d
else: return None
def make_idx_property_setter(self, doclist, diff_list):
fields = []
doclist.sort(lambda a, b: a.idx < b.idx)
for d in doclist:
if d.doctype=="Customize Form Field":
fields.append(d.fieldname)
d = frappe.doc('Property Setter')
d.doctype_or_field = 'DocType'
d.doc_type = self.doc.doc_type
d.property = "_idx"
d.value = json.dumps(fields)
d.property_type = "Text"
diff_list.append(d)
def set_properties(self, ps_doclist):
"""
* Delete a property setter entry
+ if it already exists
+ if marked for deletion
* Save the property setter doc in the list
"""
for d in ps_doclist:
# Delete existing property setter entry
if not d.fields.get("field_name"):
frappe.db.sql("""
DELETE FROM `tabProperty Setter`
WHERE doc_type = %(doc_type)s
AND property = %(property)s""", d.fields)
else:
frappe.db.sql("""
DELETE FROM `tabProperty Setter`
WHERE doc_type = %(doc_type)s
AND field_name = %(field_name)s
AND property = %(property)s""", d.fields)
# Save the property setter doc if not marked for deletion i.e. delete=0
if not d.delete:
d.insert()
self.set_property_setters()
self.update_custom_fields()
self.set_idx_property_setter()
validate_fields_for_doctype(self.doc_type)
frappe.msgprint("{}: {} {}.".format(_("DocType"), _(self.doc_type), _("updated")))
frappe.clear_cache(doctype=self.doc_type)
self.fetch_to_customize()
def delete(self):
"""
Deletes all property setter entries for the selected doctype
and resets it to standard
"""
if self.doc.doc_type:
frappe.db.sql("""
DELETE FROM `tabProperty Setter`
WHERE doc_type = %s""", self.doc.doc_type)
def set_property_setters(self):
meta = frappe.get_meta(self.doc_type)
# doctype property setters
for property in self.doctype_properties:
if self.get(property) != meta.get(property):
self.make_property_setter(property=property, value=self.get(property),
property_type=self.doctype_properties[property])
frappe.clear_cache(doctype=self.doc.doc_type)
for df in self.get("customize_form_fields"):
if df.get("__islocal"):
continue
meta_df = meta.get("fields", {"fieldname": df.fieldname})
if not meta_df or meta_df[0].get("is_custom_field"):
continue
for property in self.docfield_properties:
if df.get(property) != meta_df[0].get(property):
if property == "fieldtype":
self.validate_fieldtype_change(df, meta_df[0].get(property), df.get(property))
self.make_property_setter(property=property, value=df.get(property),
property_type=self.docfield_properties[property], fieldname=df.fieldname)
def update_custom_fields(self):
for df in self.get("customize_form_fields"):
if df.get("__islocal"):
self.add_custom_field(df)
else:
self.update_in_custom_field(df)
self.delete_custom_fields()
def add_custom_field(self, df):
d = frappe.new_doc("Custom Field")
d.dt = self.doc_type
for property in self.docfield_properties:
d.set(property, df.get(property))
d.insert()
df.fieldname = d.fieldname
def update_in_custom_field(self, df):
meta = frappe.get_meta(self.doc_type)
meta_df = meta.get("fields", {"fieldname": df.fieldname})
if not (meta_df and meta_df[0].get("is_custom_field")):
return
custom_field = frappe.get_doc("Custom Field", meta_df[0].name)
changed = False
for property in self.docfield_properties:
if df.get(property) != custom_field.get(property):
if property == "fieldtype":
self.validate_fieldtype_change(df, meta_df[0].get(property), df.get(property))
custom_field.set(property, df.get(property))
changed = True
if changed:
custom_field.save()
def delete_custom_fields(self):
meta = frappe.get_meta(self.doc_type)
fields_to_remove = (set([df.fieldname for df in meta.get("fields")])
- set(df.fieldname for df in self.get("customize_form_fields")))
self.get()
for fieldname in fields_to_remove:
df = meta.get("fields", {"fieldname": fieldname})[0]
if df.get("is_custom_field"):
frappe.delete_doc("Custom Field", df.name)
def set_idx_property_setter(self):
meta = frappe.get_meta(self.doc_type)
field_order_has_changed = [df.fieldname for df in meta.get("fields")] != \
[d.fieldname for d in self.get("customize_form_fields")]
if field_order_has_changed:
_idx = []
for df in sorted(self.get("customize_form_fields"), key=lambda x: x.idx):
_idx.append(df.fieldname)
def remove_forbidden(self, string):
"""
Replace forbidden characters with a space
"""
forbidden = ['%', "'", '"', '#', '*', '?', '`']
for f in forbidden:
string.replace(f, ' ')
self.make_property_setter(property="_idx", value=json.dumps(_idx), property_type="Text")
def make_property_setter(self, property, value, property_type, fieldname=None):
self.delete_existing_property_setter(property, fieldname)
property_value = self.get_existing_property_value(property, fieldname)
if property_value==value:
return
# create a new property setter
frappe.make_property_setter({
"doctype": self.doc_type,
"doctype_or_field": "DocField" if fieldname else "DocType",
"fieldname": fieldname,
"property": property,
"value": value,
"property_type": property_type
})
def delete_existing_property_setter(self, property, fieldname=None):
# first delete existing property setter
existing_property_setter = frappe.db.get_value("Property Setter", {"doc_type": self.doc_type,
"property": property, "field_name['']": fieldname or ''})
if existing_property_setter:
frappe.delete_doc("Property Setter", existing_property_setter)
def get_existing_property_value(self, property, fieldname=None):
# check if there is any need to make property setter!
if fieldname:
property_value = frappe.db.get_value("DocField", {"parent": self.doc_type,
"fieldname": fieldname}, property)
else:
try:
property_value = frappe.db.get_value("DocType", self.doc_type, property)
except Exception, e:
if e.args[0]==1054:
property_value = None
else:
raise
return property_value
def validate_fieldtype_change(self, df, old_value, new_value):
for allowed_changes in self.allowed_fieldtype_change:
if ((old_value in allowed_changes and new_value in allowed_changes)
or (old_value not in allowed_changes and new_value not in allowed_changes)):
continue
else:
frappe.throw("{row} # {num}, {label}: {msg} {allowed_changes}".format(
row=_("Row"), num=df.idx, label=_(df.label), msg=_("Field Type can be one of"),
allowed_changes=", ".join([_(fieldtype) for fieldtype in allowed_changes])))
def reset_to_defaults(self):
if not self.doc_type:
return
frappe.db.sql("""delete from `tabProperty Setter` where doc_type=%s""", self.doc_type)
frappe.clear_cache(doctype=self.doc_type)
self.fetch_to_customize()

View file

@ -1,153 +0,0 @@
[
{
"creation": "2013-01-29 17:54:08",
"docstatus": 0,
"modified": "2014-01-15 16:16:23",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"autoname": "DL.####",
"doctype": "DocType",
"hide_toolbar": 1,
"icon": "icon-glass",
"issingle": 1,
"module": "Core",
"name": "__common__",
"search_fields": "doc_type"
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "Customize Form",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"create": 1,
"doctype": "DocPerm",
"email": 1,
"name": "__common__",
"parent": "Customize Form",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"print": 1,
"read": 1,
"report": 0,
"role": "System Manager",
"submit": 0,
"write": 1
},
{
"doctype": "DocType",
"name": "Customize Form"
},
{
"doctype": "DocField",
"fieldname": "doc_type",
"fieldtype": "Link",
"hidden": 0,
"label": "Enter Form Type",
"no_copy": 0,
"options": "DocType",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "properties",
"fieldtype": "Section Break",
"label": "Properties"
},
{
"doctype": "DocField",
"fieldname": "column_break0",
"fieldtype": "Column Break"
},
{
"description": "Fields separated by comma (,) will be included in the<br /><b>Search By</b> list of Search dialog box",
"doctype": "DocField",
"fieldname": "search_fields",
"fieldtype": "Data",
"label": "Search Fields",
"no_copy": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "default_print_format",
"fieldtype": "Link",
"label": "Default Print Format",
"no_copy": 0,
"options": "Print Format",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "column_break1",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"fieldname": "allow_print",
"fieldtype": "Check",
"label": "Hide Print",
"no_copy": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "allow_email",
"fieldtype": "Check",
"label": "Hide Email",
"no_copy": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "allow_copy",
"fieldtype": "Check",
"label": "Hide Copy",
"no_copy": 0,
"search_index": 0
},
{
"description": "Note: maximum attachment size = 1mb",
"doctype": "DocField",
"fieldname": "allow_attach",
"fieldtype": "Check",
"label": "Allow Attach",
"no_copy": 0,
"search_index": 0
},
{
"depends_on": "eval:cint(doc.allow_attach)",
"doctype": "DocField",
"fieldname": "max_attachments",
"fieldtype": "Int",
"label": "Max Attachments",
"no_copy": 0,
"search_index": 0
},
{
"description": "Customize Label, Print Hide, Default etc.",
"doctype": "DocField",
"fieldname": "fields_section_break",
"fieldtype": "Section Break",
"label": "Fields"
},
{
"default": "no add rows",
"doctype": "DocField",
"fieldname": "fields",
"fieldtype": "Table",
"label": "Fields",
"no_copy": 0,
"options": "Customize Form Field",
"search_index": 0
},
{
"doctype": "DocPerm"
}
]

View file

@ -0,0 +1,162 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
from __future__ import unicode_literals
import frappe, unittest, json
from frappe.test_runner import make_test_records_for_doctype
test_dependencies = ["Custom Field", "Property Setter"]
class TestCustomizeForm(unittest.TestCase):
def insert_custom_field(self):
frappe.get_doc({
"doctype": "Custom Field",
"dt": "User",
"label": "Test Custom Field",
"description": "A Custom Field for Testing",
"fieldtype": "Select",
"in_list_view": 1,
"options": "\nCustom 1\nCustom 2\nCustom 3",
"default": "Custom 3"
}).insert()
def delete_custom_field(self):
frappe.delete_doc("Custom Field", "User-test_custom_field")
def setUp(self):
self.insert_custom_field()
frappe.clear_cache(doctype="User")
def tearDown(self):
self.delete_custom_field()
frappe.clear_cache(doctype="User")
def get_customize_form(self, doctype=None):
d = frappe.get_doc("Customize Form")
if doctype:
d.doc_type = doctype
d.run_method("fetch_to_customize")
return d
def test_fetch_to_customize(self):
d = self.get_customize_form()
self.assertEquals(d.doc_type, None)
self.assertEquals(len(d.get("customize_form_fields")), 0)
d = self.get_customize_form("Event")
self.assertEquals(d.doc_type, "Event")
self.assertEquals(len(d.get("customize_form_fields")), 30)
d = self.get_customize_form("User")
self.assertEquals(d.doc_type, "User")
self.assertEquals(len(d.get("customize_form_fields")), 53)
self.assertEquals(d.get("customize_form_fields")[-1].fieldname, "test_custom_field")
self.assertEquals(d.get("customize_form_fields", {"fieldname": "location"})[0].in_list_view, 1)
return d
def test_save_customization_idx(self):
d = self.get_customize_form("User")
original_sequence = [df.fieldname for df in d.get("customize_form_fields")]
# move field to last
location_field = d.get("customize_form_fields", {"fieldname": "location"})[0]
d.get("customize_form_fields").remove(location_field)
d.append("customize_form_fields", location_field)
d.run_method("save_customization")
frappe.clear_cache(doctype=d.doc_type)
property_setter_name, _idx = frappe.db.get_value("Property Setter",
{"doc_type": d.doc_type, "property": "_idx"}, ("name", "value"))
self.assertTrue(_idx)
_idx = json.loads(_idx)
for i, df in enumerate(frappe.get_meta(d.doc_type).get("fields")):
self.assertEquals(_idx[i], df.fieldname)
frappe.delete_doc("Property Setter", property_setter_name)
frappe.clear_cache(doctype=d.doc_type)
for i, df in enumerate(frappe.get_meta(d.doc_type).get("fields")):
self.assertEquals(original_sequence[i], df.fieldname)
def test_save_customization_property(self):
d = self.get_customize_form("User")
self.assertEquals(frappe.db.get_value("Property Setter",
{"doc_type": "User", "property": "allow_copy"}, "value"), None)
d.allow_copy = 1
d.run_method("save_customization")
self.assertEquals(frappe.db.get_value("Property Setter",
{"doc_type": "User", "property": "allow_copy"}, "value"), '1')
d.allow_copy = 0
d.run_method("save_customization")
self.assertEquals(frappe.db.get_value("Property Setter",
{"doc_type": "User", "property": "allow_copy"}, "value"), None)
def test_save_customization_field_property(self):
d = self.get_customize_form("User")
self.assertEquals(frappe.db.get_value("Property Setter",
{"doc_type": "User", "property": "reqd", "field_name": "location"}, "value"), None)
location_field = d.get("customize_form_fields", {"fieldname": "location"})[0]
location_field.reqd = 1
d.run_method("save_customization")
self.assertEquals(frappe.db.get_value("Property Setter",
{"doc_type": "User", "property": "reqd", "field_name": "location"}, "value"), '1')
location_field = d.get("customize_form_fields", {"fieldname": "location"})[0]
location_field.reqd = 0
d.run_method("save_customization")
self.assertEquals(frappe.db.get_value("Property Setter",
{"doc_type": "User", "property": "reqd", "field_name": "location"}, "value"), '0')
def test_save_customization_custom_field_property(self):
d = self.get_customize_form("User")
self.assertEquals(frappe.db.get_value("Custom Field", "User-test_custom_field", "reqd"), None)
custom_field = d.get("customize_form_fields", {"fieldname": "test_custom_field"})[0]
custom_field.reqd = 1
d.run_method("save_customization")
self.assertEquals(frappe.db.get_value("Custom Field", "User-test_custom_field", "reqd"), 1)
custom_field = d.get("customize_form_fields", {"is_custom_field": True})[0]
custom_field.reqd = 0
d.run_method("save_customization")
self.assertEquals(frappe.db.get_value("Custom Field", "User-test_custom_field", "reqd"), 0)
def test_save_customization_new_field(self):
d = self.get_customize_form("User")
d.append("customize_form_fields", {
"label": "Test Add Custom Field Via Customize Form",
"fieldtype": "Data",
"__islocal": 1
})
d.run_method("save_customization")
self.assertEquals(frappe.db.get_value("Custom Field",
"User-test_add_custom_field_via_customize_form", "fieldtype"), "Data")
frappe.delete_doc("Custom Field", "User-test_add_custom_field_via_customize_form")
self.assertEquals(frappe.db.get_value("Custom Field",
"User-test_add_custom_field_via_customize_form"), None)
def test_save_customization_remove_field(self):
d = self.get_customize_form("User")
custom_field = d.get("customize_form_fields", {"fieldname": "test_custom_field"})[0]
d.get("customize_form_fields").remove(custom_field)
d.run_method("save_customization")
self.assertEquals(frappe.db.get_value("Custom Field", custom_field.name), None)
frappe.local.test_objects["Custom Field"] = []
make_test_records_for_doctype("Custom Field")
def test_reset_to_defaults(self):
d = frappe.get_doc("Customize Form")
d.doc_type = "User"
d.run_method('reset_to_defaults')
self.assertEquals(d.get("customize_form_fields", {"fieldname": "location"})[0].in_list_view, None)
frappe.local.test_objects["Property Setter"] = []
make_test_records_for_doctype("Property Setter")

View file

@ -0,0 +1,236 @@
{
"allow_copy": 0,
"autoname": "DLF.#####",
"creation": "2013-02-22 01:27:32.000000",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"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
},
{
"fieldname": "fieldtype",
"fieldtype": "Select",
"hidden": 0,
"in_list_view": 1,
"label": "Type",
"oldfieldname": "fieldtype",
"oldfieldtype": "Select",
"options": "Button\nCheck\nCode\nColumn Break\nCurrency\nData\nDate\nDatetime\nFloat\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,
"search_index": 1
},
{
"description": "For Links, enter the DocType as range\nFor Select, enter list of Options separated by comma",
"fieldname": "options",
"fieldtype": "Text",
"hidden": 0,
"in_list_view": 1,
"label": "Options",
"oldfieldname": "options",
"oldfieldtype": "Text",
"permlevel": 0,
"print_hide": 0,
"reqd": 0,
"search_index": 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": "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": "print_width",
"fieldtype": "Data",
"label": "Print Width",
"permlevel": 0,
"print_width": "50px",
"width": "50px"
},
{
"fieldname": "reqd",
"fieldtype": "Check",
"hidden": 0,
"label": "Reqd",
"oldfieldname": "reqd",
"oldfieldtype": "Check",
"permlevel": 0,
"print_hide": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"fieldname": "ignore_restrictions",
"fieldtype": "Check",
"label": "Ignore Restrictions",
"permlevel": 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": "in_list_view",
"fieldtype": "Check",
"label": "In List View",
"permlevel": 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": "print_hide",
"fieldtype": "Check",
"hidden": 0,
"label": "Print Hide",
"oldfieldname": "print_hide",
"oldfieldtype": "Check",
"permlevel": 0,
"print_hide": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "report_hide",
"fieldtype": "Check",
"hidden": 0,
"label": "Report Hide",
"oldfieldname": "report_hide",
"oldfieldtype": "Check",
"permlevel": 0,
"print_hide": 0,
"reqd": 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
},
{
"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,
"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": "default",
"fieldtype": "Text",
"hidden": 0,
"label": "Default",
"oldfieldname": "default",
"oldfieldtype": "Text",
"permlevel": 0,
"print_hide": 0,
"reqd": 0,
"search_index": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"issingle": 0,
"istable": 1,
"modified": "2013-12-23 16:12:45.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Customize Form Field",
"owner": "Administrator",
"read_only": 0
}

View file

@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
from frappe.model.document import Document
class CustomizeFormField(Document):
pass

View file

@ -1,249 +0,0 @@
[
{
"creation": "2013-02-22 01:27:32",
"docstatus": 0,
"modified": "2013-12-23 16:12:45",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_copy": 0,
"autoname": "DLF.#####",
"doctype": "DocType",
"hide_heading": 0,
"hide_toolbar": 0,
"issingle": 0,
"istable": 1,
"module": "Core",
"name": "__common__",
"read_only": 0
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "Customize Form Field",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"doctype": "DocType",
"name": "Customize Form Field"
},
{
"doctype": "DocField",
"fieldname": "label",
"fieldtype": "Data",
"hidden": 0,
"in_list_view": 1,
"label": "Label",
"oldfieldname": "label",
"oldfieldtype": "Data",
"print_hide": 0,
"reqd": 0,
"search_index": 1
},
{
"doctype": "DocField",
"fieldname": "fieldtype",
"fieldtype": "Select",
"hidden": 0,
"in_list_view": 1,
"label": "Type",
"oldfieldname": "fieldtype",
"oldfieldtype": "Select",
"options": "Button\nCheck\nCode\nColumn Break\nCurrency\nData\nDate\nDatetime\nFloat\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime",
"print_hide": 0,
"reqd": 1,
"search_index": 1
},
{
"doctype": "DocField",
"fieldname": "fieldname",
"fieldtype": "Data",
"hidden": 0,
"in_list_view": 1,
"label": "Name",
"oldfieldname": "fieldname",
"oldfieldtype": "Data",
"print_hide": 0,
"read_only": 1,
"reqd": 0,
"search_index": 1
},
{
"description": "For Links, enter the DocType as range\nFor Select, enter list of Options separated by comma",
"doctype": "DocField",
"fieldname": "options",
"fieldtype": "Text",
"hidden": 0,
"in_list_view": 1,
"label": "Options",
"oldfieldname": "options",
"oldfieldtype": "Text",
"print_hide": 0,
"reqd": 0,
"search_index": 0
},
{
"default": "0",
"doctype": "DocField",
"fieldname": "permlevel",
"fieldtype": "Int",
"hidden": 0,
"in_list_view": 1,
"label": "Perm Level",
"oldfieldname": "permlevel",
"oldfieldtype": "Int",
"print_hide": 0,
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "width",
"fieldtype": "Data",
"hidden": 0,
"in_list_view": 1,
"label": "Width",
"oldfieldname": "width",
"oldfieldtype": "Data",
"print_hide": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"doctype": "DocField",
"fieldname": "print_width",
"fieldtype": "Data",
"label": "Print Width",
"print_width": "50px",
"width": "50px"
},
{
"doctype": "DocField",
"fieldname": "reqd",
"fieldtype": "Check",
"hidden": 0,
"label": "Reqd",
"oldfieldname": "reqd",
"oldfieldtype": "Check",
"print_hide": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"doctype": "DocField",
"fieldname": "ignore_restrictions",
"fieldtype": "Check",
"label": "Ignore Restrictions"
},
{
"doctype": "DocField",
"fieldname": "in_filter",
"fieldtype": "Check",
"hidden": 0,
"label": "In Filter",
"oldfieldname": "in_filter",
"oldfieldtype": "Check",
"print_hide": 0,
"print_width": "50px",
"reqd": 0,
"width": "50px"
},
{
"doctype": "DocField",
"fieldname": "in_list_view",
"fieldtype": "Check",
"label": "In List View"
},
{
"doctype": "DocField",
"fieldname": "hidden",
"fieldtype": "Check",
"hidden": 0,
"label": "Hidden",
"oldfieldname": "hidden",
"oldfieldtype": "Check",
"print_hide": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"doctype": "DocField",
"fieldname": "print_hide",
"fieldtype": "Check",
"hidden": 0,
"label": "Print Hide",
"oldfieldname": "print_hide",
"oldfieldtype": "Check",
"print_hide": 0,
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "report_hide",
"fieldtype": "Check",
"hidden": 0,
"label": "Report Hide",
"oldfieldname": "report_hide",
"oldfieldtype": "Check",
"print_hide": 0,
"reqd": 0
},
{
"doctype": "DocField",
"fieldname": "allow_on_submit",
"fieldtype": "Check",
"hidden": 0,
"label": "Allow on Submit",
"oldfieldname": "allow_on_submit",
"oldfieldtype": "Check",
"print_hide": 0,
"reqd": 0
},
{
"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",
"doctype": "DocField",
"fieldname": "depends_on",
"fieldtype": "Data",
"hidden": 0,
"label": "Depends On",
"oldfieldname": "depends_on",
"oldfieldtype": "Data",
"print_hide": 0,
"reqd": 0
},
{
"doctype": "DocField",
"fieldname": "description",
"fieldtype": "Text",
"hidden": 0,
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Text",
"print_hide": 0,
"print_width": "300px",
"reqd": 0,
"width": "300px"
},
{
"doctype": "DocField",
"fieldname": "default",
"fieldtype": "Text",
"hidden": 0,
"label": "Default",
"oldfieldname": "default",
"oldfieldtype": "Text",
"print_hide": 0,
"reqd": 0,
"search_index": 0
}
]

View file

@ -1,4 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
from __future__ import unicode_literals

View file

@ -1,9 +0,0 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
from __future__ import unicode_literals
import frappe
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl

View file

@ -1,44 +0,0 @@
[
{
"creation": "2013-02-22 01:27:32",
"docstatus": 0,
"modified": "2013-12-20 19:23:05",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doctype": "DocType",
"istable": 1,
"module": "Core",
"name": "__common__"
},
{
"doctype": "DocField",
"fieldtype": "Link",
"in_list_view": 1,
"name": "__common__",
"oldfieldtype": "Link",
"parent": "Default Home Page",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"doctype": "DocType",
"name": "Default Home Page"
},
{
"doctype": "DocField",
"fieldname": "role",
"label": "Role",
"oldfieldname": "role",
"options": "Role"
},
{
"doctype": "DocField",
"fieldname": "home_page",
"label": "Home Page",
"oldfieldname": "home_page",
"options": "Page"
}
]

View file

@ -0,0 +1,48 @@
{
"allow_copy": 0,
"autoname": "DEF.######",
"creation": "2013-02-22 01:27:32.000000",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "defkey",
"fieldtype": "Data",
"hidden": 0,
"in_list_view": 1,
"label": "Key",
"oldfieldname": "defkey",
"oldfieldtype": "Data",
"permlevel": 0,
"print_width": "200px",
"reqd": 1,
"search_index": 0,
"width": "200px"
},
{
"fieldname": "defvalue",
"fieldtype": "Text",
"hidden": 0,
"in_list_view": 1,
"label": "Value",
"oldfieldname": "defvalue",
"oldfieldtype": "Text",
"permlevel": 0,
"print_width": "200px",
"reqd": 0,
"search_index": 0,
"width": "200px"
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"issingle": 0,
"istable": 1,
"modified": "2013-12-20 19:23:05.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "DefaultValue",
"owner": "Administrator",
"read_only": 0
}

View file

@ -4,9 +4,10 @@
from __future__ import unicode_literals
import frappe
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
from frappe.model.document import Document
class DefaultValue(Document):
pass
def on_doctype_update():
if not frappe.db.sql("""show index from `tabDefaultValue`

View file

@ -1,56 +0,0 @@
[
{
"creation": "2013-02-22 01:27:32",
"docstatus": 0,
"modified": "2013-12-20 19:23:05",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_copy": 0,
"autoname": "DEF.######",
"doctype": "DocType",
"hide_heading": 0,
"hide_toolbar": 0,
"issingle": 0,
"istable": 1,
"module": "Core",
"name": "__common__",
"read_only": 0
},
{
"doctype": "DocField",
"hidden": 0,
"in_list_view": 1,
"name": "__common__",
"parent": "DefaultValue",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0,
"print_width": "200px",
"search_index": 0,
"width": "200px"
},
{
"doctype": "DocType",
"name": "DefaultValue"
},
{
"doctype": "DocField",
"fieldname": "defkey",
"fieldtype": "Data",
"label": "Key",
"oldfieldname": "defkey",
"oldfieldtype": "Data",
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "defvalue",
"fieldtype": "Text",
"label": "Value",
"oldfieldname": "defvalue",
"oldfieldtype": "Text",
"reqd": 0
}
]

View file

@ -0,0 +1,312 @@
{
"allow_copy": 0,
"autoname": "FL.#####",
"creation": "2013-02-22 01:27:33.000000",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "label_and_type",
"fieldtype": "Section Break",
"label": "Label and Type",
"permlevel": 0
},
{
"fieldname": "label",
"fieldtype": "Data",
"hidden": 0,
"in_list_view": 1,
"label": "Label",
"oldfieldname": "label",
"oldfieldtype": "Data",
"permlevel": 0,
"print_width": "163",
"reqd": 0,
"search_index": 1,
"width": "163"
},
{
"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\nFloat\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime",
"permlevel": 0,
"reqd": 1,
"search_index": 1
},
{
"fieldname": "fieldname",
"fieldtype": "Data",
"hidden": 0,
"in_list_view": 1,
"label": "Name",
"oldfieldname": "fieldname",
"oldfieldtype": "Data",
"permlevel": 0,
"reqd": 0,
"search_index": 1
},
{
"fieldname": "reqd",
"fieldtype": "Check",
"hidden": 0,
"in_list_view": 1,
"label": "Mandatory",
"oldfieldname": "reqd",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"fieldname": "search_index",
"fieldtype": "Check",
"hidden": 0,
"label": "Index",
"oldfieldname": "search_index",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"fieldname": "in_list_view",
"fieldtype": "Check",
"label": "In List View",
"permlevel": 0,
"print_width": "70px",
"width": "70px"
},
{
"fieldname": "column_break_6",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"description": "For Links, enter the DocType as range\nFor Select, enter list of Options separated by comma",
"fieldname": "options",
"fieldtype": "Text",
"hidden": 0,
"in_list_view": 1,
"label": "Options",
"oldfieldname": "options",
"oldfieldtype": "Text",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "permissions",
"fieldtype": "Section Break",
"label": "Permissions",
"permlevel": 0
},
{
"fieldname": "depends_on",
"fieldtype": "Data",
"label": "Depends On",
"oldfieldname": "depends_on",
"oldfieldtype": "Data",
"permlevel": 0
},
{
"default": "0",
"fieldname": "permlevel",
"fieldtype": "Int",
"hidden": 0,
"label": "Perm Level",
"oldfieldname": "permlevel",
"oldfieldtype": "Int",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"fieldname": "hidden",
"fieldtype": "Check",
"hidden": 0,
"label": "Hidden",
"oldfieldname": "hidden",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"fieldname": "read_only",
"fieldtype": "Check",
"label": "Read Only",
"permlevel": 0,
"print_width": "50px",
"width": "50px"
},
{
"description": "Do not allow user to change after set the first time",
"fieldname": "set_only_once",
"fieldtype": "Check",
"label": "Set Only Once",
"permlevel": 0
},
{
"fieldname": "column_break_13",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"description": "User restrictions should not apply for this Link",
"fieldname": "ignore_restrictions",
"fieldtype": "Check",
"label": "Ignore Restrictions",
"permlevel": 0
},
{
"fieldname": "allow_on_submit",
"fieldtype": "Check",
"label": "Allow on Submit",
"oldfieldname": "allow_on_submit",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"width": "50px"
},
{
"fieldname": "report_hide",
"fieldtype": "Check",
"label": "Report Hide",
"oldfieldname": "report_hide",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"width": "50px"
},
{
"fieldname": "display",
"fieldtype": "Section Break",
"label": "Display",
"permlevel": 0
},
{
"fieldname": "default",
"fieldtype": "Text",
"hidden": 0,
"label": "Default",
"oldfieldname": "default",
"oldfieldtype": "Text",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "in_filter",
"fieldtype": "Check",
"label": "In Filter",
"oldfieldname": "in_filter",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"width": "50px"
},
{
"fieldname": "no_copy",
"fieldtype": "Check",
"label": "No Copy",
"oldfieldname": "no_copy",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"width": "50px"
},
{
"fieldname": "column_break_22",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"fieldname": "description",
"fieldtype": "Text",
"in_list_view": 1,
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Text",
"permlevel": 0,
"print_width": "300px",
"width": "300px"
},
{
"fieldname": "print_hide",
"fieldtype": "Check",
"hidden": 0,
"label": "Print Hide",
"oldfieldname": "print_hide",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"fieldname": "print_width",
"fieldtype": "Data",
"label": "Print Width",
"permlevel": 0
},
{
"fieldname": "width",
"fieldtype": "Data",
"hidden": 0,
"label": "Width",
"oldfieldname": "width",
"oldfieldtype": "Data",
"permlevel": 0,
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"fieldname": "oldfieldname",
"fieldtype": "Data",
"hidden": 1,
"oldfieldname": "oldfieldname",
"oldfieldtype": "Data",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "oldfieldtype",
"fieldtype": "Data",
"hidden": 1,
"oldfieldname": "oldfieldtype",
"oldfieldtype": "Data",
"permlevel": 0,
"reqd": 0,
"search_index": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"in_dialog": 1,
"issingle": 0,
"istable": 1,
"modified": "2014-03-05 14:58:43.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "DocField",
"owner": "Administrator",
"read_only": 0
}

View file

@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
from frappe.model.document import Document
class DocField(Document):
pass

View file

@ -1,325 +0,0 @@
[
{
"creation": "2013-02-22 01:27:33",
"docstatus": 0,
"modified": "2014-03-05 14:58:43",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_copy": 0,
"autoname": "FL.#####",
"doctype": "DocType",
"hide_heading": 0,
"hide_toolbar": 0,
"in_dialog": 1,
"issingle": 0,
"istable": 1,
"module": "Core",
"name": "__common__",
"read_only": 0
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "DocField",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"doctype": "DocType",
"name": "DocField"
},
{
"doctype": "DocField",
"fieldname": "label_and_type",
"fieldtype": "Section Break",
"label": "Label and Type"
},
{
"doctype": "DocField",
"fieldname": "label",
"fieldtype": "Data",
"hidden": 0,
"in_list_view": 1,
"label": "Label",
"oldfieldname": "label",
"oldfieldtype": "Data",
"print_width": "163",
"reqd": 0,
"search_index": 1,
"width": "163"
},
{
"doctype": "DocField",
"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\nFloat\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime",
"reqd": 1,
"search_index": 1
},
{
"doctype": "DocField",
"fieldname": "fieldname",
"fieldtype": "Data",
"hidden": 0,
"in_list_view": 1,
"label": "Name",
"oldfieldname": "fieldname",
"oldfieldtype": "Data",
"reqd": 0,
"search_index": 1
},
{
"doctype": "DocField",
"fieldname": "reqd",
"fieldtype": "Check",
"hidden": 0,
"in_list_view": 1,
"label": "Mandatory",
"oldfieldname": "reqd",
"oldfieldtype": "Check",
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"doctype": "DocField",
"fieldname": "search_index",
"fieldtype": "Check",
"hidden": 0,
"label": "Index",
"oldfieldname": "search_index",
"oldfieldtype": "Check",
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"doctype": "DocField",
"fieldname": "in_list_view",
"fieldtype": "Check",
"label": "In List View",
"print_width": "70px",
"width": "70px"
},
{
"doctype": "DocField",
"fieldname": "column_break_6",
"fieldtype": "Column Break"
},
{
"description": "For Links, enter the DocType as range\nFor Select, enter list of Options separated by comma",
"doctype": "DocField",
"fieldname": "options",
"fieldtype": "Text",
"hidden": 0,
"in_list_view": 1,
"label": "Options",
"oldfieldname": "options",
"oldfieldtype": "Text",
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "permissions",
"fieldtype": "Section Break",
"label": "Permissions"
},
{
"doctype": "DocField",
"fieldname": "depends_on",
"fieldtype": "Data",
"label": "Depends On",
"oldfieldname": "depends_on",
"oldfieldtype": "Data"
},
{
"default": "0",
"doctype": "DocField",
"fieldname": "permlevel",
"fieldtype": "Int",
"hidden": 0,
"label": "Perm Level",
"oldfieldname": "permlevel",
"oldfieldtype": "Int",
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"doctype": "DocField",
"fieldname": "hidden",
"fieldtype": "Check",
"hidden": 0,
"label": "Hidden",
"oldfieldname": "hidden",
"oldfieldtype": "Check",
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"doctype": "DocField",
"fieldname": "read_only",
"fieldtype": "Check",
"label": "Read Only",
"print_width": "50px",
"width": "50px"
},
{
"doctype": "DocField",
"fieldname": "set_only_once",
"fieldtype": "Check",
"label": "Set Only Once",
"description": "Do not allow user to change after set the first time"
},
{
"doctype": "DocField",
"fieldname": "column_break_13",
"fieldtype": "Column Break"
},
{
"description": "User restrictions should not apply for this Link",
"doctype": "DocField",
"fieldname": "ignore_restrictions",
"fieldtype": "Check",
"label": "Ignore Restrictions"
},
{
"doctype": "DocField",
"fieldname": "allow_on_submit",
"fieldtype": "Check",
"label": "Allow on Submit",
"oldfieldname": "allow_on_submit",
"oldfieldtype": "Check",
"print_width": "50px",
"width": "50px"
},
{
"doctype": "DocField",
"fieldname": "report_hide",
"fieldtype": "Check",
"label": "Report Hide",
"oldfieldname": "report_hide",
"oldfieldtype": "Check",
"print_width": "50px",
"width": "50px"
},
{
"doctype": "DocField",
"fieldname": "display",
"fieldtype": "Section Break",
"label": "Display"
},
{
"doctype": "DocField",
"fieldname": "default",
"fieldtype": "Text",
"hidden": 0,
"label": "Default",
"oldfieldname": "default",
"oldfieldtype": "Text",
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "in_filter",
"fieldtype": "Check",
"label": "In Filter",
"oldfieldname": "in_filter",
"oldfieldtype": "Check",
"print_width": "50px",
"width": "50px"
},
{
"doctype": "DocField",
"fieldname": "no_copy",
"fieldtype": "Check",
"label": "No Copy",
"oldfieldname": "no_copy",
"oldfieldtype": "Check",
"print_width": "50px",
"width": "50px"
},
{
"doctype": "DocField",
"fieldname": "column_break_22",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"fieldname": "description",
"fieldtype": "Text",
"in_list_view": 1,
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Text",
"print_width": "300px",
"width": "300px"
},
{
"doctype": "DocField",
"fieldname": "print_hide",
"fieldtype": "Check",
"hidden": 0,
"label": "Print Hide",
"oldfieldname": "print_hide",
"oldfieldtype": "Check",
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"doctype": "DocField",
"fieldname": "print_width",
"fieldtype": "Data",
"label": "Print Width"
},
{
"doctype": "DocField",
"fieldname": "width",
"fieldtype": "Data",
"hidden": 0,
"label": "Width",
"oldfieldname": "width",
"oldfieldtype": "Data",
"print_width": "50px",
"reqd": 0,
"search_index": 0,
"width": "50px"
},
{
"doctype": "DocField",
"fieldname": "oldfieldname",
"fieldtype": "Data",
"hidden": 1,
"oldfieldname": "oldfieldname",
"oldfieldtype": "Data",
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "oldfieldtype",
"fieldtype": "Data",
"hidden": 1,
"oldfieldname": "oldfieldtype",
"oldfieldtype": "Data",
"reqd": 0,
"search_index": 0
}
]

View file

@ -0,0 +1,216 @@
{
"allow_copy": 0,
"autoname": "PERM.#####",
"creation": "2013-02-22 01:27:33.000000",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "role_and_level",
"fieldtype": "Section Break",
"label": "Role and Level",
"permlevel": 0
},
{
"fieldname": "role",
"fieldtype": "Link",
"hidden": 0,
"in_list_view": 1,
"label": "Role",
"oldfieldname": "role",
"oldfieldtype": "Link",
"options": "Role",
"permlevel": 0,
"print_width": "150px",
"reqd": 1,
"search_index": 0,
"width": "150px"
},
{
"fieldname": "column_break_2",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"default": "0",
"fieldname": "permlevel",
"fieldtype": "Int",
"hidden": 0,
"in_list_view": 1,
"label": "Level",
"oldfieldname": "permlevel",
"oldfieldtype": "Int",
"permlevel": 0,
"print_width": "40px",
"reqd": 0,
"search_index": 0,
"width": "40px"
},
{
"fieldname": "section_break_4",
"fieldtype": "Section Break",
"label": "Permissions",
"permlevel": 0
},
{
"fieldname": "read",
"fieldtype": "Check",
"hidden": 0,
"in_list_view": 1,
"label": "Read",
"oldfieldname": "read",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "32px",
"reqd": 0,
"search_index": 0,
"width": "32px"
},
{
"description": "Only restricted users can access",
"fieldname": "restricted",
"fieldtype": "Check",
"label": "Restricted",
"permlevel": 0
},
{
"fieldname": "write",
"fieldtype": "Check",
"hidden": 0,
"in_list_view": 1,
"label": "Write",
"oldfieldname": "write",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "32px",
"reqd": 0,
"search_index": 0,
"width": "32px"
},
{
"fieldname": "create",
"fieldtype": "Check",
"hidden": 0,
"in_list_view": 1,
"label": "Create",
"oldfieldname": "create",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "32px",
"reqd": 0,
"search_index": 0,
"width": "32px"
},
{
"fieldname": "delete",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Delete",
"permlevel": 0
},
{
"fieldname": "column_break_8",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"fieldname": "submit",
"fieldtype": "Check",
"hidden": 0,
"in_list_view": 1,
"label": "Submit",
"oldfieldname": "submit",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "32px",
"reqd": 0,
"search_index": 0,
"width": "32px"
},
{
"fieldname": "cancel",
"fieldtype": "Check",
"hidden": 0,
"in_list_view": 1,
"label": "Cancel",
"oldfieldname": "cancel",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "32px",
"reqd": 0,
"search_index": 0,
"width": "32px"
},
{
"fieldname": "amend",
"fieldtype": "Check",
"label": "Amend",
"oldfieldname": "amend",
"oldfieldtype": "Check",
"permlevel": 0,
"print_width": "32px",
"width": "32px"
},
{
"fieldname": "additional_permissions",
"fieldtype": "Section Break",
"label": "Additional Permissions",
"permlevel": 0
},
{
"fieldname": "report",
"fieldtype": "Check",
"label": "Report",
"permlevel": 0,
"print_width": "32px",
"width": "32px"
},
{
"fieldname": "export",
"fieldtype": "Check",
"label": "Export",
"permlevel": 0
},
{
"fieldname": "import",
"fieldtype": "Check",
"label": "Import",
"permlevel": 0
},
{
"fieldname": "column_break_19",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"fieldname": "print",
"fieldtype": "Check",
"label": "Print",
"permlevel": 0
},
{
"fieldname": "email",
"fieldtype": "Check",
"label": "Email",
"permlevel": 0
},
{
"description": "This role can restrict users for accessing the record.",
"fieldname": "restrict",
"fieldtype": "Check",
"label": "Can Restrict",
"permlevel": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"issingle": 0,
"istable": 1,
"modified": "2014-01-22 14:32:34.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "DocPerm",
"owner": "Administrator",
"read_only": 0
}

View file

@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
from frappe.model.document import Document
class DocPerm(Document):
pass

View file

@ -1,229 +0,0 @@
[
{
"creation": "2013-02-22 01:27:33",
"docstatus": 0,
"modified": "2014-01-22 14:32:34",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_copy": 0,
"autoname": "PERM.#####",
"doctype": "DocType",
"hide_heading": 0,
"hide_toolbar": 0,
"issingle": 0,
"istable": 1,
"module": "Core",
"name": "__common__",
"read_only": 0
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "DocPerm",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"doctype": "DocType",
"name": "DocPerm"
},
{
"doctype": "DocField",
"fieldname": "role_and_level",
"fieldtype": "Section Break",
"label": "Role and Level"
},
{
"doctype": "DocField",
"fieldname": "role",
"fieldtype": "Link",
"hidden": 0,
"in_list_view": 1,
"label": "Role",
"oldfieldname": "role",
"oldfieldtype": "Link",
"options": "Role",
"print_width": "150px",
"reqd": 1,
"search_index": 0,
"width": "150px"
},
{
"doctype": "DocField",
"fieldname": "column_break_2",
"fieldtype": "Column Break"
},
{
"default": "0",
"doctype": "DocField",
"fieldname": "permlevel",
"fieldtype": "Int",
"hidden": 0,
"in_list_view": 1,
"label": "Level",
"oldfieldname": "permlevel",
"oldfieldtype": "Int",
"print_width": "40px",
"reqd": 0,
"search_index": 0,
"width": "40px"
},
{
"doctype": "DocField",
"fieldname": "section_break_4",
"fieldtype": "Section Break",
"label": "Permissions"
},
{
"doctype": "DocField",
"fieldname": "read",
"fieldtype": "Check",
"hidden": 0,
"in_list_view": 1,
"label": "Read",
"oldfieldname": "read",
"oldfieldtype": "Check",
"print_width": "32px",
"reqd": 0,
"search_index": 0,
"width": "32px"
},
{
"description": "Only restricted users can access",
"doctype": "DocField",
"fieldname": "restricted",
"fieldtype": "Check",
"label": "Restricted"
},
{
"doctype": "DocField",
"fieldname": "write",
"fieldtype": "Check",
"hidden": 0,
"in_list_view": 1,
"label": "Write",
"oldfieldname": "write",
"oldfieldtype": "Check",
"print_width": "32px",
"reqd": 0,
"search_index": 0,
"width": "32px"
},
{
"doctype": "DocField",
"fieldname": "create",
"fieldtype": "Check",
"hidden": 0,
"in_list_view": 1,
"label": "Create",
"oldfieldname": "create",
"oldfieldtype": "Check",
"print_width": "32px",
"reqd": 0,
"search_index": 0,
"width": "32px"
},
{
"doctype": "DocField",
"fieldname": "delete",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Delete"
},
{
"doctype": "DocField",
"fieldname": "column_break_8",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"fieldname": "submit",
"fieldtype": "Check",
"hidden": 0,
"in_list_view": 1,
"label": "Submit",
"oldfieldname": "submit",
"oldfieldtype": "Check",
"print_width": "32px",
"reqd": 0,
"search_index": 0,
"width": "32px"
},
{
"doctype": "DocField",
"fieldname": "cancel",
"fieldtype": "Check",
"hidden": 0,
"in_list_view": 1,
"label": "Cancel",
"oldfieldname": "cancel",
"oldfieldtype": "Check",
"print_width": "32px",
"reqd": 0,
"search_index": 0,
"width": "32px"
},
{
"doctype": "DocField",
"fieldname": "amend",
"fieldtype": "Check",
"label": "Amend",
"oldfieldname": "amend",
"oldfieldtype": "Check",
"print_width": "32px",
"width": "32px"
},
{
"doctype": "DocField",
"fieldname": "additional_permissions",
"fieldtype": "Section Break",
"label": "Additional Permissions"
},
{
"doctype": "DocField",
"fieldname": "report",
"fieldtype": "Check",
"label": "Report",
"print_width": "32px",
"width": "32px"
},
{
"doctype": "DocField",
"fieldname": "export",
"fieldtype": "Check",
"label": "Export"
},
{
"doctype": "DocField",
"fieldname": "import",
"fieldtype": "Check",
"label": "Import"
},
{
"doctype": "DocField",
"fieldname": "column_break_19",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"fieldname": "print",
"fieldtype": "Check",
"label": "Print"
},
{
"doctype": "DocField",
"fieldname": "email",
"fieldtype": "Check",
"label": "Email"
},
{
"description": "This role can restrict users for accessing the record.",
"doctype": "DocField",
"fieldname": "restrict",
"fieldtype": "Check",
"label": "Can Restrict"
}
]

View file

@ -0,0 +1,362 @@
{
"allow_attach": 0,
"allow_copy": 0,
"autoname": "Prompt",
"creation": "2013-02-18 13:36:19.000000",
"custom": 0,
"description": "DocType is a Table / Form in the application.",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "sb0",
"fieldtype": "Section Break",
"hidden": 0,
"label": "DocType Details",
"oldfieldtype": "Section Break",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "module",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Module",
"oldfieldname": "module",
"oldfieldtype": "Link",
"options": "Module Def",
"permlevel": 0,
"reqd": 1,
"search_index": 1
},
{
"description": "Child Tables are shown as a Grid in other DocTypes.",
"fieldname": "istable",
"fieldtype": "Check",
"hidden": 0,
"label": "Is Child Table",
"oldfieldname": "istable",
"oldfieldtype": "Check",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"description": "Single Types have only one record no tables associated. Values are stored in tabSingles",
"fieldname": "issingle",
"fieldtype": "Check",
"hidden": 0,
"label": "Is Single",
"oldfieldname": "issingle",
"oldfieldtype": "Check",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "cb01",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"fieldname": "document_type",
"fieldtype": "Select",
"label": "Document Type",
"oldfieldname": "document_type",
"oldfieldtype": "Select",
"options": "\nMaster\nTransaction\nSystem\nOther",
"permlevel": 0
},
{
"fieldname": "icon",
"fieldtype": "Data",
"label": "Icon",
"permlevel": 0
},
{
"fieldname": "custom",
"fieldtype": "Check",
"label": "Custom?",
"no_copy": 0,
"permlevel": 0
},
{
"fieldname": "plugin",
"fieldtype": "Data",
"hidden": 1,
"label": "Plugin",
"permlevel": 0,
"read_only": 0
},
{
"fieldname": "fields_section_break",
"fieldtype": "Section Break",
"hidden": 0,
"label": "Fields",
"oldfieldtype": "Section Break",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "fields",
"fieldtype": "Table",
"hidden": 0,
"label": "Fields",
"oldfieldname": "fields",
"oldfieldtype": "Table",
"options": "DocField",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "sb1",
"fieldtype": "Section Break",
"label": "Naming",
"permlevel": 0
},
{
"description": "<a onclick=\"msgprint('<ol>\\\n<li><b>field:[fieldname]</b> - By Field\\\n<li><b>naming_series:</b> - By Naming Series (field called naming_series must be present\\\n<li><b>Prompt</b> - Prompt user for a name\\\n<li><b>[series]</b> - Series by prefix (separated by a dot); for example PRE.#####\\\n</ol>')\">Naming Options</a>",
"fieldname": "autoname",
"fieldtype": "Data",
"hidden": 0,
"label": "Auto Name",
"oldfieldname": "autoname",
"oldfieldtype": "Data",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "name_case",
"fieldtype": "Select",
"label": "Name Case",
"oldfieldname": "name_case",
"oldfieldtype": "Select",
"options": "\nTitle Case\nUPPER CASE",
"permlevel": 0
},
{
"fieldname": "column_break_15",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"description": "Show this field as title",
"fieldname": "title_field",
"fieldtype": "Data",
"label": "Title Field",
"permlevel": 0
},
{
"fieldname": "search_fields",
"fieldtype": "Data",
"hidden": 0,
"label": "Search Fields",
"oldfieldname": "search_fields",
"oldfieldtype": "Data",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "sb2",
"fieldtype": "Section Break",
"label": "Permission Rules",
"permlevel": 0
},
{
"fieldname": "permissions",
"fieldtype": "Table",
"hidden": 0,
"label": "Permissions",
"oldfieldname": "permissions",
"oldfieldtype": "Table",
"options": "DocPerm",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "sb3",
"fieldtype": "Section Break",
"permlevel": 0
},
{
"fieldname": "cb30",
"fieldtype": "Column Break",
"label": "Permissions Settings",
"permlevel": 0
},
{
"fieldname": "in_create",
"fieldtype": "Check",
"label": "User Cannot Create",
"oldfieldname": "in_create",
"oldfieldtype": "Check",
"permlevel": 0
},
{
"fieldname": "read_only",
"fieldtype": "Check",
"hidden": 0,
"label": "User Cannot Search",
"oldfieldname": "read_only",
"oldfieldtype": "Check",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "is_submittable",
"fieldtype": "Check",
"label": "Is Submittable",
"permlevel": 0
},
{
"description": "Allow Import via Data Import Tool",
"fieldname": "allow_import",
"fieldtype": "Check",
"label": "Allow Import",
"permlevel": 0
},
{
"fieldname": "allow_rename",
"fieldtype": "Check",
"label": "Allow Rename",
"oldfieldname": "allow_rename",
"oldfieldtype": "Check",
"permlevel": 0
},
{
"fieldname": "in_dialog",
"fieldtype": "Check",
"label": "In Dialog",
"oldfieldname": "in_dialog",
"oldfieldtype": "Check",
"permlevel": 0
},
{
"fieldname": "read_only_onload",
"fieldtype": "Check",
"label": "Show Print First",
"oldfieldname": "read_only_onload",
"oldfieldtype": "Check",
"permlevel": 0
},
{
"fieldname": "allow_attach",
"fieldtype": "Check",
"label": "Allow Attach",
"oldfieldname": "allow_attach",
"oldfieldtype": "Check",
"permlevel": 0
},
{
"fieldname": "max_attachments",
"fieldtype": "Int",
"hidden": 1,
"label": "Max Attachments",
"oldfieldname": "max_attachments",
"oldfieldtype": "Int",
"permlevel": 0
},
{
"fieldname": "cb31",
"fieldtype": "Column Break",
"label": "Hide Actions",
"permlevel": 0
},
{
"fieldname": "hide_heading",
"fieldtype": "Check",
"hidden": 0,
"label": "Hide Heading",
"oldfieldname": "hide_heading",
"oldfieldtype": "Check",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "hide_toolbar",
"fieldtype": "Check",
"hidden": 0,
"label": "Hide Toolbar",
"oldfieldname": "hide_toolbar",
"oldfieldtype": "Check",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "allow_copy",
"fieldtype": "Check",
"hidden": 0,
"label": "Hide Copy",
"oldfieldname": "allow_copy",
"oldfieldtype": "Check",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "default_print_format",
"fieldtype": "Data",
"label": "Default Print Format",
"permlevel": 0
},
{
"fieldname": "description",
"fieldtype": "Small Text",
"hidden": 0,
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Text",
"permlevel": 0,
"reqd": 0,
"search_index": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-bolt",
"idx": 1,
"issingle": 0,
"istable": 0,
"modified": "2014-01-27 11:57:14.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "DocType",
"owner": "Administrator",
"permissions": [
{
"cancel": 0,
"delete": 0,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"submit": 0
},
{
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Administrator",
"submit": 0,
"write": 1
}
],
"read_only": 0,
"search_fields": "module"
}

View file

@ -1,5 +1,5 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# MIT License. See license.txt
from __future__ import unicode_literals
@ -9,60 +9,59 @@ import os
from frappe.utils import now, cint
from frappe.model import no_value_fields
from frappe.model.document import Document
class DocType:
def __init__(self, doc=None, doclist=[]):
self.doc = doc
self.doclist = doclist
class DocType(Document):
def validate(self):
if not frappe.conf.get("developer_mode"):
frappe.throw("Not in Developer Mode! Set in site_config.json")
for c in [".", "/", "#", "&", "=", ":", "'", '"']:
if c in self.doc.name:
if c in self.name:
frappe.msgprint(c + " not allowed in name", raise_exception=1)
for d in self.get("fields"):
d.parent = self.name
self.validate_series()
self.scrub_field_names()
self.validate_title_field()
validate_fields(self.doclist.get({"doctype":"DocField"}))
validate_permissions(self.doclist.get({"doctype":"DocPerm"}))
validate_fields(self.get("fields"))
validate_permissions(self.get("permissions"))
self.make_amendable()
self.check_link_replacement_error()
def change_modified_of_parent(self):
if frappe.flags.in_import:
return
parent_list = frappe.db.sql("""SELECT parent
from tabDocField where fieldtype="Table" and options=%s""", self.doc.name)
parent_list = frappe.db.sql("""SELECT parent
from tabDocField where fieldtype="Table" and options=%s""", self.name)
for p in parent_list:
frappe.db.sql('UPDATE tabDocType SET modified=%s WHERE `name`=%s', (now(), p[0]))
def scrub_field_names(self):
restricted = ('name','parent','idx','owner','creation','modified','modified_by',
'parentfield','parenttype',"file_list")
for d in self.doclist:
if d.parent and d.fieldtype:
if (not d.fieldname):
for d in self.get("fields"):
if d.fieldtype:
if (not getattr(d, "fieldname", None)):
if d.label:
d.fieldname = d.label.strip().lower().replace(' ','_')
if d.fieldname in restricted:
d.fieldname = d.fieldname + '1'
else:
d.fieldname = d.fieldtype.lower().replace(" ","_") + "_" + str(d.idx)
def validate_title_field(self):
if self.doc.title_field and \
self.doc.title_field not in [d.fieldname for d in self.doclist.get({"doctype":"DocField"})]:
if self.title_field and \
self.title_field not in [d.fieldname for d in self.get("fields")]:
frappe.throw(_("Title field must be a valid fieldname"))
def validate_series(self, autoname=None, name=None):
if not autoname: autoname = self.doc.autoname
if not name: name = self.doc.name
if not autoname and self.doclist.get({"fieldname":"naming_series"}):
self.doc.autoname = "naming_series:"
if not autoname: autoname = self.autoname
if not name: name = self.name
if not autoname and self.get("fields", {"fieldname":"naming_series"}):
self.autoname = "naming_series:"
if autoname and (not autoname.startswith('field:')) and (not autoname.startswith('eval:')) \
and (not autoname=='Prompt') and (not autoname.startswith('naming_series:')):
prefix = autoname.split('.')[0]
@ -72,140 +71,138 @@ class DocType:
def on_update(self):
from frappe.model.db_schema import updatedb
updatedb(self.doc.name)
updatedb(self.name)
self.change_modified_of_parent()
make_module_and_roles(self.doclist)
make_module_and_roles(self)
from frappe import conf
if (not frappe.flags.in_import) and conf.get('developer_mode') or 0:
self.export_doc()
self.make_controller_template()
# update index
if not self.doc.custom:
from frappe.model.code import load_doctype_module
module = load_doctype_module( self.doc.name, self.doc.module)
if not getattr(self, "custom", False):
from frappe.modules import load_doctype_module
module = load_doctype_module(self.name, self.module)
if hasattr(module, "on_doctype_update"):
module.on_doctype_update()
frappe.clear_cache(doctype=self.doc.name)
frappe.clear_cache(doctype=self.name)
def check_link_replacement_error(self):
for d in self.doclist.get({"doctype":"DocField", "fieldtype":"Select"}):
for d in self.get("fields", {"fieldtype":"Select"}):
if (frappe.db.get_value("DocField", d.name, "options") or "").startswith("link:") \
and not d.options.startswith("link:"):
frappe.msgprint("link: type Select fields are getting replaced. Please check for %s" % d.label,
raise_exception=True)
def on_trash(self):
frappe.db.sql("delete from `tabCustom Field` where dt = %s", self.doc.name)
frappe.db.sql("delete from `tabCustom Script` where dt = %s", self.doc.name)
frappe.db.sql("delete from `tabProperty Setter` where doc_type = %s", self.doc.name)
frappe.db.sql("delete from `tabReport` where ref_doctype=%s", self.doc.name)
frappe.db.sql("delete from `tabCustom Field` where dt = %s", self.name)
frappe.db.sql("delete from `tabCustom Script` where dt = %s", self.name)
frappe.db.sql("delete from `tabProperty Setter` where doc_type = %s", self.name)
frappe.db.sql("delete from `tabReport` where ref_doctype=%s", self.name)
def before_rename(self, old, new, merge=False):
if merge:
frappe.throw(_("DocType can not be merged"))
def after_rename(self, old, new, merge=False):
if self.doc.issingle:
if self.issingle:
frappe.db.sql("""update tabSingles set doctype=%s where doctype=%s""", (new, old))
else:
frappe.db.sql("rename table `tab%s` to `tab%s`" % (old, new))
def export_doc(self):
from frappe.modules.export_file import export_to_files
export_to_files(record_list=[['DocType', self.doc.name]])
export_to_files(record_list=[['DocType', self.name]])
def import_doc(self):
from frappe.modules.import_module import import_from_files
import_from_files(record_list=[[self.doc.module, 'doctype', self.doc.name]])
import_from_files(record_list=[[self.module, 'doctype', self.name]])
def make_controller_template(self):
from frappe.modules import get_doc_path, get_module_path, scrub
pypath = os.path.join(get_doc_path(self.doc.module,
self.doc.doctype, self.doc.name), scrub(self.doc.name) + '.py')
pypath = os.path.join(get_doc_path(self.module,
self.doctype, self.name), scrub(self.name) + '.py')
if not os.path.exists(pypath):
# get app publisher for copyright
app = frappe.local.module_app[frappe.scrub(self.doc.module)]
app = frappe.local.module_app[frappe.scrub(self.module)]
if not app:
frappe.throw("App not found!")
app_publisher = frappe.get_hooks(hook="app_publisher", app_name=app)[0]
with open(pypath, 'w') as pyfile:
with open(os.path.join(get_module_path("core"), "doctype", "doctype",
with open(os.path.join(get_module_path("core"), "doctype", "doctype",
"doctype_template.py"), 'r') as srcfile:
pyfile.write(srcfile.read().format(app_publisher=app_publisher))
pyfile.write(srcfile.read().format(app_publisher=app_publisher, classname=self.name.replace(" ", "")))
def make_amendable(self):
"""
if is_submittable is set, add amended_from docfields
"""
if self.doc.is_submittable:
if not frappe.db.sql("""select name from tabDocField
where fieldname = 'amended_from' and parent = %s""", self.doc.name):
new = self.doc.addchild('fields', 'DocField', self.doclist)
new.label = 'Amended From'
new.fieldtype = 'Link'
new.fieldname = 'amended_from'
new.options = self.doc.name
new.permlevel = 0
new.read_only = 1
new.print_hide = 1
new.no_copy = 1
new.idx = self.get_max_idx() + 1
if self.is_submittable:
if not frappe.db.sql("""select name from tabDocField
where fieldname = 'amended_from' and parent = %s""", self.name):
self.append("fields", {
"label": "Amended From",
"fieldtype": "Link",
"fieldname": "amended_from",
"options": self.name,
"read_only": 1,
"print_hide": 1,
"no_copy": 1
})
def get_max_idx(self):
max_idx = frappe.db.sql("""select max(idx) from `tabDocField` where parent = %s""",
self.doc.name)
max_idx = frappe.db.sql("""select max(idx) from `tabDocField` where parent = %s""",
self.name)
return max_idx and max_idx[0][0] or 0
def validate_fields_for_doctype(doctype):
from frappe.model.doctype import get
validate_fields(get(doctype, cached=False).get({"parent":doctype,
"doctype":"DocField"}))
validate_fields(frappe.get_meta(doctype).get("fields"))
def validate_fields(fields):
def check_illegal_characters(fieldname):
for c in ['.', ',', ' ', '-', '&', '%', '=', '"', "'", '*', '$',
for c in ['.', ',', ' ', '-', '&', '%', '=', '"', "'", '*', '$',
'(', ')', '[', ']', '/']:
if c in fieldname:
frappe.msgprint("'%s' not allowed in fieldname (%s)" % (c, fieldname))
def check_unique_fieldname(fieldname):
duplicates = filter(None, map(lambda df: df.fieldname==fieldname and str(df.idx) or None, fields))
if len(duplicates) > 1:
frappe.msgprint('Fieldname <b>%s</b> appears more than once in rows (%s). Please rectify' \
% (fieldname, ', '.join(duplicates)), raise_exception=1)
def check_illegal_mandatory(d):
if d.fieldtype in ('HTML', 'Button', 'Section Break', 'Column Break') and d.reqd:
frappe.msgprint('%(label)s [%(fieldtype)s] cannot be mandatory' % d.fields,
print d.fieldname, d.reqd
frappe.msgprint('%(parent)s, %(label)s [%(fieldtype)s] cannot be mandatory' % d.as_dict(),
raise_exception=1)
def check_link_table_options(d):
if d.fieldtype in ("Link", "Table"):
if not d.options:
frappe.msgprint("""#%(idx)s %(label)s: Options must be specified for Link and Table type fields""" % d.fields,
frappe.msgprint("""#%(idx)s %(label)s: Options must be specified for Link and Table type fields""" % d.as_dict(),
raise_exception=1)
if d.options=="[Select]":
if d.options=="[Select]" or d.options==d.parent:
return
if d.options != d.parent and not frappe.db.exists("DocType", d.options):
frappe.msgprint("""#%(idx)s %(label)s: Options %(options)s must be a valid "DocType" for Link and Table type fields""" % d.fields,
frappe.msgprint("""#%(idx)s %(label)s: Options %(options)s must be a valid "DocType" for Link and Table type fields""" % d.as_dict(),
raise_exception=1)
def check_hidden_and_mandatory(d):
if d.hidden and d.reqd and not d.default:
frappe.msgprint("""#%(idx)s %(label)s: Cannot be hidden and mandatory (reqd) without default""" % d.fields,
frappe.msgprint("""#%(idx)s %(label)s: Cannot be hidden and mandatory (reqd) without default""" % d.as_dict(),
raise_exception=True)
def check_min_items_in_list(fields):
if len(filter(lambda d: d.in_list_view, fields))==0:
for d in fields[:5]:
d.in_list_view = 1
def check_width(d):
if d.fieldtype == "Currency" and cint(d.width) < 100:
frappe.msgprint("Minimum width for FieldType 'Currency' is 100px", raise_exception=1)
@ -228,49 +225,53 @@ def validate_fields(fields):
check_min_items_in_list(fields)
def validate_permissions_for_doctype(doctype, for_remove=False):
from frappe.model.doctype import get
validate_permissions(get(doctype, cached=False).get({"parent":doctype,
"doctype":"DocPerm"}), for_remove)
validate_permissions(frappe.get_meta(doctype, cached=False).get("permissions"), for_remove)
def validate_permissions(permissions, for_remove=False):
doctype = permissions and permissions[0].parent
issingle = issubmittable = isimportable = False
if doctype and not doctype.startswith("New DocType"):
values = frappe.db.get_value("DocType", doctype,
["issingle", "is_submittable", "allow_import"], as_dict=True)
values = frappe.db.get_value("DocType", doctype,
["issingle", "is_submittable", "allow_import"], as_dict=True)
if values:
issingle = cint(values.issingle)
issubmittable = cint(values.is_submittable)
isimportable = cint(values.allow_import)
def get_txt(d):
return "For %s (level %s) in %s, row #%s:" % (d.role, d.permlevel, d.parent, d.idx)
def check_atleast_one_set(d):
if not d.read and not d.write and not d.submit and not d.cancel and not d.create:
frappe.msgprint(get_txt(d) + " Atleast one of Read, Write, Create, Submit, Cancel must be set.",
raise_exception=True)
def check_double(d):
similar = permissions.get({
"role":d.role,
"permlevel":d.permlevel,
"match": d.match
})
if len(similar) > 1:
frappe.msgprint(get_txt(d) + " Only one rule allowed for a particular Role and Level.",
has_similar = False
for p in permissions:
if p.role==d.role and p.permlevel==d.permlevel and p.match==d.match and p!=d:
has_similar = True
break
if has_similar:
frappe.msgprint(get_txt(d) + " Only one rule allowed for a particular Role and Level.",
raise_exception=True)
def check_level_zero_is_set(d):
if cint(d.permlevel) > 0 and d.role != 'All':
if not permissions.get({"role": d.role, "permlevel": 0}):
has_zero_perm = False
for p in permissions:
if p.role==d.role and (p.permlevel or 0)==0 and p!=d:
has_zero_perm = True
break
if not has_zero_perm:
frappe.msgprint(get_txt(d) + " Higher level permissions are meaningless if level 0 permission is not set.",
raise_exception=True)
if d.create or d.submit or d.cancel or d.amend or d.match:
if d.create or d.submit or d.cancel or d.amend or d.match:
frappe.msgprint("Create, Submit, Cancel, Amend, Match has no meaning at level " + d.permlevel,
raise_exception=True)
def check_permission_dependency(d):
if d.cancel and not d.submit:
frappe.msgprint(get_txt(d) + " Cannot set Cancel permission if Submit is not set.",
@ -281,29 +282,29 @@ def validate_permissions(permissions, for_remove=False):
if d.amend and not d.write:
frappe.msgprint(get_txt(d) + " Cannot set Amend if Cancel is not set.",
raise_exception=True)
if (d.fields.get("import") or d.export) and not d.report:
if (d.get("import") or d.export) and not d.report:
frappe.msgprint(get_txt(d) + " Cannot set Import or Export permission if Report is not set.",
raise_exception=True)
if d.fields.get("import") and not d.create:
if d.get("import") and not d.create:
frappe.msgprint(get_txt(d) + " Cannot set Import if Create is not set.",
raise_exception=True)
def remove_rights_for_single(d):
if not issingle:
return
if d.report:
frappe.msgprint("{doctype} {meaningless}".format(doctype=doctype,
meaningless=_("is a single DocType, permission of type Report is meaningless.")))
d.report = 0
d.fields["import"] = 0
d.fields["export"] = 0
d.set("import", 0)
d.set("export", 0)
if d.restrict:
frappe.msgprint("{doctype} {meaningless}".format(doctype=doctype,
meaningless=_("is a single DocType, permission of type Restrict is meaningless.")))
d.restrict = 0
def check_if_submittable(d):
if d.submit and not issubmittable:
frappe.msgprint(doctype + " is not Submittable, cannot assign submit rights.",
@ -311,14 +312,14 @@ def validate_permissions(permissions, for_remove=False):
elif d.amend and not issubmittable:
frappe.msgprint(doctype + " is not Submittable, cannot assign amend rights.",
raise_exception=True)
def check_if_importable(d):
if d.fields.get("import") and not isimportable:
if d.get("import") and not isimportable:
frappe.throw("{doctype}: {not_importable}".format(doctype=doctype,
not_importable=_("is not allowed to be imported, cannot assign import rights.")))
for d in permissions:
if not d.permlevel:
if not d.permlevel:
d.permlevel=0
check_atleast_one_set(d)
if not for_remove:
@ -329,19 +330,22 @@ def validate_permissions(permissions, for_remove=False):
check_level_zero_is_set(d)
remove_rights_for_single(d)
def make_module_and_roles(doclist, perm_doctype="DocPerm"):
def make_module_and_roles(doc, perm_fieldname="permissions"):
try:
if not frappe.db.exists("Module Def", doclist[0].module):
m = frappe.bean({"doctype": "Module Def", "module_name": doclist[0].module})
if not frappe.db.exists("Module Def", doc.module):
m = frappe.get_doc({"doctype": "Module Def", "module_name": doc.module})
m.app_name = frappe.local.module_app[frappe.scrub(doc.module)]
m.ignore_mandatory = m.ignore_permissions = True
m.insert()
default_roles = ["Administrator", "Guest", "All"]
roles = [p.role for p in doclist.get({"doctype": perm_doctype})] + default_roles
roles = [p.role for p in doc.get("permissions") or []] + default_roles
for role in list(set(roles)):
if not frappe.db.exists("Role", role):
r = frappe.bean({"doctype": "Role", "role_name": role})
r.doc.role_name = role
r = frappe.get_doc({"doctype": "Role", "role_name": role})
r.role_name = role
r.ignore_mandatory = r.ignore_permissions = True
r.insert()
except frappe.DoesNotExistError, e:
pass

View file

@ -1,375 +0,0 @@
[
{
"creation": "2013-02-18 13:36:19",
"docstatus": 0,
"modified": "2014-01-27 11:57:14",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_attach": 0,
"allow_copy": 0,
"autoname": "Prompt",
"custom": 0,
"description": "DocType is a Table / Form in the application.",
"doctype": "DocType",
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-bolt",
"issingle": 0,
"istable": 0,
"module": "Core",
"name": "__common__",
"read_only": 0,
"search_fields": "module"
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "DocType",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"cancel": 0,
"doctype": "DocPerm",
"email": 1,
"name": "__common__",
"parent": "DocType",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"submit": 0
},
{
"doctype": "DocType",
"name": "DocType"
},
{
"doctype": "DocField",
"fieldname": "sb0",
"fieldtype": "Section Break",
"hidden": 0,
"label": "DocType Details",
"oldfieldtype": "Section Break",
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "module",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Module",
"oldfieldname": "module",
"oldfieldtype": "Link",
"options": "Module Def",
"reqd": 1,
"search_index": 1
},
{
"description": "Child Tables are shown as a Grid in other DocTypes.",
"doctype": "DocField",
"fieldname": "istable",
"fieldtype": "Check",
"hidden": 0,
"label": "Is Child Table",
"oldfieldname": "istable",
"oldfieldtype": "Check",
"reqd": 0,
"search_index": 0
},
{
"description": "Single Types have only one record no tables associated. Values are stored in tabSingles",
"doctype": "DocField",
"fieldname": "issingle",
"fieldtype": "Check",
"hidden": 0,
"label": "Is Single",
"oldfieldname": "issingle",
"oldfieldtype": "Check",
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "cb01",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"fieldname": "document_type",
"fieldtype": "Select",
"label": "Document Type",
"oldfieldname": "document_type",
"oldfieldtype": "Select",
"options": "\nMaster\nTransaction\nSystem\nOther"
},
{
"doctype": "DocField",
"fieldname": "icon",
"fieldtype": "Data",
"label": "Icon"
},
{
"doctype": "DocField",
"fieldname": "custom",
"fieldtype": "Check",
"label": "Custom?",
"no_copy": 0
},
{
"doctype": "DocField",
"fieldname": "plugin",
"fieldtype": "Data",
"hidden": 1,
"label": "Plugin",
"read_only": 0
},
{
"doctype": "DocField",
"fieldname": "fields_section_break",
"fieldtype": "Section Break",
"hidden": 0,
"label": "Fields",
"oldfieldtype": "Section Break",
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "fields",
"fieldtype": "Table",
"hidden": 0,
"label": "Fields",
"oldfieldname": "fields",
"oldfieldtype": "Table",
"options": "DocField",
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "sb1",
"fieldtype": "Section Break",
"label": "Naming"
},
{
"description": "<a onclick=\"msgprint('<ol>\\\n<li><b>field:[fieldname]</b> - By Field\\\n<li><b>naming_series:</b> - By Naming Series (field called naming_series must be present\\\n<li><b>Prompt</b> - Prompt user for a name\\\n<li><b>[series]</b> - Series by prefix (separated by a dot); for example PRE.#####\\\n</ol>')\">Naming Options</a>",
"doctype": "DocField",
"fieldname": "autoname",
"fieldtype": "Data",
"hidden": 0,
"label": "Auto Name",
"oldfieldname": "autoname",
"oldfieldtype": "Data",
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "name_case",
"fieldtype": "Select",
"label": "Name Case",
"oldfieldname": "name_case",
"oldfieldtype": "Select",
"options": "\nTitle Case\nUPPER CASE"
},
{
"doctype": "DocField",
"fieldname": "column_break_15",
"fieldtype": "Column Break"
},
{
"description": "Show this field as title",
"doctype": "DocField",
"fieldname": "title_field",
"fieldtype": "Data",
"label": "Title Field"
},
{
"doctype": "DocField",
"fieldname": "search_fields",
"fieldtype": "Data",
"hidden": 0,
"label": "Search Fields",
"oldfieldname": "search_fields",
"oldfieldtype": "Data",
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "sb2",
"fieldtype": "Section Break",
"label": "Permission Rules"
},
{
"doctype": "DocField",
"fieldname": "permissions",
"fieldtype": "Table",
"hidden": 0,
"label": "Permissions",
"oldfieldname": "permissions",
"oldfieldtype": "Table",
"options": "DocPerm",
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "sb3",
"fieldtype": "Section Break"
},
{
"doctype": "DocField",
"fieldname": "cb30",
"fieldtype": "Column Break",
"label": "Permissions Settings"
},
{
"doctype": "DocField",
"fieldname": "in_create",
"fieldtype": "Check",
"label": "User Cannot Create",
"oldfieldname": "in_create",
"oldfieldtype": "Check"
},
{
"doctype": "DocField",
"fieldname": "read_only",
"fieldtype": "Check",
"hidden": 0,
"label": "User Cannot Search",
"oldfieldname": "read_only",
"oldfieldtype": "Check",
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "is_submittable",
"fieldtype": "Check",
"label": "Is Submittable"
},
{
"description": "Allow Import via Data Import Tool",
"doctype": "DocField",
"fieldname": "allow_import",
"fieldtype": "Check",
"label": "Allow Import"
},
{
"doctype": "DocField",
"fieldname": "allow_rename",
"fieldtype": "Check",
"label": "Allow Rename",
"oldfieldname": "allow_rename",
"oldfieldtype": "Check"
},
{
"doctype": "DocField",
"fieldname": "in_dialog",
"fieldtype": "Check",
"label": "In Dialog",
"oldfieldname": "in_dialog",
"oldfieldtype": "Check"
},
{
"doctype": "DocField",
"fieldname": "read_only_onload",
"fieldtype": "Check",
"label": "Show Print First",
"oldfieldname": "read_only_onload",
"oldfieldtype": "Check"
},
{
"doctype": "DocField",
"fieldname": "allow_attach",
"fieldtype": "Check",
"label": "Allow Attach",
"oldfieldname": "allow_attach",
"oldfieldtype": "Check"
},
{
"doctype": "DocField",
"fieldname": "max_attachments",
"fieldtype": "Int",
"hidden": 1,
"label": "Max Attachments",
"oldfieldname": "max_attachments",
"oldfieldtype": "Int"
},
{
"doctype": "DocField",
"fieldname": "cb31",
"fieldtype": "Column Break",
"label": "Hide Actions"
},
{
"doctype": "DocField",
"fieldname": "hide_heading",
"fieldtype": "Check",
"hidden": 0,
"label": "Hide Heading",
"oldfieldname": "hide_heading",
"oldfieldtype": "Check",
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "hide_toolbar",
"fieldtype": "Check",
"hidden": 0,
"label": "Hide Toolbar",
"oldfieldname": "hide_toolbar",
"oldfieldtype": "Check",
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "allow_copy",
"fieldtype": "Check",
"hidden": 0,
"label": "Hide Copy",
"oldfieldname": "allow_copy",
"oldfieldtype": "Check",
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "default_print_format",
"fieldtype": "Data",
"label": "Default Print Format"
},
{
"doctype": "DocField",
"fieldname": "description",
"fieldtype": "Small Text",
"hidden": 0,
"label": "Description",
"oldfieldname": "description",
"oldfieldtype": "Text",
"reqd": 0,
"search_index": 0
},
{
"delete": 0,
"doctype": "DocPerm",
"role": "System Manager"
},
{
"create": 1,
"delete": 1,
"doctype": "DocPerm",
"role": "Administrator",
"write": 1
}
]

View file

@ -3,7 +3,7 @@
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
class {classname}(Document):
pass

View file

@ -0,0 +1,282 @@
{
"autoname": "EV.#####",
"creation": "2013-06-10 13:17:47.000000",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "details",
"fieldtype": "Section Break",
"label": "Details",
"oldfieldtype": "Section Break",
"permlevel": 0
},
{
"fieldname": "subject",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Subject",
"permlevel": 0,
"reqd": 1
},
{
"fieldname": "event_type",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Event Type",
"no_copy": 0,
"oldfieldname": "event_type",
"oldfieldtype": "Select",
"options": "Private\nPublic\nCancel",
"permlevel": 0,
"reqd": 1,
"search_index": 1
},
{
"default": "1",
"fieldname": "send_reminder",
"fieldtype": "Check",
"label": "Send an email reminder in the morning",
"permlevel": 0
},
{
"fieldname": "column_break_4",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"fieldname": "all_day",
"fieldtype": "Check",
"label": "All Day",
"permlevel": 0
},
{
"fieldname": "starts_on",
"fieldtype": "Datetime",
"label": "Starts on",
"permlevel": 0,
"reqd": 1
},
{
"fieldname": "ends_on",
"fieldtype": "Datetime",
"label": "Ends on",
"permlevel": 0,
"reqd": 0
},
{
"fieldname": "section_break_8",
"fieldtype": "Section Break",
"permlevel": 0
},
{
"fieldname": "repeat_this_event",
"fieldtype": "Check",
"label": "Repeat this Event",
"permlevel": 0
},
{
"depends_on": "repeat_this_event",
"fieldname": "section_break_11",
"fieldtype": "Section Break",
"permlevel": 0
},
{
"depends_on": "repeat_this_event",
"fieldname": "repeat_on",
"fieldtype": "Select",
"label": "Repeat On",
"options": "\nEvery Day\nEvery Week\nEvery Month\nEvery Year",
"permlevel": 0
},
{
"depends_on": "repeat_this_event",
"description": "Leave blank to repeat always",
"fieldname": "repeat_till",
"fieldtype": "Date",
"label": "Repeat Till",
"permlevel": 0
},
{
"fieldname": "column_break_11",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"fieldname": "monday",
"fieldtype": "Check",
"label": "Monday",
"permlevel": 0
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"fieldname": "tuesday",
"fieldtype": "Check",
"label": "Tuesday",
"permlevel": 0
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"fieldname": "wednesday",
"fieldtype": "Check",
"label": "Wednesday",
"permlevel": 0
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"fieldname": "thursday",
"fieldtype": "Check",
"label": "Thursday",
"permlevel": 0
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"fieldname": "friday",
"fieldtype": "Check",
"label": "Friday",
"permlevel": 0
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"fieldname": "saturday",
"fieldtype": "Check",
"label": "Saturday",
"permlevel": 0
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"fieldname": "sunday",
"fieldtype": "Check",
"label": "Sunday",
"permlevel": 0
},
{
"fieldname": "section_break_6",
"fieldtype": "Section Break",
"permlevel": 0
},
{
"fieldname": "description",
"fieldtype": "Text Editor",
"in_list_view": 0,
"label": "Description",
"no_copy": 0,
"oldfieldname": "description",
"oldfieldtype": "Text",
"permlevel": 0,
"print_width": "300px",
"search_index": 0,
"width": "300px"
},
{
"fieldname": "participants",
"fieldtype": "Section Break",
"label": "Participants",
"oldfieldtype": "Section Break",
"permlevel": 0
},
{
"fieldname": "individuals",
"fieldtype": "Column Break",
"label": "Individuals",
"oldfieldtype": "Column Break",
"permlevel": 0,
"print_width": "50%",
"width": "50%"
},
{
"fieldname": "event_individuals",
"fieldtype": "Table",
"label": "Event Individuals",
"no_copy": 0,
"oldfieldname": "event_individuals",
"oldfieldtype": "Table",
"options": "Event User",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "groups",
"fieldtype": "Column Break",
"label": "Groups",
"oldfieldtype": "Column Break",
"permlevel": 0,
"print_width": "50%",
"width": "50%"
},
{
"fieldname": "event_roles",
"fieldtype": "Table",
"label": "Event Roles",
"no_copy": 0,
"oldfieldname": "event_roles",
"oldfieldtype": "Table",
"options": "Event Role",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "ref_type",
"fieldtype": "Data",
"hidden": 0,
"label": "Ref Type",
"no_copy": 0,
"oldfieldname": "ref_type",
"oldfieldtype": "Data",
"permlevel": 0,
"read_only": 1,
"search_index": 0
},
{
"fieldname": "ref_name",
"fieldtype": "Data",
"hidden": 0,
"label": "Ref Name",
"no_copy": 0,
"oldfieldname": "ref_name",
"oldfieldtype": "Data",
"permlevel": 0,
"read_only": 1,
"search_index": 0
}
],
"icon": "icon-calendar",
"idx": 1,
"in_create": 1,
"modified": "2014-01-24 13:00:01.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Event",
"owner": "Administrator",
"permissions": [
{
"cancel": 0,
"create": 1,
"delete": 0,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "All",
"submit": 0,
"write": 1
},
{
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"submit": 0,
"write": 1
}
],
"read_only": 1,
"title_field": "subject"
}

View file

@ -14,14 +14,6 @@ class Event(Document):
def validate(self):
if self.starts_on and self.ends_on and self.starts_on > self.ends_on:
frappe.msgprint(frappe._("Event End must be after Start"), raise_exception=True)
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
def validate(self):
if self.doc.starts_on and self.doc.ends_on and self.doc.starts_on > self.doc.ends_on:
frappe.msgprint(frappe._("Event End must be after Start"), raise_exception=True)
def get_permission_query_conditions():
return """(tabEvent.event_type='Public' or tabEvent.owner='%(user)s'
@ -35,21 +27,14 @@ def get_permission_query_conditions():
"roles": "', '".join(frappe.get_roles(frappe.session.user))
}
def has_permission(doc, bean=None):
def has_permission(doc):
if doc.event_type=="Public" or doc.owner==frappe.session.user:
return True
# need full doclist to check roles and users
if not bean:
bean = frappe.bean("Event", doc.name)
if len(bean.doclist)==1:
return False
if bean.doclist.get({"doctype":"Event User", "person":frappe.session.user}):
if doc.get("event_individuals", {"person":frappe.session.user}):
return True
if bean.doclist.get({"doctype":"Event Role", "role":("in", frappe.get_roles())}):
if doc.get("event_roles", {"role":("in", frappe.get_roles())}):
return True
return False

View file

@ -1,293 +0,0 @@
[
{
"creation": "2013-06-10 13:17:47",
"docstatus": 0,
"modified": "2014-01-24 13:00:01",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"autoname": "EV.#####",
"doctype": "DocType",
"icon": "icon-calendar",
"in_create": 1,
"module": "Core",
"name": "__common__",
"read_only": 1,
"title_field": "subject"
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "Event",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"cancel": 0,
"create": 1,
"doctype": "DocPerm",
"email": 1,
"name": "__common__",
"parent": "Event",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"submit": 0,
"write": 1
},
{
"doctype": "DocType",
"name": "Event"
},
{
"doctype": "DocField",
"fieldname": "details",
"fieldtype": "Section Break",
"label": "Details",
"oldfieldtype": "Section Break"
},
{
"doctype": "DocField",
"fieldname": "subject",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Subject",
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "event_type",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Event Type",
"no_copy": 0,
"oldfieldname": "event_type",
"oldfieldtype": "Select",
"options": "Private\nPublic\nCancel",
"reqd": 1,
"search_index": 1
},
{
"default": "1",
"doctype": "DocField",
"fieldname": "send_reminder",
"fieldtype": "Check",
"label": "Send an email reminder in the morning"
},
{
"doctype": "DocField",
"fieldname": "column_break_4",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"fieldname": "all_day",
"fieldtype": "Check",
"label": "All Day"
},
{
"doctype": "DocField",
"fieldname": "starts_on",
"fieldtype": "Datetime",
"label": "Starts on",
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "ends_on",
"fieldtype": "Datetime",
"label": "Ends on",
"reqd": 0
},
{
"doctype": "DocField",
"fieldname": "section_break_8",
"fieldtype": "Section Break"
},
{
"doctype": "DocField",
"fieldname": "repeat_this_event",
"fieldtype": "Check",
"label": "Repeat this Event"
},
{
"depends_on": "repeat_this_event",
"doctype": "DocField",
"fieldname": "section_break_11",
"fieldtype": "Section Break"
},
{
"depends_on": "repeat_this_event",
"doctype": "DocField",
"fieldname": "repeat_on",
"fieldtype": "Select",
"label": "Repeat On",
"options": "\nEvery Day\nEvery Week\nEvery Month\nEvery Year"
},
{
"depends_on": "repeat_this_event",
"description": "Leave blank to repeat always",
"doctype": "DocField",
"fieldname": "repeat_till",
"fieldtype": "Date",
"label": "Repeat Till"
},
{
"doctype": "DocField",
"fieldname": "column_break_11",
"fieldtype": "Column Break"
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"doctype": "DocField",
"fieldname": "monday",
"fieldtype": "Check",
"label": "Monday"
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"doctype": "DocField",
"fieldname": "tuesday",
"fieldtype": "Check",
"label": "Tuesday"
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"doctype": "DocField",
"fieldname": "wednesday",
"fieldtype": "Check",
"label": "Wednesday"
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"doctype": "DocField",
"fieldname": "thursday",
"fieldtype": "Check",
"label": "Thursday"
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"doctype": "DocField",
"fieldname": "friday",
"fieldtype": "Check",
"label": "Friday"
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"doctype": "DocField",
"fieldname": "saturday",
"fieldtype": "Check",
"label": "Saturday"
},
{
"depends_on": "eval:doc.repeat_this_event && doc.repeat_on===\"Every Day\"",
"doctype": "DocField",
"fieldname": "sunday",
"fieldtype": "Check",
"label": "Sunday"
},
{
"doctype": "DocField",
"fieldname": "section_break_6",
"fieldtype": "Section Break"
},
{
"doctype": "DocField",
"fieldname": "description",
"fieldtype": "Text Editor",
"in_list_view": 0,
"label": "Description",
"no_copy": 0,
"oldfieldname": "description",
"oldfieldtype": "Text",
"print_width": "300px",
"search_index": 0,
"width": "300px"
},
{
"doctype": "DocField",
"fieldname": "participants",
"fieldtype": "Section Break",
"label": "Participants",
"oldfieldtype": "Section Break"
},
{
"doctype": "DocField",
"fieldname": "individuals",
"fieldtype": "Column Break",
"label": "Individuals",
"oldfieldtype": "Column Break",
"print_width": "50%",
"width": "50%"
},
{
"doctype": "DocField",
"fieldname": "event_individuals",
"fieldtype": "Table",
"label": "Event Individuals",
"no_copy": 0,
"oldfieldname": "event_individuals",
"oldfieldtype": "Table",
"options": "Event User",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "groups",
"fieldtype": "Column Break",
"label": "Groups",
"oldfieldtype": "Column Break",
"print_width": "50%",
"width": "50%"
},
{
"doctype": "DocField",
"fieldname": "event_roles",
"fieldtype": "Table",
"label": "Event Roles",
"no_copy": 0,
"oldfieldname": "event_roles",
"oldfieldtype": "Table",
"options": "Event Role",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "ref_type",
"fieldtype": "Data",
"hidden": 0,
"label": "Ref Type",
"no_copy": 0,
"oldfieldname": "ref_type",
"oldfieldtype": "Data",
"read_only": 1,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "ref_name",
"fieldtype": "Data",
"hidden": 0,
"label": "Ref Name",
"no_copy": 0,
"oldfieldname": "ref_name",
"oldfieldtype": "Data",
"read_only": 1,
"search_index": 0
},
{
"delete": 0,
"doctype": "DocPerm",
"role": "All"
},
{
"delete": 1,
"doctype": "DocPerm",
"role": "System Manager"
}
]

View file

@ -3,57 +3,33 @@
"""Use blog post test to test permission restriction logic"""
test_records = [
[{
"doctype": "Event",
"subject":"_Test Event 1",
"starts_on": "2014-01-01",
"event_type": "Public",
}],
[{
"doctype": "Event",
"starts_on": "2014-01-01",
"subject":"_Test Event 2",
"event_type": "Private",
}],
[{
"doctype": "Event",
"starts_on": "2014-01-01",
"subject":"_Test Event 3",
"event_type": "Private",
}, {
"doctype": "Event User",
"parentfield": "event_individuals",
"person": "test1@example.com"
}],
]
import frappe
import frappe.defaults
import unittest
test_records = frappe.get_test_records('Event')
class TestEvent(unittest.TestCase):
# def setUp(self):
# user = frappe.bean("User", "test1@example.com")
# user.get_controller().add_roles("Website Manager")
# user = frappe.get_doc("User", "test1@example.com")
# user.add_roles("Website Manager")
def tearDown(self):
frappe.set_user("Administrator")
def test_allowed_public(self):
frappe.set_user("test1@example.com")
doc = frappe.doc("Event", frappe.db.get_value("Event", {"subject":"_Test Event 1"}))
doc = frappe.get_doc("Event", frappe.db.get_value("Event", {"subject":"_Test Event 1"}))
self.assertTrue(frappe.has_permission("Event", refdoc=doc))
def test_not_allowed_private(self):
frappe.set_user("test1@example.com")
doc = frappe.doc("Event", frappe.db.get_value("Event", {"subject":"_Test Event 2"}))
doc = frappe.get_doc("Event", frappe.db.get_value("Event", {"subject":"_Test Event 2"}))
self.assertFalse(frappe.has_permission("Event", refdoc=doc))
def test_allowed_private_if_in_event_user(self):
frappe.set_user("test1@example.com")
doc = frappe.doc("Event", frappe.db.get_value("Event", {"subject":"_Test Event 3"}))
doc = frappe.get_doc("Event", frappe.db.get_value("Event", {"subject":"_Test Event 3"}))
self.assertTrue(frappe.has_permission("Event", refdoc=doc))
def test_event_list(self):
@ -63,5 +39,4 @@ class TestEvent(unittest.TestCase):
subjects = [r.subject for r in res]
self.assertTrue("_Test Event 1" in subjects)
self.assertTrue("_Test Event 3" in subjects)
self.assertFalse("_Test Event 2" in subjects)
self.assertFalse("_Test Event 2" in subjects)

View file

@ -0,0 +1,23 @@
[
{
"doctype": "Event",
"subject":"_Test Event 1",
"starts_on": "2014-01-01",
"event_type": "Public"
},
{
"doctype": "Event",
"starts_on": "2014-01-01",
"subject":"_Test Event 2",
"event_type": "Private"
},
{
"doctype": "Event",
"starts_on": "2014-01-01",
"subject":"_Test Event 3",
"event_type": "Private",
"event_individuals": [{
"person": "test1@example.com"
}]
}
]

View file

@ -0,0 +1,27 @@
{
"autoname": "__EVR.#####",
"creation": "2013-02-22 01:27:33.000000",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "role",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Role",
"oldfieldname": "role",
"oldfieldtype": "Link",
"options": "Role",
"permlevel": 0,
"print_width": "240px",
"width": "240px"
}
],
"idx": 1,
"istable": 1,
"modified": "2013-12-20 19:23:12.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Event Role",
"owner": "Administrator"
}

View file

@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
from frappe.model.document import Document
class EventRole(Document):
pass

View file

@ -1,40 +0,0 @@
[
{
"creation": "2013-02-22 01:27:33",
"docstatus": 0,
"modified": "2013-12-20 19:23:12",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"autoname": "__EVR.#####",
"doctype": "DocType",
"istable": 1,
"module": "Core",
"name": "__common__"
},
{
"doctype": "DocField",
"fieldname": "role",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Role",
"name": "__common__",
"oldfieldname": "role",
"oldfieldtype": "Link",
"options": "Role",
"parent": "Event Role",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0,
"print_width": "240px",
"width": "240px"
},
{
"doctype": "DocType",
"name": "Event Role"
},
{
"doctype": "DocField"
}
]

View file

@ -0,0 +1,28 @@
{
"autoname": "EVP.#####",
"creation": "2013-02-22 01:27:33.000000",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "person",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Person",
"oldfieldname": "person",
"oldfieldtype": "Select",
"options": "link:User",
"permlevel": 0,
"print_width": "240px",
"search_index": 1,
"width": "240px"
}
],
"idx": 1,
"istable": 1,
"modified": "2013-12-20 19:23:14.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Event User",
"owner": "Administrator"
}

View file

@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
from frappe.model.document import Document
class EventUser(Document):
pass

View file

@ -1,41 +0,0 @@
[
{
"creation": "2013-02-22 01:27:33",
"docstatus": 0,
"modified": "2013-12-20 19:23:14",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"autoname": "EVP.#####",
"doctype": "DocType",
"istable": 1,
"module": "Core",
"name": "__common__"
},
{
"doctype": "DocField",
"fieldname": "person",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Person",
"name": "__common__",
"oldfieldname": "person",
"oldfieldtype": "Select",
"options": "link:User",
"parent": "Event User",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0,
"print_width": "240px",
"search_index": 1,
"width": "240px"
},
{
"doctype": "DocType",
"name": "Event User"
},
{
"doctype": "DocField"
}
]

View file

@ -0,0 +1,255 @@
{
"_last_update": null,
"_user_tags": null,
"allow_attach": null,
"allow_copy": null,
"allow_email": null,
"allow_import": null,
"allow_print": null,
"allow_rename": null,
"allow_trash": null,
"autoname": "File.######",
"change_log": null,
"client_script": null,
"client_script_core": null,
"client_string": null,
"colour": null,
"creation": "2012-12-12 11:19:22",
"custom": null,
"default_print_format": null,
"description": null,
"docstatus": 0,
"doctype": "DocType",
"document_type": null,
"dt_template": null,
"fields": [
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "file_name",
"fieldtype": "Data",
"hidden": null,
"ignore_restrictions": null,
"in_filter": null,
"in_list_view": 1,
"label": "File Name",
"no_column": null,
"no_copy": null,
"oldfieldname": "file_name",
"oldfieldtype": "Data",
"options": null,
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": 1,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "file_url",
"fieldtype": "Data",
"hidden": null,
"ignore_restrictions": null,
"in_filter": null,
"in_list_view": 1,
"label": "File URL",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": null,
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": 1,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "attached_to_doctype",
"fieldtype": "Link",
"hidden": null,
"ignore_restrictions": null,
"in_filter": null,
"in_list_view": 1,
"label": "Attached To DocType",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": "DocType",
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": 1,
"report_hide": null,
"reqd": null,
"search_index": 1,
"set_only_once": null,
"trigger": null,
"width": null
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "attached_to_name",
"fieldtype": "Data",
"hidden": null,
"ignore_restrictions": null,
"in_filter": null,
"in_list_view": 1,
"label": "Attached To Name",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": null,
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": 1,
"report_hide": null,
"reqd": null,
"search_index": 1,
"set_only_once": null,
"trigger": null,
"width": null
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "file_size",
"fieldtype": "Int",
"hidden": null,
"ignore_restrictions": null,
"in_filter": null,
"in_list_view": 1,
"label": "File Size",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": null,
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": 1,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "content_hash",
"fieldtype": "Data",
"hidden": null,
"ignore_restrictions": null,
"in_filter": null,
"in_list_view": null,
"label": "Content Hash",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": null,
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": null,
"search_index": 1,
"set_only_once": null,
"trigger": null,
"width": null
}
],
"hide_heading": null,
"hide_toolbar": null,
"icon": "icon-file",
"idx": 1,
"in_create": null,
"in_dialog": null,
"is_submittable": null,
"is_transaction_doc": null,
"issingle": null,
"istable": null,
"max_attachments": null,
"menu_index": null,
"modified": "2014-04-07 17:01:13.295614",
"modified_by": "Administrator",
"module": "Core",
"name": "File Data",
"name_case": null,
"owner": "Administrator",
"parent": null,
"parent_node": null,
"parentfield": null,
"parenttype": null,
"permissions": [
{
"amend": null,
"cancel": 0,
"create": null,
"delete": 1,
"email": 1,
"export": null,
"import": null,
"match": null,
"permlevel": 0,
"print": 1,
"read": 1,
"report": null,
"restrict": null,
"restricted": null,
"role": "System Manager",
"submit": null,
"write": 1
}
],
"plugin": null,
"print_outline": null,
"read_only": 0,
"read_only_onload": null,
"search_fields": null,
"section_style": null,
"server_code": null,
"server_code_compiled": null,
"server_code_core": null,
"server_code_error": null,
"show_in_menu": null,
"smallicon": null,
"subject": null,
"tag_fields": null,
"title_field": null,
"use_template": null,
"version": null
}

View file

@ -10,34 +10,33 @@ naming for same name files: file.gif, file-1.gif, file-2.gif etc
import frappe, frappe.utils, os
from frappe import conf
from frappe.model.document import Document
from frappe.utils.file_manager import delete_file_data_content
class DocType():
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
class FileData(Document):
def before_insert(self):
frappe.local.rollback_observers.append(self)
def on_update(self):
# check duplicate assignement
n_records = frappe.db.sql("""select name from `tabFile Data`
where file_name=%s
where content_hash=%s
and name!=%s
and attached_to_doctype=%s
and attached_to_name=%s""", (self.doc.file_name, self.doc.name, self.doc.attached_to_doctype,
self.doc.attached_to_name))
and attached_to_name=%s""", (self.content_hash, self.name, self.attached_to_doctype,
self.attached_to_name))
if len(n_records) > 0:
self.doc.duplicate_entry = n_records[0][0]
self.duplicate_entry = n_records[0][0]
frappe.msgprint(frappe._("Same file has already been attached to the record"))
frappe.db.rollback()
raise frappe.DuplicateEntryError
def on_trash(self):
if self.doc.attached_to_name:
if self.attached_to_name:
# check persmission
try:
if not self.bean.ignore_permissions and \
not frappe.has_permission(self.doc.attached_to_doctype, "write", self.doc.attached_to_name):
if not getattr(self, 'ignore_permissions', False) and \
not frappe.has_permission(self.attached_to_doctype, "write", self.attached_to_name):
frappe.msgprint(frappe._("No permission to write / remove."), raise_exception=True)
@ -45,14 +44,9 @@ class DocType():
pass
# if file not attached to any other record, delete it
if self.doc.file_name and not frappe.db.count("File Data",
{"file_name": self.doc.file_name, "name": ["!=", self.doc.name]}):
if self.doc.file_name.startswith("files/"):
path = frappe.utils.get_site_path("public", self.doc.file_name)
else:
path = frappe.utils.get_site_path("public", "files", self.doc.file_name)
if os.path.exists(path):
os.remove(path)
if self.file_name and not frappe.db.count("File Data",
{"content_hash": self.content_hash, "name": ["!=", self.name]}):
delete_file_data_content(self)
def on_rollback(self):
self.on_trash()
self.on_trash()

View file

@ -1,87 +0,0 @@
[
{
"creation": "2012-12-12 11:19:22",
"docstatus": 0,
"modified": "2014-01-20 17:48:46",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"autoname": "File.######",
"doctype": "DocType",
"icon": "icon-file",
"module": "Core",
"name": "__common__",
"read_only": 0
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "File Data",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0,
"read_only": 1
},
{
"cancel": 1,
"delete": 1,
"doctype": "DocPerm",
"email": 1,
"name": "__common__",
"parent": "File Data",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"print": 1,
"read": 1,
"role": "System Manager",
"write": 1
},
{
"doctype": "DocType",
"name": "File Data"
},
{
"doctype": "DocField",
"fieldname": "file_name",
"fieldtype": "Data",
"label": "File Name",
"oldfieldname": "file_name",
"oldfieldtype": "Data"
},
{
"doctype": "DocField",
"fieldname": "file_url",
"fieldtype": "Data",
"in_list_view": 1,
"label": "File URL"
},
{
"doctype": "DocField",
"fieldname": "attached_to_doctype",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Attached To DocType",
"options": "DocType",
"search_index": 1
},
{
"doctype": "DocField",
"fieldname": "attached_to_name",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Attached To Name",
"search_index": 1
},
{
"doctype": "DocField",
"fieldname": "file_size",
"fieldtype": "Int",
"in_list_view": 1,
"label": "File Size"
},
{
"doctype": "DocPerm"
}
]

View file

@ -0,0 +1,80 @@
{
"allow_attach": 1,
"autoname": "field:letter_head_name",
"creation": "2012-11-22 17:45:46.000000",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "letter_head_name",
"fieldtype": "Data",
"in_filter": 0,
"label": "Letter Head Name",
"oldfieldname": "letter_head_name",
"oldfieldtype": "Data",
"permlevel": 0,
"reqd": 1
},
{
"depends_on": "letter_head_name",
"fieldname": "disabled",
"fieldtype": "Check",
"label": "Disabled",
"oldfieldname": "disabled",
"oldfieldtype": "Check",
"permlevel": 0
},
{
"depends_on": "letter_head_name",
"description": "Check this to make this the default letter head in all prints",
"fieldname": "is_default",
"fieldtype": "Check",
"label": "Is Default",
"oldfieldname": "is_default",
"oldfieldtype": "Check",
"permlevel": 0
},
{
"depends_on": "letter_head_name",
"description": "Letter Head in HTML",
"fieldname": "content",
"fieldtype": "Text Editor",
"label": "Content",
"oldfieldname": "content",
"oldfieldtype": "Text Editor",
"permlevel": 0
}
],
"icon": "icon-font",
"idx": 1,
"max_attachments": 3,
"modified": "2014-01-20 17:48:56.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Letter Head",
"owner": "Administrator",
"permissions": [
{
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"submit": 0,
"write": 1
},
{
"delete": 0,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "All"
}
]
}

View file

@ -5,10 +5,9 @@ from __future__ import unicode_literals
import frappe
class DocType:
def __init__(self, doc, doclist=[]):
self.doc = doc
self.doclist = doclist
from frappe.model.document import Document
class LetterHead(Document):
def validate(self):
self.set_as_default()
@ -18,13 +17,13 @@ class DocType:
def set_as_default(self):
from frappe.utils import set_default
if not self.doc.is_default:
if not self.is_default:
if not frappe.db.sql("""select count(*) from `tabLetter Head` where ifnull(is_default,0)=1"""):
self.doc.is_default = 1
if self.doc.is_default:
self.is_default = 1
if self.is_default:
frappe.db.sql("update `tabLetter Head` set is_default=0 where name != %s",
self.doc.name)
set_default('letter_head', self.doc.name)
self.name)
set_default('letter_head', self.name)
# update control panel - so it loads new letter directly
frappe.db.set_value('Control Panel', None, 'letter_head', self.doc.content)
frappe.db.set_default("letter_head", self.content)

View file

@ -1,95 +0,0 @@
[
{
"creation": "2012-11-22 17:45:46",
"docstatus": 0,
"modified": "2014-01-20 17:48:56",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_attach": 1,
"autoname": "field:letter_head_name",
"doctype": "DocType",
"icon": "icon-font",
"max_attachments": 3,
"module": "Core",
"name": "__common__"
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "Letter Head",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"doctype": "DocPerm",
"email": 1,
"name": "__common__",
"parent": "Letter Head",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1
},
{
"doctype": "DocType",
"name": "Letter Head"
},
{
"doctype": "DocField",
"fieldname": "letter_head_name",
"fieldtype": "Data",
"in_filter": 0,
"label": "Letter Head Name",
"oldfieldname": "letter_head_name",
"oldfieldtype": "Data",
"reqd": 1
},
{
"depends_on": "letter_head_name",
"doctype": "DocField",
"fieldname": "disabled",
"fieldtype": "Check",
"label": "Disabled",
"oldfieldname": "disabled",
"oldfieldtype": "Check"
},
{
"depends_on": "letter_head_name",
"description": "Check this to make this the default letter head in all prints",
"doctype": "DocField",
"fieldname": "is_default",
"fieldtype": "Check",
"label": "Is Default",
"oldfieldname": "is_default",
"oldfieldtype": "Check"
},
{
"depends_on": "letter_head_name",
"description": "Letter Head in HTML",
"doctype": "DocField",
"fieldname": "content",
"fieldtype": "Text Editor",
"label": "Content",
"oldfieldname": "content",
"oldfieldtype": "Text Editor"
},
{
"cancel": 0,
"create": 1,
"delete": 1,
"doctype": "DocPerm",
"role": "System Manager",
"submit": 0,
"write": 1
},
{
"delete": 0,
"doctype": "DocPerm",
"role": "All"
}
]

View file

@ -1,4 +1,6 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
test_records = []
import frappe
test_records = frappe.get_test_records('Letter Head')

View file

@ -0,0 +1 @@
[]

View file

@ -0,0 +1,162 @@
{
"_last_update": null,
"_user_tags": null,
"allow_attach": null,
"allow_copy": null,
"allow_email": null,
"allow_import": null,
"allow_print": null,
"allow_rename": 1,
"allow_trash": null,
"autoname": "field:module_name",
"change_log": null,
"client_script": null,
"client_script_core": null,
"client_string": null,
"colour": null,
"creation": "2013-01-10 16:34:03",
"custom": null,
"default_print_format": null,
"description": null,
"docstatus": 0,
"doctype": "DocType",
"document_type": null,
"dt_template": null,
"fields": [
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "module_name",
"fieldtype": "Data",
"hidden": null,
"ignore_restrictions": null,
"in_filter": null,
"in_list_view": 1,
"label": "Module Name",
"no_column": null,
"no_copy": null,
"oldfieldname": "module_name",
"oldfieldtype": "Data",
"options": null,
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": null,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
},
{
"allow_on_submit": null,
"default": null,
"depends_on": null,
"description": null,
"fieldname": "app_name",
"fieldtype": "Data",
"hidden": null,
"ignore_restrictions": null,
"in_filter": null,
"in_list_view": 1,
"label": "App Name",
"no_column": null,
"no_copy": null,
"oldfieldname": null,
"oldfieldtype": null,
"options": null,
"permlevel": 0,
"print_hide": null,
"print_width": null,
"read_only": null,
"report_hide": null,
"reqd": 1,
"search_index": null,
"set_only_once": null,
"trigger": null,
"width": null
}
],
"hide_heading": null,
"hide_toolbar": null,
"icon": "icon-sitemap",
"idx": 1,
"in_create": null,
"in_dialog": null,
"is_submittable": null,
"is_transaction_doc": null,
"issingle": null,
"istable": null,
"max_attachments": null,
"menu_index": null,
"modified": "2014-04-07 13:00:27.894115",
"modified_by": "Administrator",
"module": "Core",
"name": "Module Def",
"name_case": null,
"owner": "Administrator",
"parent": null,
"parent_node": null,
"parentfield": null,
"parenttype": null,
"permissions": [
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": null,
"import": null,
"match": null,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"restrict": null,
"restricted": null,
"role": "Administrator",
"submit": 0,
"write": 1
},
{
"amend": null,
"cancel": null,
"create": 1,
"delete": 1,
"email": null,
"export": null,
"import": null,
"match": null,
"permlevel": 0,
"print": null,
"read": 1,
"report": null,
"restrict": null,
"restricted": null,
"role": "System Manager",
"submit": null,
"write": 1
}
],
"plugin": null,
"print_outline": null,
"read_only": null,
"read_only_onload": null,
"search_fields": null,
"section_style": null,
"server_code": null,
"server_code_compiled": null,
"server_code_core": null,
"server_code_error": null,
"show_in_menu": null,
"smallicon": null,
"subject": null,
"tag_fields": null,
"title_field": null,
"use_template": null,
"version": null
}

View file

@ -2,8 +2,32 @@
# MIT License. See license.txt
from __future__ import unicode_literals
import frappe
import frappe, os
from frappe.model.document import Document
class ModuleDef(Document):
def validate(self):
modules = None
if not frappe.local.module_app.get(self.name):
with open(frappe.get_app_path(self.app_name, "modules.txt"), "r") as f:
content = f.read()
if not frappe.scrub(self.name) in content.splitlines():
modules = filter(None, content.splitlines())
modules.append(frappe.scrub(self.name))
if modules:
with open(frappe.get_app_path(self.app_name, "modules.txt"), "w") as f:
f.write("\n".join(modules))
frappe.clear_cache()
frappe.setup_module_map()
module_path = frappe.get_app_path(self.app_name, self.name)
if not os.path.exists(module_path):
os.mkdir(module_path)
with open(os.path.join(module_path, "__init__.py"), "w") as f:
f.write("")
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl

View file

@ -1,63 +0,0 @@
[
{
"creation": "2013-01-10 16:34:03",
"docstatus": 0,
"modified": "2014-02-18 15:32:49",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_rename": 1,
"autoname": "field:module_name",
"doctype": "DocType",
"icon": "icon-sitemap",
"module": "Core",
"name": "__common__"
},
{
"doctype": "DocField",
"fieldname": "module_name",
"fieldtype": "Data",
"label": "Module Name",
"name": "__common__",
"oldfieldname": "module_name",
"oldfieldtype": "Data",
"parent": "Module Def",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"create": 1,
"delete": 1,
"doctype": "DocPerm",
"name": "__common__",
"parent": "Module Def",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"read": 1,
"write": 1
},
{
"doctype": "DocType",
"name": "Module Def"
},
{
"doctype": "DocField"
},
{
"amend": 0,
"cancel": 0,
"doctype": "DocPerm",
"email": 1,
"print": 1,
"report": 1,
"role": "Administrator",
"submit": 0
},
{
"doctype": "DocPerm",
"role": "System Manager"
}
]

View file

@ -0,0 +1,33 @@
{
"creation": "2013-11-18 05:31:03.000000",
"docstatus": 0,
"doctype": "DocType",
"document_type": "Other",
"fields": [
{
"fieldname": "for_doctype",
"fieldtype": "Data",
"label": "For DocType",
"permlevel": 0,
"search_index": 1
},
{
"fieldname": "count",
"fieldtype": "Int",
"label": "Count",
"permlevel": 0
},
{
"fieldname": "open_count",
"fieldtype": "Int",
"label": "Open Count",
"permlevel": 0
}
],
"idx": 1,
"modified": "2013-12-20 19:24:14.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Notification Count",
"owner": "Administrator"
}

View file

@ -6,12 +6,15 @@
from __future__ import unicode_literals
import frappe
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
from frappe.model.document import Document
class NotificationCount(Document):
pass
@frappe.whitelist()
def get_notifications():
if frappe.flags.in_install_app:
return
config = get_notification_config()
can_read = frappe.user.get_can_read()
open_count_doctype = {}
@ -31,7 +34,7 @@ def get_notifications():
result = frappe.get_list(d, fields=["count(*)"],
filters=[[d, key, "=", condition[key]]], as_list=True, limit_page_length=1)[0][0]
frappe.doc({"doctype":"Notification Count", "for_doctype":d,
frappe.get_doc({"doctype":"Notification Count", "for_doctype":d,
"open_count":result}).insert()
open_count_doctype[d] = result
@ -41,7 +44,7 @@ def get_notifications():
open_count_module[m] = notification_count[m]
else:
open_count_module[m] = frappe.get_attr(config.for_module[m])()
frappe.doc({"doctype":"Notification Count", "for_doctype":m,
frappe.get_doc({"doctype":"Notification Count", "for_doctype":m,
"open_count":open_count_module[m]}).insert()
return {
@ -56,12 +59,12 @@ def delete_notification_count_for(doctype):
def delete_event_notification_count():
delete_notification_count_for("Event")
def clear_doctype_notifications(bean, method=None):
def clear_doctype_notifications(doc, method=None):
if frappe.flags.in_import:
return
config = get_notification_config()
doctype = bean.doc.doctype
doctype = doc.doctype
if doctype in config.for_doctype:
delete_notification_count_for(doctype)

View file

@ -1,46 +0,0 @@
[
{
"creation": "2013-11-18 05:31:03",
"docstatus": 0,
"modified": "2013-12-20 19:24:14",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doctype": "DocType",
"document_type": "Other",
"module": "Core",
"name": "__common__"
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "Notification Count",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"doctype": "DocType",
"name": "Notification Count"
},
{
"doctype": "DocField",
"fieldname": "for_doctype",
"fieldtype": "Data",
"label": "For DocType",
"search_index": 1
},
{
"doctype": "DocField",
"fieldname": "count",
"fieldtype": "Int",
"label": "Count"
},
{
"doctype": "DocField",
"fieldname": "open_count",
"fieldtype": "Int",
"label": "Open Count"
}
]

View file

@ -0,0 +1,88 @@
{
"allow_copy": 1,
"creation": "2014-03-03 19:48:01.000000",
"description": "Email Settings for Outgoing and Incoming Emails.",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"description": "SMTP Server (e.g. smtp.gmail.com)",
"fieldname": "mail_server",
"fieldtype": "Data",
"label": "Outgoing Mail Server",
"permlevel": 0
},
{
"description": "<a href=\"https://en.wikipedia.org/wiki/Transport_Layer_Security\" target=\"_blank\">[?]</a>",
"fieldname": "use_ssl",
"fieldtype": "Check",
"label": "Use TLS",
"permlevel": 0
},
{
"description": "If non standard port (e.g. 587)",
"fieldname": "mail_port",
"fieldtype": "Int",
"label": "Port",
"permlevel": 0
},
{
"fieldname": "cb0",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"description": "Set Login and Password if authentication is required.",
"fieldname": "mail_login",
"fieldtype": "Data",
"label": "Login Id",
"permlevel": 0
},
{
"description": "Check this if you want to send emails as this id only (in case of restriction by your email provider).",
"fieldname": "always_use_login_id_as_sender",
"fieldtype": "Check",
"label": "Always use above Login Id as sender",
"permlevel": 0
},
{
"fieldname": "mail_password",
"fieldtype": "Password",
"label": "Mail Password",
"permlevel": 0
},
{
"description": "System generated mails will be sent from this email id.",
"fieldname": "auto_email_id",
"fieldtype": "Data",
"label": "Auto Email Id",
"permlevel": 0
},
{
"default": "1",
"description": "If checked, an email with an attached HTML format will be added to part of the EMail body as well as attachment. To only send as attachment, uncheck this.",
"fieldname": "send_print_in_body_and_attachment",
"fieldtype": "Check",
"label": "Send Print in Body and Attachment",
"permlevel": 0
}
],
"icon": "icon-cog",
"idx": 1,
"in_create": 1,
"issingle": 1,
"modified": "2014-03-03 20:20:09.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Outgoing Email Settings",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"permlevel": 0,
"read": 1,
"role": "System Manager",
"write": 1
}
]
}

View file

@ -6,20 +6,19 @@
from __future__ import unicode_literals
import frappe
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
from frappe.model.document import Document
class OutgoingEmailSettings(Document):
def validate(self):
self.doc.encode()
if self.doc.mail_server:
if self.mail_server:
from frappe.utils import cint
from frappe.utils.email_lib.smtp import SMTPServer
smtpserver = SMTPServer(login = self.doc.mail_login,
password = self.doc.mail_password,
server = self.doc.mail_server,
port = cint(self.doc.mail_port),
use_ssl = self.doc.use_ssl
smtpserver = SMTPServer(login = self.mail_login,
password = self.mail_password,
server = self.mail_server,
port = cint(self.mail_port),
use_ssl = self.use_ssl
)
# exceptions are handled in session connect

View file

@ -1,107 +0,0 @@
[
{
"creation": "2014-03-03 19:48:01",
"docstatus": 0,
"modified": "2014-03-03 20:20:09",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_copy": 1,
"description": "Email Settings for Outgoing and Incoming Emails.",
"doctype": "DocType",
"icon": "icon-cog",
"in_create": 1,
"issingle": 1,
"module": "Core",
"name": "__common__"
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "Outgoing Email Settings",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"create": 1,
"doctype": "DocPerm",
"name": "__common__",
"parent": "Outgoing Email Settings",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"read": 1,
"role": "System Manager",
"write": 1
},
{
"doctype": "DocType",
"name": "Outgoing Email Settings"
},
{
"description": "SMTP Server (e.g. smtp.gmail.com)",
"doctype": "DocField",
"fieldname": "mail_server",
"fieldtype": "Data",
"label": "Outgoing Mail Server"
},
{
"description": "<a href=\"https://en.wikipedia.org/wiki/Transport_Layer_Security\" target=\"_blank\">[?]</a>",
"doctype": "DocField",
"fieldname": "use_ssl",
"fieldtype": "Check",
"label": "Use TLS"
},
{
"description": "If non standard port (e.g. 587)",
"doctype": "DocField",
"fieldname": "mail_port",
"fieldtype": "Int",
"label": "Port"
},
{
"doctype": "DocField",
"fieldname": "cb0",
"fieldtype": "Column Break"
},
{
"description": "Set Login and Password if authentication is required.",
"doctype": "DocField",
"fieldname": "mail_login",
"fieldtype": "Data",
"label": "Login Id"
},
{
"description": "Check this if you want to send emails as this id only (in case of restriction by your email provider).",
"doctype": "DocField",
"fieldname": "always_use_login_id_as_sender",
"fieldtype": "Check",
"label": "Always use above Login Id as sender"
},
{
"doctype": "DocField",
"fieldname": "mail_password",
"fieldtype": "Password",
"label": "Mail Password"
},
{
"description": "System generated mails will be sent from this email id.",
"doctype": "DocField",
"fieldname": "auto_email_id",
"fieldtype": "Data",
"label": "Auto Email Id"
},
{
"default": "1",
"description": "If checked, an email with an attached HTML format will be added to part of the EMail body as well as attachment. To only send as attachment, uncheck this.",
"doctype": "DocField",
"fieldname": "send_print_in_body_and_attachment",
"fieldtype": "Check",
"label": "Send Print in Body and Attachment"
},
{
"doctype": "DocPerm"
}
]

View file

@ -0,0 +1,113 @@
{
"allow_copy": 0,
"allow_rename": 1,
"autoname": "field:page_name",
"creation": "2012-12-20 17:16:49.000000",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "page_html",
"fieldtype": "Section Break",
"label": "Page HTML",
"oldfieldtype": "Section Break",
"permlevel": 0
},
{
"fieldname": "page_name",
"fieldtype": "Data",
"label": "Page Name",
"oldfieldname": "page_name",
"oldfieldtype": "Data",
"permlevel": 0,
"reqd": 1
},
{
"fieldname": "title",
"fieldtype": "Data",
"label": "Title",
"permlevel": 0
},
{
"fieldname": "icon",
"fieldtype": "Data",
"label": "icon",
"permlevel": 0
},
{
"fieldname": "column_break0",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"fieldname": "module",
"fieldtype": "Link",
"label": "Module",
"oldfieldname": "module",
"oldfieldtype": "Select",
"options": "Module Def",
"permlevel": 0,
"reqd": 1
},
{
"fieldname": "standard",
"fieldtype": "Select",
"label": "Standard",
"oldfieldname": "standard",
"oldfieldtype": "Select",
"options": "\nYes\nNo",
"permlevel": 0,
"reqd": 1,
"search_index": 1
},
{
"fieldname": "section_break0",
"fieldtype": "Section Break",
"permlevel": 0
},
{
"fieldname": "roles",
"fieldtype": "Table",
"hidden": 0,
"label": "Roles",
"oldfieldname": "roles",
"oldfieldtype": "Table",
"options": "Page Role",
"permlevel": 0,
"reqd": 0,
"search_index": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-file",
"idx": 1,
"issingle": 0,
"istable": 0,
"modified": "2013-12-30 13:48:02.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Page",
"owner": "Administrator",
"permissions": [
{
"cancel": 0,
"create": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"role": "Administrator",
"submit": 0,
"write": 1
},
{
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"role": "All"
}
],
"read_only": 0
}

View file

@ -3,11 +3,9 @@
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d,dl
class Page(Document):
def autoname(self):
"""
Creates a url friendly name for this page.
@ -15,17 +13,17 @@ class DocType:
it will add name-1, name-2 etc.
"""
from frappe.utils import cint
if (self.doc.name and self.doc.name.startswith('New Page')) or not self.doc.name:
self.doc.name = self.doc.page_name.lower().replace('"','').replace("'",'').\
if (self.name and self.name.startswith('New Page')) or not self.name:
self.name = self.page_name.lower().replace('"','').replace("'",'').\
replace(' ', '-')[:20]
if frappe.db.exists('Page',self.doc.name):
if frappe.db.exists('Page',self.name):
cnt = frappe.db.sql("""select name from tabPage
where name like "%s-%%" order by name desc limit 1""" % self.doc.name)
where name like "%s-%%" order by name desc limit 1""" % self.name)
if cnt:
cnt = cint(cnt[0][0].split('-')[-1]) + 1
else:
cnt = 1
self.doc.name += '-' + str(cnt)
self.name += '-' + str(cnt)
# export
def on_update(self):
@ -35,16 +33,16 @@ class DocType:
"""
from frappe import conf
from frappe.core.doctype.doctype.doctype import make_module_and_roles
make_module_and_roles(self.doclist, "Page Role")
make_module_and_roles(self, "roles")
if not frappe.flags.in_import and getattr(conf,'developer_mode', 0) and self.doc.standard=='Yes':
if not frappe.flags.in_import and getattr(conf,'developer_mode', 0) and self.standard=='Yes':
from frappe.modules.export_file import export_to_files
from frappe.modules import get_module_path, scrub
import os
export_to_files(record_list=[['Page', self.doc.name]])
export_to_files(record_list=[['Page', self.name]])
# write files
path = os.path.join(get_module_path(self.doc.module), 'page', scrub(self.doc.name), scrub(self.doc.name))
path = os.path.join(get_module_path(self.module), 'page', scrub(self.name), scrub(self.name))
# js
if not os.path.exists(path + '.js'):
@ -55,35 +53,39 @@ class DocType:
title: '%s',
single_column: true
});
}""" % (self.doc.name, self.doc.title))
}""" % (self.name, self.title))
def get_from_files(self):
"""
Loads page info from files in module
"""
def as_dict(self):
d = super(Page, self).as_dict()
for key in ("script", "style", "content"):
d[key] = self.get(key)
return d
def load_assets(self):
from frappe.modules import get_module_path, scrub
import os
path = os.path.join(get_module_path(self.doc.module), 'page', scrub(self.doc.name))
path = os.path.join(get_module_path(self.module), 'page', scrub(self.name))
# script
fpath = os.path.join(path, scrub(self.doc.name) + '.js')
fpath = os.path.join(path, scrub(self.name) + '.js')
if os.path.exists(fpath):
with open(fpath, 'r') as f:
self.doc.script = f.read()
self.script = f.read()
# css
fpath = os.path.join(path, scrub(self.doc.name) + '.css')
fpath = os.path.join(path, scrub(self.name) + '.css')
if os.path.exists(fpath):
with open(fpath, 'r') as f:
self.doc.style = f.read()
self.style = f.read()
# html
fpath = os.path.join(path, scrub(self.doc.name) + '.html')
fpath = os.path.join(path, scrub(self.name) + '.html')
if os.path.exists(fpath):
with open(fpath, 'r') as f:
self.doc.content = f.read()
self.content = f.read()
if frappe.lang != 'en':
from frappe.translate import get_lang_js
self.doc.script += get_lang_js("page", self.doc.name)
self.script += get_lang_js("page", self.name)

View file

@ -1,129 +0,0 @@
[
{
"creation": "2012-12-20 17:16:49",
"docstatus": 0,
"modified": "2013-12-30 13:48:02",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_copy": 0,
"allow_rename": 1,
"autoname": "field:page_name",
"doctype": "DocType",
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-file",
"issingle": 0,
"istable": 0,
"module": "Core",
"name": "__common__",
"read_only": 0
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "Page",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"doctype": "DocPerm",
"email": 1,
"name": "__common__",
"parent": "Page",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"print": 1,
"read": 1
},
{
"doctype": "DocType",
"name": "Page"
},
{
"doctype": "DocField",
"fieldname": "page_html",
"fieldtype": "Section Break",
"label": "Page HTML",
"oldfieldtype": "Section Break"
},
{
"doctype": "DocField",
"fieldname": "page_name",
"fieldtype": "Data",
"label": "Page Name",
"oldfieldname": "page_name",
"oldfieldtype": "Data",
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "title",
"fieldtype": "Data",
"label": "Title"
},
{
"doctype": "DocField",
"fieldname": "icon",
"fieldtype": "Data",
"label": "icon"
},
{
"doctype": "DocField",
"fieldname": "column_break0",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"fieldname": "module",
"fieldtype": "Link",
"label": "Module",
"oldfieldname": "module",
"oldfieldtype": "Select",
"options": "Module Def",
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "standard",
"fieldtype": "Select",
"label": "Standard",
"oldfieldname": "standard",
"oldfieldtype": "Select",
"options": "\nYes\nNo",
"reqd": 1,
"search_index": 1
},
{
"doctype": "DocField",
"fieldname": "section_break0",
"fieldtype": "Section Break"
},
{
"doctype": "DocField",
"fieldname": "roles",
"fieldtype": "Table",
"hidden": 0,
"label": "Roles",
"oldfieldname": "roles",
"oldfieldtype": "Table",
"options": "Page Role",
"reqd": 0,
"search_index": 0
},
{
"cancel": 0,
"create": 1,
"doctype": "DocPerm",
"role": "Administrator",
"submit": 0,
"write": 1
},
{
"doctype": "DocPerm",
"role": "All"
}
]

View file

@ -0,0 +1,33 @@
{
"allow_copy": 0,
"autoname": "PR.######",
"creation": "2013-02-22 01:27:34.000000",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "role",
"fieldtype": "Link",
"hidden": 0,
"in_list_view": 1,
"label": "Role",
"oldfieldname": "role",
"oldfieldtype": "Link",
"options": "Role",
"permlevel": 0,
"reqd": 0,
"search_index": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
"issingle": 0,
"istable": 1,
"modified": "2013-12-20 19:23:24.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Page Role",
"owner": "Administrator",
"read_only": 0
}

View file

@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
from frappe.model.document import Document
class PageRole(Document):
pass

View file

@ -1,46 +0,0 @@
[
{
"creation": "2013-02-22 01:27:34",
"docstatus": 0,
"modified": "2013-12-20 19:23:24",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_copy": 0,
"autoname": "PR.######",
"doctype": "DocType",
"hide_heading": 0,
"hide_toolbar": 0,
"issingle": 0,
"istable": 1,
"module": "Core",
"name": "__common__",
"read_only": 0
},
{
"doctype": "DocField",
"fieldname": "role",
"fieldtype": "Link",
"hidden": 0,
"in_list_view": 1,
"label": "Role",
"name": "__common__",
"oldfieldname": "role",
"oldfieldtype": "Link",
"options": "Role",
"parent": "Page Role",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocType",
"name": "Page Role"
},
{
"doctype": "DocField"
}
]

View file

@ -0,0 +1,33 @@
{
"autoname": "PATCHLOG.#####",
"creation": "2013-01-17 11:36:45.000000",
"description": "List of patches executed",
"docstatus": 0,
"doctype": "DocType",
"document_type": "System",
"fields": [
{
"fieldname": "patch",
"fieldtype": "Data",
"label": "Patch",
"permlevel": 0
}
],
"icon": "icon-cog",
"idx": 1,
"modified": "2013-12-20 19:24:15.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Patch Log",
"owner": "Administrator",
"permissions": [
{
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Administrator"
}
]
}

View file

@ -6,6 +6,7 @@
from __future__ import unicode_literals
import frappe
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
from frappe.model.document import Document
class PatchLog(Document):
pass

View file

@ -1,52 +0,0 @@
[
{
"creation": "2013-01-17 11:36:45",
"docstatus": 0,
"modified": "2013-12-20 19:24:15",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"autoname": "PATCHLOG.#####",
"description": "List of patches executed",
"doctype": "DocType",
"document_type": "System",
"icon": "icon-cog",
"module": "Core",
"name": "__common__"
},
{
"doctype": "DocField",
"fieldname": "patch",
"fieldtype": "Data",
"label": "Patch",
"name": "__common__",
"parent": "Patch Log",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"doctype": "DocPerm",
"email": 1,
"name": "__common__",
"parent": "Patch Log",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Administrator"
},
{
"doctype": "DocType",
"name": "Patch Log"
},
{
"doctype": "DocField"
},
{
"doctype": "DocPerm"
}
]

View file

@ -0,0 +1,162 @@
{
"allow_attach": 0,
"allow_copy": 0,
"allow_rename": 0,
"autoname": "Prompt",
"creation": "2013-01-23 19:54:43.000000",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"allow_on_submit": 0,
"fieldname": "module",
"fieldtype": "Select",
"hidden": 0,
"in_filter": 1,
"label": "Module",
"no_copy": 0,
"oldfieldname": "module",
"oldfieldtype": "Select",
"options": "link:Module Def",
"permlevel": 0,
"print_hide": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 1
},
{
"description": "Belongs to",
"fieldname": "doc_type",
"fieldtype": "Select",
"in_filter": 1,
"label": "DocType",
"options": "link:DocType",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"allow_on_submit": 0,
"default": "No",
"fieldname": "standard",
"fieldtype": "Select",
"hidden": 0,
"in_filter": 1,
"label": "Standard",
"no_copy": 1,
"oldfieldname": "standard",
"oldfieldtype": "Select",
"options": "No\nYes",
"permlevel": 1,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 1
},
{
"fieldname": "print_format_type",
"fieldtype": "Select",
"label": "Print Format Type",
"options": "Client\nServer",
"permlevel": 0
},
{
"fieldname": "section_break_6",
"fieldtype": "Section Break",
"permlevel": 0
},
{
"allow_on_submit": 0,
"depends_on": "eval:doc.print_format_type!=\"Server\"",
"fieldname": "html",
"fieldtype": "Code",
"hidden": 0,
"in_filter": 0,
"label": "HTML",
"no_copy": 0,
"oldfieldname": "html",
"oldfieldtype": "Text Editor",
"options": "HTML",
"permlevel": 0,
"print_hide": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
}
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-print",
"idx": 1,
"in_create": 0,
"in_dialog": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2014-01-20 17:49:00.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Print Format",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Administrator",
"submit": 0,
"write": 1
},
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"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": "Administrator",
"submit": 0,
"write": 1
}
],
"read_only": 0,
"read_only_onload": 0
}

View file

@ -1,5 +1,5 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
# MIT License. See license.txt
from __future__ import unicode_literals
import frappe, os
@ -8,36 +8,35 @@ from frappe.modules import get_doc_path
standard_format = "templates/print_formats/standard.html"
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d,dl
from frappe.model.document import Document
class PrintFormat(Document):
def validate(self):
if self.doc.standard=="Yes" and frappe.session.user != "Administrator":
if self.standard=="Yes" and frappe.session.user != "Administrator":
frappe.msgprint("Standard Print Format cannot be updated.", raise_exception=1)
# old_doc_type is required for clearing item cache
self.old_doc_type = frappe.db.get_value('Print Format',
self.doc.name, 'doc_type')
self.name, 'doc_type')
def on_update(self):
if hasattr(self, 'old_doc_type') and self.old_doc_type:
frappe.clear_cache(doctype=self.old_doc_type)
if self.doc.doc_type:
frappe.clear_cache(doctype=self.doc.doc_type)
frappe.clear_cache(doctype=self.old_doc_type)
if self.doc_type:
frappe.clear_cache(doctype=self.doc_type)
self.export_doc()
def export_doc(self):
# export
if self.doc.standard == 'Yes' and (frappe.conf.get('developer_mode') or 0) == 1:
if self.standard == 'Yes' and (frappe.conf.get('developer_mode') or 0) == 1:
from frappe.modules.export_file import export_to_files
export_to_files(record_list=[['Print Format', self.doc.name]],
record_module=self.doc.module)
export_to_files(record_list=[['Print Format', self.name]],
record_module=self.module)
def on_trash(self):
if self.doc.doc_type:
frappe.clear_cache(doctype=self.doc.doc_type)
if self.doc_type:
frappe.clear_cache(doctype=self.doc_type)
def get_args():
if not frappe.form_dict.format:
@ -48,37 +47,34 @@ def get_args():
<p>Parameters doctype, name and format required</p>
<pre>%s</pre>""" % repr(frappe.form_dict)
}
bean = frappe.bean(frappe.form_dict.doctype, frappe.form_dict.name)
doc = frappe.get_doc(frappe.form_dict.doctype, frappe.form_dict.name)
for ptype in ("read", "print"):
if not frappe.has_permission(bean.doc.doctype, ptype, bean.doc):
if not frappe.has_permission(doc.doctype, ptype, doc):
return {
"body": """<h1>Error</h1>
<p>No {ptype} permission</p>""".format(ptype=ptype)
}
return {
"body": get_html(bean.doc, bean.doclist),
"body": get_html(doc),
"css": get_print_style(frappe.form_dict.style),
"comment": frappe.session.user
}
def get_html(doc, doclist, print_format=None):
def get_html(doc, name=None, print_format=None):
from jinja2 import Environment
if isinstance(doc, basestring) and isinstance(doclist, basestring):
bean = frappe.bean(doc, doclist)
doc = bean.doc
doclist = bean.doclist
template = Environment().from_string(get_print_format_name(doc.doctype,
if isinstance(doc, basestring) and isinstance(name, basestring):
doc = frappe.get_doc(doc, name)
template = Environment().from_string(get_print_format_name(doc.doctype,
print_format or frappe.form_dict.format))
doctype = frappe.get_doctype(doc.doctype)
meta = frappe.get_meta(doc.doctype)
args = {
"doc": doc,
"doclist": doclist,
"doctype": doctype,
"meta": meta,
"frappe": frappe,
"utils": frappe.utils
}
@ -88,9 +84,9 @@ def get_html(doc, doclist, print_format=None):
def get_print_format_name(doctype, format_name):
if format_name==standard_format:
return format_name
# server, find template
path = os.path.join(get_doc_path(frappe.db.get_value("DocType", doctype, "module"),
path = os.path.join(get_doc_path(frappe.db.get_value("DocType", doctype, "module"),
"Print Format", format_name), format_name + ".html")
if os.path.exists(path):
with open(path, "r") as pffile:
@ -105,7 +101,7 @@ def get_print_format_name(doctype, format_name):
def get_print_style(style=None):
if not style:
style = frappe.db.get_default("print_style") or "Standard"
path = os.path.join(get_doc_path("Core", "DocType", "Print Format"), "styles",
path = os.path.join(get_doc_path("Core", "DocType", "Print Format"), "styles",
style.lower() + ".css")
if not os.path.exists(path):
if style!="Standard":
@ -115,4 +111,3 @@ def get_print_style(style=None):
else:
with open(path, 'r') as sfile:
return sfile.read()

View file

@ -1,175 +0,0 @@
[
{
"creation": "2013-01-23 19:54:43",
"docstatus": 0,
"modified": "2014-01-20 17:49:00",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_attach": 0,
"allow_copy": 0,
"allow_rename": 0,
"autoname": "Prompt",
"doctype": "DocType",
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-print",
"in_create": 0,
"in_dialog": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"module": "Core",
"name": "__common__",
"read_only": 0,
"read_only_onload": 0
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "Print Format",
"parentfield": "fields",
"parenttype": "DocType"
},
{
"amend": 0,
"cancel": 0,
"doctype": "DocPerm",
"name": "__common__",
"parent": "Print Format",
"parentfield": "permissions",
"parenttype": "DocType",
"read": 1,
"report": 1,
"submit": 0
},
{
"doctype": "DocType",
"name": "Print Format"
},
{
"allow_on_submit": 0,
"doctype": "DocField",
"fieldname": "module",
"fieldtype": "Select",
"hidden": 0,
"in_filter": 1,
"label": "Module",
"no_copy": 0,
"oldfieldname": "module",
"oldfieldtype": "Select",
"options": "link:Module Def",
"permlevel": 0,
"print_hide": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 1
},
{
"description": "Belongs to",
"doctype": "DocField",
"fieldname": "doc_type",
"fieldtype": "Select",
"in_filter": 1,
"label": "DocType",
"options": "link:DocType",
"permlevel": 0,
"reqd": 0,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"permlevel": 0
},
{
"allow_on_submit": 0,
"default": "No",
"doctype": "DocField",
"fieldname": "standard",
"fieldtype": "Select",
"hidden": 0,
"in_filter": 1,
"label": "Standard",
"no_copy": 1,
"oldfieldname": "standard",
"oldfieldtype": "Select",
"options": "No\nYes",
"permlevel": 1,
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 1
},
{
"doctype": "DocField",
"fieldname": "print_format_type",
"fieldtype": "Select",
"label": "Print Format Type",
"options": "Client\nServer",
"permlevel": 0
},
{
"doctype": "DocField",
"fieldname": "section_break_6",
"fieldtype": "Section Break",
"permlevel": 0
},
{
"allow_on_submit": 0,
"depends_on": "eval:doc.print_format_type!=\"Server\"",
"doctype": "DocField",
"fieldname": "html",
"fieldtype": "Code",
"hidden": 0,
"in_filter": 0,
"label": "HTML",
"no_copy": 0,
"oldfieldname": "html",
"oldfieldtype": "Text Editor",
"options": "HTML",
"permlevel": 0,
"print_hide": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0
},
{
"create": 1,
"delete": 1,
"doctype": "DocPerm",
"email": 1,
"permlevel": 0,
"print": 1,
"role": "Administrator",
"write": 1
},
{
"create": 1,
"delete": 1,
"doctype": "DocPerm",
"email": 1,
"permlevel": 0,
"print": 1,
"role": "System Manager",
"write": 1
},
{
"create": 0,
"delete": 0,
"doctype": "DocPerm",
"permlevel": 1,
"role": "System Manager"
},
{
"create": 0,
"delete": 0,
"doctype": "DocPerm",
"permlevel": 1,
"role": "Administrator",
"write": 1
}
]

View file

@ -0,0 +1,120 @@
{
"creation": "2013-01-10 16:34:04.000000",
"description": "Property Setter overrides a standard DocType or Field property",
"docstatus": 0,
"doctype": "DocType",
"fields": [
{
"fieldname": "help",
"fieldtype": "HTML",
"label": "Help",
"options": "<div class=\"alert\">Please don't update it as it can mess up your form. Use the Customize Form View and Custom Fields to set properties!</div>",
"permlevel": 0
},
{
"fieldname": "sb0",
"fieldtype": "Section Break",
"permlevel": 0
},
{
"depends_on": "eval:doc.__islocal",
"fieldname": "doctype_or_field",
"fieldtype": "Select",
"label": "DocType or Field",
"options": "\nDocField\nDocType",
"permlevel": 0,
"reqd": 1
},
{
"description": "New value to be set",
"fieldname": "value",
"fieldtype": "Text",
"label": "Set Value",
"permlevel": 0
},
{
"fieldname": "column_break0",
"fieldtype": "Column Break",
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "doc_type",
"fieldtype": "Link",
"in_filter": 0,
"label": "DocType",
"options": "DocType",
"permlevel": 0,
"reqd": 1,
"search_index": 1
},
{
"depends_on": "eval:doc.doctype_or_field=='DocField'",
"description": "ID (name) of the entity whose property is to be set",
"fieldname": "field_name",
"fieldtype": "Data",
"in_filter": 0,
"label": "Field Name",
"permlevel": 0,
"reqd": 0,
"search_index": 1
},
{
"fieldname": "property",
"fieldtype": "Data",
"in_filter": 0,
"label": "Property",
"permlevel": 0,
"reqd": 1,
"search_index": 1
},
{
"fieldname": "property_type",
"fieldtype": "Data",
"label": "Property Type",
"permlevel": 0
},
{
"fieldname": "default_value",
"fieldtype": "Data",
"label": "Default Value",
"permlevel": 0
}
],
"icon": "icon-glass",
"idx": 1,
"modified": "2014-01-20 17:49:03.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Property Setter",
"owner": "Administrator",
"permissions": [
{
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Administrator",
"submit": 0,
"write": 1
},
{
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"submit": 0,
"write": 1
}
],
"search_fields": "doc_name,property"
}

View file

@ -4,26 +4,26 @@
from __future__ import unicode_literals
import frappe
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
from frappe.model.document import Document
class PropertySetter(Document):
def autoname(self):
self.doc.name = self.doc.doc_type + "-" \
+ (self.doc.field_name and (self.doc.field_name + "-") or "") \
+ self.doc.property
self.name = self.doc_type + "-" \
+ (self.field_name and (self.field_name + "-") or "") \
+ self.property
def validate(self):
"""delete other property setters on this, if this is new"""
if self.doc.fields['__islocal']:
if self.get('__islocal'):
frappe.db.sql("""delete from `tabProperty Setter` where
doctype_or_field = %(doctype_or_field)s
and doc_type = %(doc_type)s
and ifnull(field_name,'') = ifnull(%(field_name)s, '')
and property = %(property)s""", self.doc.fields)
and property = %(property)s""", self.get_valid_dict())
# clear cache
frappe.clear_cache(doctype = self.doc.doc_type)
frappe.clear_cache(doctype = self.doc_type)
def get_property_list(self, dt):
return frappe.db.sql("""select fieldname, label, fieldtype
@ -41,21 +41,21 @@ class DocType:
}
def get_field_ids(self):
return frappe.db.sql("select name, fieldtype, label, fieldname from tabDocField where parent=%s", self.doc.doc_type, as_dict = 1)
return frappe.db.sql("select name, fieldtype, label, fieldname from tabDocField where parent=%s", self.doc_type, as_dict = 1)
def get_defaults(self):
if not self.doc.field_name:
return frappe.db.sql("select * from `tabDocType` where name=%s", self.doc.doc_type, as_dict = 1)[0]
if not self.field_name:
return frappe.db.sql("select * from `tabDocType` where name=%s", self.doc_type, as_dict = 1)[0]
else:
return frappe.db.sql("select * from `tabDocField` where fieldname=%s and parent=%s",
(self.doc.field_name, self.doc.doc_type), as_dict = 1)[0]
(self.field_name, self.doc_type), as_dict = 1)[0]
def on_update(self):
from frappe.core.doctype.doctype.doctype import validate_fields_for_doctype
validate_fields_for_doctype(self.doc.doc_type)
validate_fields_for_doctype(self.doc_type)
def make_property_setter(doctype, fieldname, property, value, property_type, for_doctype = False):
return frappe.bean({
return frappe.get_doc({
"doctype":"Property Setter",
"doctype_or_field": for_doctype and "DocType" or "DocField",
"doc_type": doctype,

View file

@ -1,130 +0,0 @@
[
{
"creation": "2013-01-10 16:34:04",
"docstatus": 0,
"modified": "2014-01-20 17:49:03",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"description": "Property Setter overrides a standard DocType or Field property",
"doctype": "DocType",
"icon": "icon-glass",
"module": "Core",
"name": "__common__",
"search_fields": "doc_name,property"
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "Property Setter",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"cancel": 0,
"create": 1,
"delete": 1,
"doctype": "DocPerm",
"email": 1,
"name": "__common__",
"parent": "Property Setter",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"submit": 0,
"write": 1
},
{
"doctype": "DocType",
"name": "Property Setter"
},
{
"doctype": "DocField",
"fieldname": "help",
"fieldtype": "HTML",
"label": "Help",
"options": "<div class=\"alert\">Please don't update it as it can mess up your form. Use the Customize Form View and Custom Fields to set properties!</div>"
},
{
"doctype": "DocField",
"fieldname": "sb0",
"fieldtype": "Section Break"
},
{
"depends_on": "eval:doc.__islocal",
"doctype": "DocField",
"fieldname": "doctype_or_field",
"fieldtype": "Select",
"label": "DocType or Field",
"options": "\nDocField\nDocType",
"reqd": 1
},
{
"description": "New value to be set",
"doctype": "DocField",
"fieldname": "value",
"fieldtype": "Text",
"label": "Set Value"
},
{
"doctype": "DocField",
"fieldname": "column_break0",
"fieldtype": "Column Break",
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "doc_type",
"fieldtype": "Link",
"in_filter": 0,
"label": "DocType",
"options": "DocType",
"reqd": 0,
"search_index": 1
},
{
"depends_on": "eval:doc.doctype_or_field=='DocField'",
"description": "ID (name) of the entity whose property is to be set",
"doctype": "DocField",
"fieldname": "field_name",
"fieldtype": "Data",
"in_filter": 0,
"label": "Field Name",
"reqd": 0,
"search_index": 1
},
{
"doctype": "DocField",
"fieldname": "property",
"fieldtype": "Data",
"in_filter": 0,
"label": "Property",
"reqd": 1,
"search_index": 1
},
{
"doctype": "DocField",
"fieldname": "property_type",
"fieldtype": "Data",
"label": "Property Type"
},
{
"doctype": "DocField",
"fieldname": "default_value",
"fieldtype": "Data",
"label": "Default Value"
},
{
"doctype": "DocPerm",
"role": "Administrator"
},
{
"doctype": "DocPerm",
"role": "System Manager"
}
]

View file

@ -0,0 +1,10 @@
[
{
"doc_type": "User",
"doctype_or_field": "DocField",
"field_name": "location",
"property": "in_list_view",
"property_type": "Check",
"value": "1"
}
]

View file

@ -0,0 +1,161 @@
{
"autoname": "field:report_name",
"creation": "2013-03-09 15:45:57.000000",
"docstatus": 0,
"doctype": "DocType",
"document_type": "System",
"fields": [
{
"fieldname": "report_name",
"fieldtype": "Data",
"label": "Report Name",
"permlevel": 0,
"read_only": 0,
"reqd": 1
},
{
"fieldname": "ref_doctype",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Ref DocType",
"options": "DocType",
"permlevel": 0,
"read_only": 0,
"reqd": 1
},
{
"fieldname": "is_standard",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Is Standard",
"options": "No\nYes",
"permlevel": 0,
"read_only": 0,
"reqd": 1
},
{
"fieldname": "add_total_row",
"fieldtype": "Check",
"label": "Add Total Row",
"permlevel": 0
},
{
"fieldname": "column_break_4",
"fieldtype": "Column Break",
"permlevel": 0,
"read_only": 0
},
{
"fieldname": "report_type",
"fieldtype": "Select",
"label": "Report Type",
"options": "Report Builder\nQuery Report\nScript Report",
"permlevel": 0,
"read_only": 0,
"reqd": 1
},
{
"fieldname": "disabled",
"fieldtype": "Check",
"label": "Disabled",
"permlevel": 0,
"read_only": 0
},
{
"fieldname": "section_break_6",
"fieldtype": "Section Break",
"permlevel": 0,
"read_only": 0
},
{
"depends_on": "eval:doc.report_type==\"Query Report\"",
"fieldname": "query",
"fieldtype": "Code",
"label": "Query",
"permlevel": 0,
"read_only": 0
},
{
"depends_on": "eval:doc.report_type==\"Query Report\"",
"description": "JavaScript Format: frappe.query_reports['REPORTNAME'] = {}",
"fieldname": "javascript",
"fieldtype": "Code",
"label": "Javascript",
"permlevel": 0
},
{
"depends_on": "eval:doc.report_type==\"Report Builder\"",
"fieldname": "json",
"fieldtype": "Text",
"label": "JSON",
"permlevel": 0,
"read_only": 1
},
{
"fieldname": "module",
"fieldtype": "Link",
"label": "Module",
"options": "Module Def",
"permlevel": 0
}
],
"icon": "icon-table",
"idx": 1,
"modified": "2014-03-07 15:20:02.000000",
"modified_by": "Administrator",
"module": "Core",
"name": "Report",
"owner": "Administrator",
"permissions": [
{
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Administrator",
"submit": 0,
"write": 1
},
{
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"submit": 0,
"write": 1
},
{
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "Report Manager",
"submit": 0,
"write": 1
},
{
"cancel": 0,
"delete": 0,
"email": 1,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "All",
"submit": 0
}
]
}

View file

@ -5,25 +5,24 @@ from __future__ import unicode_literals
import frappe
from frappe import conf, _
class DocType:
def __init__(self, doc, doclist):
self.doc, self.doclist = doc, doclist
from frappe.model.document import Document
class Report(Document):
def validate(self):
"""only administrator can save standard report"""
if not self.doc.module:
self.doc.module = frappe.db.get_value("DocType", self.doc.ref_doctype, "module")
if not self.module:
self.module = frappe.db.get_value("DocType", self.ref_doctype, "module")
if not self.doc.is_standard:
self.doc.is_standard = "No"
if not self.is_standard:
self.is_standard = "No"
if frappe.session.user=="Administrator" and getattr(conf, 'developer_mode',0)==1:
self.doc.is_standard = "Yes"
self.is_standard = "Yes"
if self.doc.is_standard == "Yes" and frappe.session.user!="Administrator":
if self.is_standard == "Yes" and frappe.session.user!="Administrator":
frappe.msgprint(_("Only Administrator can save a standard report. Please rename and save."),
raise_exception=True)
if self.doc.report_type in ("Query Report", "Script Report") \
if self.report_type in ("Query Report", "Script Report") \
and frappe.session.user!="Administrator":
frappe.msgprint(_("Only Administrator allowed to create Query / Script Reports"),
raise_exception=True)
@ -33,6 +32,6 @@ class DocType:
def export_doc(self):
from frappe.modules.export_file import export_to_files
if self.doc.is_standard == 'Yes' and (conf.get('developer_mode') or 0) == 1:
export_to_files(record_list=[['Report', self.doc.name]],
record_module=self.doc.module)
if self.is_standard == 'Yes' and (conf.get('developer_mode') or 0) == 1:
export_to_files(record_list=[['Report', self.name]],
record_module=self.module)

View file

@ -1,162 +0,0 @@
[
{
"creation": "2013-03-09 15:45:57",
"docstatus": 0,
"modified": "2014-03-07 15:20:02",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"autoname": "field:report_name",
"doctype": "DocType",
"document_type": "System",
"icon": "icon-table",
"module": "Core",
"name": "__common__"
},
{
"doctype": "DocField",
"name": "__common__",
"parent": "Report",
"parentfield": "fields",
"parenttype": "DocType",
"permlevel": 0
},
{
"cancel": 0,
"doctype": "DocPerm",
"email": 1,
"name": "__common__",
"parent": "Report",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"submit": 0
},
{
"doctype": "DocType",
"name": "Report"
},
{
"doctype": "DocField",
"fieldname": "report_name",
"fieldtype": "Data",
"label": "Report Name",
"read_only": 0,
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "ref_doctype",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Ref DocType",
"options": "DocType",
"read_only": 0,
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "is_standard",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Is Standard",
"options": "No\nYes",
"read_only": 0,
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "add_total_row",
"fieldtype": "Check",
"label": "Add Total Row"
},
{
"doctype": "DocField",
"fieldname": "column_break_4",
"fieldtype": "Column Break",
"read_only": 0
},
{
"doctype": "DocField",
"fieldname": "report_type",
"fieldtype": "Select",
"label": "Report Type",
"options": "Report Builder\nQuery Report\nScript Report",
"read_only": 0,
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "disabled",
"fieldtype": "Check",
"label": "Disabled",
"read_only": 0
},
{
"doctype": "DocField",
"fieldname": "section_break_6",
"fieldtype": "Section Break",
"read_only": 0
},
{
"depends_on": "eval:doc.report_type==\"Query Report\"",
"doctype": "DocField",
"fieldname": "query",
"fieldtype": "Code",
"label": "Query",
"read_only": 0
},
{
"depends_on": "eval:doc.report_type==\"Query Report\"",
"description": "JavaScript Format: frappe.query_reports['REPORTNAME'] = {}",
"doctype": "DocField",
"fieldname": "javascript",
"fieldtype": "Code",
"label": "Javascript"
},
{
"depends_on": "eval:doc.report_type==\"Report Builder\"",
"doctype": "DocField",
"fieldname": "json",
"fieldtype": "Text",
"label": "JSON",
"read_only": 1
},
{
"doctype": "DocField",
"fieldname": "module",
"fieldtype": "Link",
"label": "Module",
"options": "Module Def"
},
{
"create": 1,
"delete": 1,
"doctype": "DocPerm",
"role": "Administrator",
"write": 1
},
{
"create": 1,
"delete": 1,
"doctype": "DocPerm",
"role": "System Manager",
"write": 1
},
{
"create": 1,
"delete": 1,
"doctype": "DocPerm",
"role": "Report Manager",
"write": 1
},
{
"delete": 0,
"doctype": "DocPerm",
"role": "All"
}
]

Some files were not shown because too many files have changed in this diff Show more