@@ -96,9 +96,9 @@ def init(site, sites_path=None): | |||||
local.site_path = os.path.join(sites_path, site) | local.site_path = os.path.join(sites_path, site) | ||||
local.message_log = [] | local.message_log = [] | ||||
local.debug_log = [] | local.debug_log = [] | ||||
local.response = _dict({}) | |||||
local.lang = "en" | local.lang = "en" | ||||
local.request_method = request.method if request else None | local.request_method = request.method if request else None | ||||
local.response = _dict({"docs":[]}) | |||||
local.conf = _dict(get_site_config()) | local.conf = _dict(get_site_config()) | ||||
local.initialised = True | local.initialised = True | ||||
local.flags = _dict({}) | local.flags = _dict({}) | ||||
@@ -115,6 +115,15 @@ def init(site, sites_path=None): | |||||
setup_module_map() | 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): | def get_site_config(sites_path=None, site_path=None): | ||||
config = {} | config = {} | ||||
@@ -200,16 +209,6 @@ def throw(msg, exc=ValidationError): | |||||
def create_folder(path): | def create_folder(path): | ||||
if not os.path.exists(path): os.makedirs(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): | def set_user(username): | ||||
from frappe.utils.user import User | from frappe.utils.user import User | ||||
local.session["user"] = username | local.session["user"] = username | ||||
@@ -65,9 +65,6 @@ def get_bootinfo(): | |||||
for method in hooks.boot_session or []: | for method in hooks.boot_session or []: | ||||
frappe.get_attr(method)(bootinfo) | frappe.get_attr(method)(bootinfo) | ||||
from frappe.model.utils import compress | |||||
bootinfo['docs'] = compress(bootinfo['docs']) | |||||
if bootinfo.lang: | if bootinfo.lang: | ||||
bootinfo.lang = unicode(bootinfo.lang) | bootinfo.lang = unicode(bootinfo.lang) | ||||
@@ -138,10 +135,10 @@ def add_home_page(bootinfo, doclist): | |||||
home_page = frappe.get_application_home_page(frappe.session.user) | home_page = frappe.get_application_home_page(frappe.session.user) | ||||
try: | try: | ||||
page_doclist = frappe.widgets.page.get(home_page) | |||||
page = frappe.widgets.page.get(home_page) | |||||
except (frappe.DoesNotExistError, frappe.PermissionError), e: | 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 | |||||
doclist.append(page) |
@@ -9,23 +9,20 @@ import os | |||||
from frappe.utils import now, cint | from frappe.utils import now, cint | ||||
from frappe.model import no_value_fields | 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): | def validate(self): | ||||
if not frappe.conf.get("developer_mode"): | if not frappe.conf.get("developer_mode"): | ||||
frappe.throw("Not in Developer Mode! Set in site_config.json") | frappe.throw("Not in Developer Mode! Set in site_config.json") | ||||
for c in [".", "/", "#", "&", "=", ":", "'", '"']: | for c in [".", "/", "#", "&", "=", ":", "'", '"']: | ||||
if c in self.doc.name: | |||||
if c in self.name: | |||||
frappe.msgprint(c + " not allowed in name", raise_exception=1) | frappe.msgprint(c + " not allowed in name", raise_exception=1) | ||||
self.validate_series() | self.validate_series() | ||||
self.scrub_field_names() | self.scrub_field_names() | ||||
self.validate_title_field() | 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.make_amendable() | ||||
self.check_link_replacement_error() | self.check_link_replacement_error() | ||||
@@ -33,14 +30,14 @@ class DocType: | |||||
if frappe.flags.in_import: | if frappe.flags.in_import: | ||||
return | return | ||||
parent_list = frappe.db.sql("""SELECT parent | parent_list = frappe.db.sql("""SELECT parent | ||||
from tabDocField where fieldtype="Table" and options=%s""", self.doc.name) | |||||
from tabDocField where fieldtype="Table" and options=%s""", self.name) | |||||
for p in parent_list: | for p in parent_list: | ||||
frappe.db.sql('UPDATE tabDocType SET modified=%s WHERE `name`=%s', (now(), p[0])) | frappe.db.sql('UPDATE tabDocType SET modified=%s WHERE `name`=%s', (now(), p[0])) | ||||
def scrub_field_names(self): | def scrub_field_names(self): | ||||
restricted = ('name','parent','idx','owner','creation','modified','modified_by', | restricted = ('name','parent','idx','owner','creation','modified','modified_by', | ||||
'parentfield','parenttype',"file_list") | 'parentfield','parenttype',"file_list") | ||||
for d in self.doclist: | |||||
for d in self.get("fields"): | |||||
if d.parent and d.fieldtype: | if d.parent and d.fieldtype: | ||||
if (not d.fieldname): | if (not d.fieldname): | ||||
if d.label: | if d.label: | ||||
@@ -52,16 +49,16 @@ class DocType: | |||||
def validate_title_field(self): | 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")) | frappe.throw(_("Title field must be a valid fieldname")) | ||||
def validate_series(self, autoname=None, name=None): | 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: autoname = self.autoname | |||||
if not name: name = self.name | |||||
if not autoname and self.doclist.get({"fieldname":"naming_series"}): | |||||
self.doc.autoname = "naming_series:" | |||||
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:')) \ | if autoname and (not autoname.startswith('field:')) and (not autoname.startswith('eval:')) \ | ||||
and (not autoname=='Prompt') and (not autoname.startswith('naming_series:')): | and (not autoname=='Prompt') and (not autoname.startswith('naming_series:')): | ||||
@@ -72,10 +69,10 @@ class DocType: | |||||
def on_update(self): | def on_update(self): | ||||
from frappe.model.db_schema import updatedb | from frappe.model.db_schema import updatedb | ||||
updatedb(self.doc.name) | |||||
updatedb(self.name) | |||||
self.change_modified_of_parent() | self.change_modified_of_parent() | ||||
make_module_and_roles(self.doclist) | |||||
make_module_and_roles(self) | |||||
from frappe import conf | from frappe import conf | ||||
if (not frappe.flags.in_import) and conf.get('developer_mode') or 0: | if (not frappe.flags.in_import) and conf.get('developer_mode') or 0: | ||||
@@ -83,53 +80,53 @@ class DocType: | |||||
self.make_controller_template() | self.make_controller_template() | ||||
# update index | # update index | ||||
if not self.doc.custom: | |||||
if not self.custom: | |||||
from frappe.model.code import load_doctype_module | from frappe.model.code import load_doctype_module | ||||
module = load_doctype_module( self.doc.name, self.doc.module) | |||||
module = load_doctype_module( self.name, self.module) | |||||
if hasattr(module, "on_doctype_update"): | if hasattr(module, "on_doctype_update"): | ||||
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): | 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:") \ | if (frappe.db.get_value("DocField", d.name, "options") or "").startswith("link:") \ | ||||
and not d.options.startswith("link:"): | and not d.options.startswith("link:"): | ||||
frappe.msgprint("link: type Select fields are getting replaced. Please check for %s" % d.label, | frappe.msgprint("link: type Select fields are getting replaced. Please check for %s" % d.label, | ||||
raise_exception=True) | raise_exception=True) | ||||
def on_trash(self): | 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): | def before_rename(self, old, new, merge=False): | ||||
if merge: | if merge: | ||||
frappe.throw(_("DocType can not be merged")) | frappe.throw(_("DocType can not be merged")) | ||||
def after_rename(self, old, new, merge=False): | 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)) | frappe.db.sql("""update tabSingles set doctype=%s where doctype=%s""", (new, old)) | ||||
else: | else: | ||||
frappe.db.sql("rename table `tab%s` to `tab%s`" % (old, new)) | frappe.db.sql("rename table `tab%s` to `tab%s`" % (old, new)) | ||||
def export_doc(self): | def export_doc(self): | ||||
from frappe.modules.export_file import export_to_files | 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): | def import_doc(self): | ||||
from frappe.modules.import_module import import_from_files | 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): | def make_controller_template(self): | ||||
from frappe.modules import get_doc_path, get_module_path, scrub | 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): | if not os.path.exists(pypath): | ||||
# get app publisher for copyright | # 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: | if not app: | ||||
frappe.throw("App not found!") | frappe.throw("App not found!") | ||||
app_publisher = frappe.get_hooks(hook="app_publisher", app_name=app)[0] | app_publisher = frappe.get_hooks(hook="app_publisher", app_name=app)[0] | ||||
@@ -143,23 +140,22 @@ class DocType: | |||||
""" | """ | ||||
if is_submittable is set, add amended_from docfields | if is_submittable is set, add amended_from docfields | ||||
""" | """ | ||||
if self.doc.is_submittable: | |||||
if self.is_submittable: | |||||
if not frappe.db.sql("""select name from tabDocField | 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 | |||||
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): | def get_max_idx(self): | ||||
max_idx = frappe.db.sql("""select max(idx) from `tabDocField` where parent = %s""", | max_idx = frappe.db.sql("""select max(idx) from `tabDocField` where parent = %s""", | ||||
self.doc.name) | |||||
self.name) | |||||
return max_idx and max_idx[0][0] or 0 | return max_idx and max_idx[0][0] or 0 | ||||
def validate_fields_for_doctype(doctype): | def validate_fields_for_doctype(doctype): | ||||
@@ -329,14 +325,14 @@ def validate_permissions(permissions, for_remove=False): | |||||
check_level_zero_is_set(d) | check_level_zero_is_set(d) | ||||
remove_rights_for_single(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: | 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.bean({"doctype": "Module Def", "module_name": doc.module}) | |||||
m.insert() | m.insert() | ||||
default_roles = ["Administrator", "Guest", "All"] | 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)] + default_roles | |||||
for role in list(set(roles)): | for role in list(set(roles)): | ||||
if not frappe.db.exists("Role", role): | if not frappe.db.exists("Role", role): | ||||
@@ -3,11 +3,9 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import frappe | 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): | def autoname(self): | ||||
""" | """ | ||||
Creates a url friendly name for this page. | Creates a url friendly name for this page. | ||||
@@ -15,17 +13,17 @@ class DocType: | |||||
it will add name-1, name-2 etc. | it will add name-1, name-2 etc. | ||||
""" | """ | ||||
from frappe.utils import cint | 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] | 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 | 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: | if cnt: | ||||
cnt = cint(cnt[0][0].split('-')[-1]) + 1 | cnt = cint(cnt[0][0].split('-')[-1]) + 1 | ||||
else: | else: | ||||
cnt = 1 | cnt = 1 | ||||
self.doc.name += '-' + str(cnt) | |||||
self.name += '-' + str(cnt) | |||||
# export | # export | ||||
def on_update(self): | def on_update(self): | ||||
@@ -35,16 +33,16 @@ class DocType: | |||||
""" | """ | ||||
from frappe import conf | from frappe import conf | ||||
from frappe.core.doctype.doctype.doctype import make_module_and_roles | 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.export_file import export_to_files | ||||
from frappe.modules import get_module_path, scrub | from frappe.modules import get_module_path, scrub | ||||
import os | import os | ||||
export_to_files(record_list=[['Page', self.doc.name]]) | |||||
export_to_files(record_list=[['Page', self.name]]) | |||||
# write files | # 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 | # js | ||||
if not os.path.exists(path + '.js'): | if not os.path.exists(path + '.js'): | ||||
@@ -55,35 +53,39 @@ class DocType: | |||||
title: '%s', | title: '%s', | ||||
single_column: true | 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 | from frappe.modules import get_module_path, scrub | ||||
import os | 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 | # 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): | if os.path.exists(fpath): | ||||
with open(fpath, 'r') as f: | with open(fpath, 'r') as f: | ||||
self.doc.script = f.read() | |||||
self.script = f.read() | |||||
# css | # 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): | if os.path.exists(fpath): | ||||
with open(fpath, 'r') as f: | with open(fpath, 'r') as f: | ||||
self.doc.style = f.read() | |||||
self.style = f.read() | |||||
# html | # 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): | if os.path.exists(fpath): | ||||
with open(fpath, 'r') as f: | with open(fpath, 'r') as f: | ||||
self.doc.content = f.read() | |||||
self.content = f.read() | |||||
if frappe.lang != 'en': | if frappe.lang != 'en': | ||||
from frappe.translate import get_lang_js | 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) | |||||
@@ -151,8 +151,7 @@ frappe.RoleEditor = Class.extend({ | |||||
.each(function(i, checkbox) { checkbox.checked = false; }); | .each(function(i, checkbox) { checkbox.checked = false; }); | ||||
// set user roles as checked | // set user roles as checked | ||||
$.each(frappe.model.get("UserRole", {parent: cur_frm.doc.name, | |||||
parentfield: "user_roles"}), function(i, user_role) { | |||||
$.each((cur_frm.doc.user_roles || []), function(i, user_role) { | |||||
var checkbox = $(me.wrapper) | var checkbox = $(me.wrapper) | ||||
.find('[data-user-role="'+user_role.role+'"] input[type="checkbox"]').get(0); | .find('[data-user-role="'+user_role.role+'"] input[type="checkbox"]').get(0); | ||||
if(checkbox) checkbox.checked = true; | if(checkbox) checkbox.checked = true; | ||||
@@ -163,8 +162,7 @@ frappe.RoleEditor = Class.extend({ | |||||
var existing_roles_map = {}; | var existing_roles_map = {}; | ||||
var existing_roles_list = []; | var existing_roles_list = []; | ||||
$.each(frappe.model.get("UserRole", {parent: cur_frm.doc.name, | |||||
parentfield: "user_roles"}), function(i, user_role) { | |||||
$.each((cur_frm.doc.user_roles || []), function(i, user_role) { | |||||
existing_roles_map[user_role.role] = user_role.name; | existing_roles_map[user_role.role] = user_role.name; | ||||
existing_roles_list.push(user_role.role); | existing_roles_list.push(user_role.role); | ||||
}); | }); | ||||
@@ -20,11 +20,9 @@ frappe.core.Workflow = frappe.ui.form.Controller.extend({ | |||||
} | } | ||||
}, | }, | ||||
update_field_options: function() { | update_field_options: function() { | ||||
var fields = $.map(frappe.model.get("DocField", { | |||||
parent: this.frm.doc.document_type, | |||||
fieldtype: ["not in", frappe.model.no_value_type] | |||||
}), | |||||
function(d) { return d.fieldname; }); | |||||
var fields = $.map(frappe.model.get_doc("DocType", this.frm.doc.document_type).fields, function(d) { | |||||
return frappe.model.no_value_type.indexOf(d.fieldtype)===-1 ? d.fieldname : null; | |||||
}) | |||||
frappe.meta.get_docfield("Workflow Document State", "update_field", this.frm.doc.name).options | frappe.meta.get_docfield("Workflow Document State", "update_field", this.frm.doc.name).options | ||||
= [""].concat(fields); | = [""].concat(fields); | ||||
} | } | ||||
@@ -428,17 +428,15 @@ frappe.PermissionEngine = Class.extend({ | |||||
}); | }); | ||||
}, | }, | ||||
get_user_fields: function(doctype) { | get_user_fields: function(doctype) { | ||||
var user_fields = frappe.model.get("DocField", {parent:doctype, | |||||
fieldtype:"Link", options:"User"}); | |||||
user_fields = user_fields.concat(frappe.model.get("DocField", {parent:doctype, | |||||
fieldtype:"Select", link_doctype:"User"})) | |||||
var user_fields = frappe.model.get_children("DocType", doctype, "fields", {fieldtype:"Link", options:"User"}) | |||||
user_fields = user_fields.concat(frappe.model.get_children("DocType", doctype, "fields", | |||||
{fieldtype:"Select", link_doctype:"User"})) | |||||
return user_fields | return user_fields | ||||
}, | }, | ||||
get_link_fields: function(doctype) { | get_link_fields: function(doctype) { | ||||
return link_fields = frappe.model.get("DocField", {parent:doctype, | |||||
fieldtype:"Link", options:["not in", ["User", '[Select]']]}); | |||||
return frappe.model.get_children("DocType", doctype, "fields", | |||||
{fieldtype:"Link", options:["not in", ["User", '[Select]']]}); | |||||
} | } | ||||
}) | }) | ||||
@@ -65,7 +65,7 @@ def handle(): | |||||
if cmd!='login': | if cmd!='login': | ||||
execute_cmd(cmd) | execute_cmd(cmd) | ||||
return build_response("json") | return build_response("json") | ||||
def execute_cmd(cmd): | def execute_cmd(cmd): | ||||
@@ -110,6 +110,16 @@ class BaseDocument(object): | |||||
return self._valid_columns | return self._valid_columns | ||||
def as_dict(self): | |||||
doc = self.get_valid_dict() | |||||
doc["doctype"] = self.doctype | |||||
for df in self.get_table_fields(): | |||||
doc[df.fieldname] = [d.as_dict() for d in (self.get(df.fieldname) or [])] | |||||
return doc | |||||
def get_table_fields(self): | |||||
return self.meta.get('fields', {"fieldtype":"Table"}) | |||||
def get_table_field_doctype(self, fieldname): | def get_table_field_doctype(self, fieldname): | ||||
return self.meta.get("fields", {"fieldname":fieldname})[0].options | return self.meta.get("fields", {"fieldname":fieldname})[0].options | ||||
@@ -41,6 +41,7 @@ def get_obj(dt = None, dn = None, doc=None, doclist=None, with_children = 0): | |||||
def get_server_obj(doc, doclist = [], basedoctype = ''): | def get_server_obj(doc, doclist = [], basedoctype = ''): | ||||
# for test | # for test | ||||
module = get_doctype_module(doc.doctype) | module = get_doctype_module(doc.doctype) | ||||
classname = doc.doctype.replace(" ", "") | |||||
return load_doctype_module(doc.doctype, module).DocType(doc, doclist) | return load_doctype_module(doc.doctype, module).DocType(doc, doclist) | ||||
def run_server_obj(server_obj, method_name, arg=None): | def run_server_obj(server_obj, method_name, arg=None): | ||||
@@ -242,6 +242,8 @@ def clear_cache(doctype=None): | |||||
def clear_single(dt): | def clear_single(dt): | ||||
frappe.cache().delete_value(cache_name(dt, False)) | frappe.cache().delete_value(cache_name(dt, False)) | ||||
frappe.cache().delete_value(cache_name(dt, True)) | frappe.cache().delete_value(cache_name(dt, True)) | ||||
frappe.cache().delete_value("meta:" + dt) | |||||
frappe.cache().delete_value("form_meta:" + dt) | |||||
if doctype_cache and (dt in doctype_cache): | if doctype_cache and (dt in doctype_cache): | ||||
del doctype_cache[dt] | del doctype_cache[dt] | ||||
@@ -16,15 +16,20 @@ def get_doc(arg1, arg2=None): | |||||
doctype = arg1 | doctype = arg1 | ||||
else: | else: | ||||
doctype = arg1.get("doctype") | doctype = arg1.get("doctype") | ||||
controller = get_controller(doctype) | |||||
if controller: | |||||
return controller(arg1, arg2) | |||||
return Document(arg1, arg2) | |||||
def get_controller(doctype): | |||||
module = load_doctype_module(doctype) | module = load_doctype_module(doctype) | ||||
classname = doctype.replace(" ", "") | classname = doctype.replace(" ", "") | ||||
if hasattr(module, classname): | if hasattr(module, classname): | ||||
_class = getattr(module, classname) | _class = getattr(module, classname) | ||||
if issubclass(_class, Document): | if issubclass(_class, Document): | ||||
return getattr(module, classname)(arg1, arg2) | |||||
return Document(arg1, arg2) | |||||
return getattr(module, classname) | |||||
class Document(BaseDocument): | class Document(BaseDocument): | ||||
def __init__(self, arg1, arg2=None): | def __init__(self, arg1, arg2=None): | ||||
@@ -59,6 +64,9 @@ class Document(BaseDocument): | |||||
else: | else: | ||||
d = frappe.db.get_value(self.doctype, self.name, "*", as_dict=1) | d = frappe.db.get_value(self.doctype, self.name, "*", as_dict=1) | ||||
if not d: | |||||
frappe.throw("{}: {}, {}".format(_("Not Found"), | |||||
self.doctype, self.name), frappe.DoesNotExistError) | |||||
self.update(d, valid_columns = d.keys()) | self.update(d, valid_columns = d.keys()) | ||||
for df in self.get_table_fields(): | for df in self.get_table_fields(): | ||||
@@ -70,9 +78,6 @@ class Document(BaseDocument): | |||||
else: | else: | ||||
self.set(df.fieldname, []) | self.set(df.fieldname, []) | ||||
def get_table_fields(self): | |||||
return self.meta.get('fields', {"fieldtype":"Table"}) | |||||
def has_permission(self, permtype): | def has_permission(self, permtype): | ||||
if getattr(self, "_ignore_permissions", False): | if getattr(self, "_ignore_permissions", False): | ||||
return True | return True | ||||
@@ -293,23 +298,10 @@ class Document(BaseDocument): | |||||
def run_method(self, method, *args, **kwargs): | def run_method(self, method, *args, **kwargs): | ||||
"""run standard triggers, plus those in frappe""" | """run standard triggers, plus those in frappe""" | ||||
def add_to_response(out, new_response): | |||||
if isinstance(new_response, dict): | |||||
out.update(new_response) | |||||
if hasattr(self, method): | if hasattr(self, method): | ||||
add_to_response(frappe.local.response, | |||||
getattr(self, method)(*args, **kwargs)) | |||||
args = [self, method] + list(args or []) | |||||
for handler in frappe.get_hooks("bean_event:" + self.doctype + ":" + method) \ | |||||
+ frappe.get_hooks("bean_event:*:" + method): | |||||
add_to_response(frappe.local.response, | |||||
frappe.call(frappe.get_attr(handler), *args, **kwargs)) | |||||
return frappe.local.response | |||||
fn = lambda self, *args, **kwargs: getattr(self, method)(*args, **kwargs) | |||||
return Document.hook(fn)(self, *args, **kwargs) | |||||
def run_before_save_methods(self): | def run_before_save_methods(self): | ||||
if self._action=="save": | if self._action=="save": | ||||
self.run_method("validate") | self.run_method("validate") | ||||
@@ -332,3 +324,31 @@ class Document(BaseDocument): | |||||
self.run_method("on_cancel") | self.run_method("on_cancel") | ||||
elif self._action=="update_after_submit": | elif self._action=="update_after_submit": | ||||
self.run_method("on_update_after_submit") | self.run_method("on_update_after_submit") | ||||
@staticmethod | |||||
def hook(f): | |||||
def add_to_response(new_response): | |||||
if isinstance(new_response, dict): | |||||
frappe.local.response.update(new_response) | |||||
def compose(fn, *hooks): | |||||
def runner(self, method, *args, **kwargs): | |||||
add_to_response(fn(self, *args, **kwargs)) | |||||
for f in hooks: | |||||
add_to_response(f(self, method, *args, **kwargs)) | |||||
return frappe.local.response | |||||
return runner | |||||
def composer(self, *args, **kwargs): | |||||
hooks = [] | |||||
method = f.__name__ | |||||
for handler in frappe.get_hooks("bean_event:" + self.doctype + ":" + method) \ | |||||
+ frappe.get_hooks("bean_event:*:" + method): | |||||
hooks.append(frappe.getattr(handler)) | |||||
composed = compose(f, *hooks) | |||||
return composed(self, method, *args, **kwargs) | |||||
return composer | |||||
@@ -12,6 +12,8 @@ from frappe.model.document import Document | |||||
###### | ###### | ||||
def get_meta(doctype, cached=True): | def get_meta(doctype, cached=True): | ||||
# TODO: cache to be cleared | |||||
if cached: | if cached: | ||||
if doctype not in frappe.local.meta: | if doctype not in frappe.local.meta: | ||||
frappe.local.meta[doctype] = frappe.cache().get_value("meta:" + doctype, lambda: Meta(doctype)) | frappe.local.meta[doctype] = frappe.cache().get_value("meta:" + doctype, lambda: Meta(doctype)) | ||||
@@ -83,7 +83,6 @@ | |||||
"public/js/frappe/model/model.js", | "public/js/frappe/model/model.js", | ||||
"public/js/frappe/model/meta.js", | "public/js/frappe/model/meta.js", | ||||
"public/js/frappe/model/doclist.js", | |||||
"public/js/frappe/model/sync.js", | "public/js/frappe/model/sync.js", | ||||
"public/js/frappe/model/create_new.js", | "public/js/frappe/model/create_new.js", | ||||
"public/js/frappe/model/perm.js", | "public/js/frappe/model/perm.js", | ||||
@@ -135,6 +134,7 @@ | |||||
"public/js/frappe/form/toolbar.js", | "public/js/frappe/form/toolbar.js", | ||||
"public/js/frappe/form/infobar.js", | "public/js/frappe/form/infobar.js", | ||||
"public/js/frappe/form/dashboard.js", | "public/js/frappe/form/dashboard.js", | ||||
"public/js/frappe/form/save.js", | |||||
"public/js/frappe/form/script_manager.js", | "public/js/frappe/form/script_manager.js", | ||||
"public/js/frappe/form/control.js", | "public/js/frappe/form/control.js", | ||||
"public/js/frappe/form/link_selector.js", | "public/js/frappe/form/link_selector.js", | ||||
@@ -980,8 +980,9 @@ frappe.ui.form.ControlTable = frappe.ui.form.Control.extend({ | |||||
this._super(); | this._super(); | ||||
// add title if prev field is not column / section heading or html | // add title if prev field is not column / section heading or html | ||||
var prev_fieldtype = frappe.model.get("DocField", | |||||
{parent: this.frm.doctype, idx: this.df.idx-1})[0].fieldtype; | |||||
var prev_fieldtype = frappe.model.get_children("DocType", this.frm.doctype, "fields", | |||||
{idx: this.df.idx-1}); | |||||
prev_fieldtype = prev_fieldtype ? prev_fieldtype[0].fieldtype : ""; | |||||
if(["Column Break", "Section Break", "HTML"].indexOf(prev_fieldtype)===-1) { | if(["Column Break", "Section Break", "HTML"].indexOf(prev_fieldtype)===-1) { | ||||
$("<label>" + this.df.label + "<label>").appendTo(this.wrapper); | $("<label>" + this.df.label + "<label>").appendTo(this.wrapper); | ||||
@@ -98,7 +98,7 @@ frappe.form.formatters = { | |||||
return "<pre>" + (value==null ? "" : $("<div>").text(value).html()) + "</pre>" | return "<pre>" + (value==null ? "" : $("<div>").text(value).html()) + "</pre>" | ||||
}, | }, | ||||
WorkflowState: function(value) { | WorkflowState: function(value) { | ||||
workflow_state = frappe.model.get("Workflow State", value)[0]; | |||||
workflow_state = frappe.model.get_doc("Workflow State", value); | |||||
if(workflow_state) { | if(workflow_state) { | ||||
return repl("<span class='label label-%(style)s' \ | return repl("<span class='label label-%(style)s' \ | ||||
data-workflow-state='%(value)s'\ | data-workflow-state='%(value)s'\ | ||||
@@ -118,11 +118,7 @@ frappe.ui.form.Grid = Class.extend({ | |||||
}); | }); | ||||
}, | }, | ||||
get_data: function() { | get_data: function() { | ||||
var data = frappe.model.get(this.df.options, { | |||||
"parenttype": this.frm.doctype, | |||||
"parentfield": this.df.fieldname, | |||||
"parent": this.frm.docname | |||||
}); | |||||
var data = this.frm.doc[this.df.fieldname] || []; | |||||
data.sort(function(a, b) { return a.idx - b.idx}); | data.sort(function(a, b) { return a.idx - b.idx}); | ||||
return data; | return data; | ||||
}, | }, | ||||
@@ -1,9 +1,7 @@ | |||||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | ||||
// MIT License. See license.txt | // MIT License. See license.txt | ||||
// for license information please see license.txt | |||||
frappe.provide("frappe.ui.form") | |||||
frappe.provide("frappe.ui.form"); | |||||
frappe.ui.form.LinkedWith = Class.extend({ | frappe.ui.form.LinkedWith = Class.extend({ | ||||
init: function(opts) { | init: function(opts) { | ||||
@@ -1,45 +1,38 @@ | |||||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | // Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | ||||
// MIT License. See license.txt | |||||
// MIT License. See license.txt | |||||
frappe.provide("frappe.model"); | |||||
frappe.model.DocList = Class.extend({ | |||||
init: function(doctype, name) { | |||||
this.doctype = doctype; this.name = name; | |||||
this.doclist = frappe.model.get_doclist(this.doctype, this.name); | |||||
this.doc = this.doclist[0]; | |||||
}, | |||||
save: function(action, callback, btn) { | |||||
this.check_name(); | |||||
if(this.check_mandatory()) { | |||||
var me = this; | |||||
this._call({ | |||||
frappe.provide("frappe.ui.form"); | |||||
frappe.ui.form.save = function(frm, action, callback, btn) { | |||||
var save = function() { | |||||
check_name(); | |||||
if(check_mandatory()) { | |||||
_call({ | |||||
method: "frappe.widgets.form.save.savedocs", | method: "frappe.widgets.form.save.savedocs", | ||||
args: { docs: frappe.model.compress(this.doclist), action:action}, | |||||
args: { docs: frm.doc, action:action}, | |||||
callback: function(r) { | callback: function(r) { | ||||
$(document).trigger("save", me.doc); | |||||
$(document).trigger("save", frm.doc); | |||||
callback(r); | callback(r); | ||||
}, | }, | ||||
btn: btn | btn: btn | ||||
}); | }); | ||||
} | } | ||||
}, | |||||
}; | |||||
cancel: function(callback, btn) { | |||||
var me = this; | |||||
this._call({ | |||||
var cancel = function() { | |||||
_call({ | |||||
method: "frappe.widgets.form.save.cancel", | method: "frappe.widgets.form.save.cancel", | ||||
args: { doctype: this.doctype, name: this.name }, | |||||
args: { doctype: frm.doc.doctype, name: frm.doc.name }, | |||||
callback: function(r) { | callback: function(r) { | ||||
$(document).trigger("save", frappe.model.get_doc(me.doctype, me.name)); | |||||
$(document).trigger("save", frm.doc); | |||||
callback(r); | callback(r); | ||||
}, | }, | ||||
btn: btn | btn: btn | ||||
}); | }); | ||||
}, | |||||
}; | |||||
check_name: function() { | |||||
var doc = this.doclist[0]; | |||||
var check_name = function() { | |||||
var doc = frm.doc; | |||||
var meta = locals.DocType[doc.doctype]; | var meta = locals.DocType[doc.doctype]; | ||||
if(doc.__islocal && (meta && meta.autoname | if(doc.__islocal && (meta && meta.autoname | ||||
&& meta.autoname.toLowerCase()=='prompt')) { | && meta.autoname.toLowerCase()=='prompt')) { | ||||
@@ -51,23 +44,22 @@ frappe.model.DocList = Class.extend({ | |||||
throw "name required"; | throw "name required"; | ||||
} | } | ||||
} | } | ||||
}, | |||||
}; | |||||
check_mandatory: function() { | |||||
var me = this; | |||||
var check_mandatory = function() { | |||||
var has_errors = false; | var has_errors = false; | ||||
this.scroll_set = false; | |||||
frm.scroll_set = false; | |||||
if(this.doc.docstatus==2) return true; // don't check for cancel | |||||
if(frm.doc.docstatus==2) return true; // don't check for cancel | |||||
$.each(this.doclist, function(i, doc) { | |||||
$.each(frm.model.get_all_docs(frm.doc), function(i, doc) { | |||||
var error_fields = []; | var error_fields = []; | ||||
$.each(frappe.meta.docfield_list[doc.doctype] || [], function(i, docfield) { | $.each(frappe.meta.docfield_list[doc.doctype] || [], function(i, docfield) { | ||||
if(docfield.fieldname) { | if(docfield.fieldname) { | ||||
var df = frappe.meta.get_docfield(doc.doctype, | var df = frappe.meta.get_docfield(doc.doctype, | ||||
docfield.fieldname, me.doclist[0].name); | |||||
docfield.fieldname, frm.doc.name); | |||||
if(df.reqd && !frappe.model.has_value(doc.doctype, doc.name, df.fieldname)) { | if(df.reqd && !frappe.model.has_value(doc.doctype, doc.name, df.fieldname)) { | ||||
has_errors = true; | has_errors = true; | ||||
@@ -87,17 +79,17 @@ frappe.model.DocList = Class.extend({ | |||||
}); | }); | ||||
return !has_errors; | return !has_errors; | ||||
}, | |||||
}; | |||||
scroll_to: function(fieldname) { | |||||
var scroll_to = function(fieldname) { | |||||
var f = cur_frm.fields_dict[fieldname]; | var f = cur_frm.fields_dict[fieldname]; | ||||
if(f) { | if(f) { | ||||
$(document).scrollTop($(f.wrapper).offset().top - 100); | $(document).scrollTop($(f.wrapper).offset().top - 100); | ||||
} | } | ||||
this.scroll_set = true; | |||||
}, | |||||
frm.scroll_set = true; | |||||
}; | |||||
_call: function(opts) { | |||||
var _call = function(opts) { | |||||
// opts = { | // opts = { | ||||
// method: "some server method", | // method: "some server method", | ||||
// args: {args to be passed}, | // args: {args to be passed}, | ||||
@@ -114,5 +106,11 @@ frappe.model.DocList = Class.extend({ | |||||
opts.callback && opts.callback(r); | opts.callback && opts.callback(r); | ||||
} | } | ||||
}) | }) | ||||
}, | |||||
}); | |||||
}; | |||||
if(action==="cancel") { | |||||
cancel(); | |||||
} else { | |||||
save(); | |||||
} | |||||
} |
@@ -109,7 +109,7 @@ frappe.ui.form.ScriptManager = Class.extend({ | |||||
} | } | ||||
}, | }, | ||||
copy_from_first_row: function(parentfield, current_row, fieldnames) { | copy_from_first_row: function(parentfield, current_row, fieldnames) { | ||||
var doclist = frappe.model.get_doclist(this.frm.doc.doctype, this.frm.doc.name, {parentfield: parentfield}); | |||||
var doclist = this.frm.doc[parentfield]; | |||||
if(doclist.length===1 || doclist[0]===current_row) return; | if(doclist.length===1 || doclist[0]===current_row) return; | ||||
$.each(fieldnames, function(i, fieldname) { | $.each(fieldnames, function(i, fieldname) { | ||||
@@ -79,7 +79,7 @@ frappe.ui.form.States = Class.extend({ | |||||
// show current state on the button | // show current state on the button | ||||
this.workflow_button.find(".state-text").text(state); | this.workflow_button.find(".state-text").text(state); | ||||
var state_doc = frappe.model.get("Workflow State", {name:state})[0]; | |||||
var state_doc = frappe.model.get_doc("Workflow State", state); | |||||
if (state_doc) { | if (state_doc) { | ||||
// set the icon | // set the icon | ||||
@@ -109,7 +109,7 @@ frappe.ui.form.States = Class.extend({ | |||||
$.each(frappe.workflow.get_transitions(this.frm.doctype, state), function(i, d) { | $.each(frappe.workflow.get_transitions(this.frm.doctype, state), function(i, d) { | ||||
if(in_list(user_roles, d.allowed)) { | if(in_list(user_roles, d.allowed)) { | ||||
d.icon = frappe.model.get("Workflow State", {name:d.next_state})[0].icon; | |||||
d.icon = frappe.model.get("Workflow State", d.next_state).icon; | |||||
$(repl('<li><a href="#" data-action="%(action)s">\ | $(repl('<li><a href="#" data-action="%(action)s">\ | ||||
<i class="icon icon-%(icon)s"></i> %(action)s</a></li>', d)) | <i class="icon icon-%(icon)s"></i> %(action)s</a></li>', d)) | ||||
@@ -122,20 +122,36 @@ $.extend(frappe.model, { | |||||
return d; | return d; | ||||
}, | }, | ||||
copy_doc: function(dt, dn, from_amend) { | |||||
copy_doc: function(doc, from_amend) { | |||||
var no_copy_list = ['name','amended_from','amendment_date','cancel_reason']; | var no_copy_list = ['name','amended_from','amendment_date','cancel_reason']; | ||||
var newdoc = frappe.model.get_new_doc(dt); | |||||
var newdoc = frappe.model.get_new_doc(doc.doctype); | |||||
for(var key in locals[dt][dn]) { | |||||
for(var key in doc) { | |||||
// dont copy name and blank fields | // dont copy name and blank fields | ||||
var df = frappe.meta.get_docfield(dt, key); | |||||
var df = frappe.meta.get_docfield(doc.doctype, key); | |||||
if(key.substr(0,2)!='__' | if(key.substr(0,2)!='__' | ||||
&& !in_list(no_copy_list, key) | && !in_list(no_copy_list, key) | ||||
&& !(df && (!from_amend && cint(df.no_copy)==1))) { | && !(df && (!from_amend && cint(df.no_copy)==1))) { | ||||
newdoc[key] = locals[dt][dn][key]; | |||||
value = doc[key]; | |||||
if(df.fieldtype==="Table") { | |||||
newdoc[key] = []; | |||||
$.each(value || [], function(i, d) { | |||||
newdoc[key].push(frappe.model.copy_doc(d, from_amend)) | |||||
}) | |||||
} else { | |||||
newdoc[key] = doc[key]; | |||||
} | |||||
} | } | ||||
} | } | ||||
newdoc.__islocal = 1; | |||||
newdoc.docstatus = 0; | |||||
newdoc.owner = user; | |||||
newdoc.creation = ''; | |||||
newdoc.modified_by = user; | |||||
newdoc.modified = ''; | |||||
return newdoc; | return newdoc; | ||||
}, | }, | ||||
@@ -167,7 +183,7 @@ $.extend(frappe.model, { | |||||
method: opts.method, | method: opts.method, | ||||
args: { | args: { | ||||
"source_name": opts.source_name, | "source_name": opts.source_name, | ||||
"target_doclist": frappe.model.get_doclist(cur_frm.doc.doctype, cur_frm.doc.name) | |||||
"target_doclist": cur_frm.doc | |||||
}, | }, | ||||
callback: function(r) { | callback: function(r) { | ||||
if(!r.exc) { | if(!r.exc) { | ||||
@@ -8,6 +8,13 @@ frappe.provide('frappe.meta.doctypes'); | |||||
frappe.provide("frappe.meta.precision_map"); | frappe.provide("frappe.meta.precision_map"); | ||||
$.extend(frappe.meta, { | $.extend(frappe.meta, { | ||||
sync: function(doc) { | |||||
$.each(doc.fields, function(i, df) { | |||||
frappe.meta.add_field(df); | |||||
}) | |||||
frappe.meta.sync_messages(doc); | |||||
}, | |||||
// build docfield_map and docfield_list | // build docfield_map and docfield_list | ||||
add_field: function(df) { | add_field: function(df) { | ||||
frappe.provide('frappe.meta.docfield_map.' + df.parent); | frappe.provide('frappe.meta.docfield_map.' + df.parent); | ||||
@@ -84,8 +91,8 @@ $.extend(frappe.meta, { | |||||
}, | }, | ||||
get_parentfield: function(parent_dt, child_dt) { | get_parentfield: function(parent_dt, child_dt) { | ||||
var df = frappe.model.get("DocField", {parent:parent_dt, fieldtype:"Table", | |||||
options:child_dt}) | |||||
var df = (frappe.model.get_doc("DocType", parent_dt).fields || []).filter(function(d) | |||||
{ return d.fieldtype==="Table" && options===child_dt }) | |||||
if(!df.length) | if(!df.length) | ||||
throw "parentfield not found for " + parent_dt + ", " + child_dt; | throw "parentfield not found for " + parent_dt + ", " + child_dt; | ||||
return df[0].fieldname; | return df[0].fieldname; | ||||
@@ -46,8 +46,8 @@ $.extend(frappe.model, { | |||||
} else { | } else { | ||||
var cached_timestamp = null; | var cached_timestamp = null; | ||||
if(localStorage["_doctype:" + doctype]) { | if(localStorage["_doctype:" + doctype]) { | ||||
var cached_doclist = JSON.parse(localStorage["_doctype:" + doctype]); | |||||
cached_timestamp = cached_doclist[0].modified; | |||||
var cached_doc = JSON.parse(localStorage["_doctype:" + doctype]); | |||||
cached_timestamp = cached_doc.modified; | |||||
} | } | ||||
return frappe.call({ | return frappe.call({ | ||||
method:'frappe.widgets.form.load.getdoctype', | method:'frappe.widgets.form.load.getdoctype', | ||||
@@ -64,7 +64,7 @@ $.extend(frappe.model, { | |||||
return; | return; | ||||
} | } | ||||
if(r.message=="use_cache") { | if(r.message=="use_cache") { | ||||
frappe.model.sync(cached_doclist); | |||||
frappe.model.sync(cached_doc); | |||||
} else { | } else { | ||||
localStorage["_doctype:" + doctype] = JSON.stringify(r.docs); | localStorage["_doctype:" + doctype] = JSON.stringify(r.docs); | ||||
} | } | ||||
@@ -206,10 +206,10 @@ $.extend(frappe.model, { | |||||
}, | }, | ||||
get: function(doctype, filters) { | get: function(doctype, filters) { | ||||
var src = locals[doctype] || locals[":" + doctype] || []; | |||||
if($.isEmptyObject(src)) | |||||
var docsdict = locals[doctype] || locals[":" + doctype] || []; | |||||
if($.isEmptyObject(docsdict)) | |||||
return []; | return []; | ||||
return frappe.utils.filter_dict(src, filters); | |||||
return frappe.utils.filter_dict(docsdict, filters); | |||||
}, | }, | ||||
get_value: function(doctype, filters, fieldname) { | get_value: function(doctype, filters, fieldname) { | ||||
@@ -277,55 +277,16 @@ $.extend(frappe.model, { | |||||
return locals[doctype] ? locals[doctype][name] : null; | return locals[doctype] ? locals[doctype][name] : null; | ||||
}, | }, | ||||
get_doclist: function(doctype, name, filters) { | |||||
var doclist = []; | |||||
if(!locals[doctype]) | |||||
return doclist; | |||||
doclist[0] = locals[doctype][name]; | |||||
$.each(frappe.model.get("DocField", {parent:doctype, fieldtype:"Table"}), | |||||
function(i, table_field) { | |||||
var child_doclist = frappe.model.get(table_field.options, { | |||||
parent:name, parenttype: doctype, | |||||
parentfield: table_field.fieldname}); | |||||
if($.isArray(child_doclist)) { | |||||
child_doclist.sort(function(a, b) { return a.idx - b.idx; }); | |||||
doclist = doclist.concat(child_doclist); | |||||
} | |||||
} | |||||
); | |||||
if(filters) { | |||||
doclist = frappe.utils.filter_dict(doclist, filters); | |||||
} | |||||
return doclist; | |||||
}, | |||||
get_children: function(doctype, parent, parentfield, parenttype) { | |||||
if(parenttype) { | |||||
var l = frappe.model.get(doctype, {parent:parent, | |||||
parentfield:parentfield, parenttype:parenttype}); | |||||
get_children: function(doctype, parent, parentfield, filters) { | |||||
if($.isPlainObject(parentfield)) { | |||||
var doc = doctype; | |||||
var filters = parentfield; | |||||
var parentfield = parent; | |||||
return frappe.utils.filter_dict((doc[parentfield] || []), filters); | |||||
} else { | } else { | ||||
var l = frappe.model.get(doctype, {parent:parent, | |||||
parentfield:parentfield}); | |||||
return frappe.utils.filter_dict((frappe.model.get_doc(doctype, parent)[parentfield] || []), filters); | |||||
} | } | ||||
if(l.length) { | |||||
l.sort(function(a,b) { return flt(a.idx) - flt(b.idx) }); | |||||
// renumber | |||||
$.each(l, function(i, v) { v.idx = i+1; }); // for chrome bugs ??? | |||||
} | |||||
return l; | |||||
}, | |||||
clear_doclist: function(doctype, name) { | |||||
$.each(frappe.model.get_doclist(doctype, name), function(i, d) { | |||||
if(d) frappe.model.clear_doc(d.doctype, d.name); | |||||
}); | |||||
}, | }, | ||||
clear_table: function(doctype, parenttype, parent, parentfield) { | clear_table: function(doctype, parenttype, parent, parentfield) { | ||||
@@ -337,7 +298,7 @@ $.extend(frappe.model, { | |||||
}, | }, | ||||
remove_from_locals: function(doctype, name) { | remove_from_locals: function(doctype, name) { | ||||
this.clear_doclist(doctype, name); | |||||
this.clear_doc(doctype, name); | |||||
if(frappe.views.formview[doctype]) { | if(frappe.views.formview[doctype]) { | ||||
delete frappe.views.formview[doctype].frm.opendocs[name]; | delete frappe.views.formview[doctype].frm.opendocs[name]; | ||||
} | } | ||||
@@ -358,13 +319,14 @@ $.extend(frappe.model, { | |||||
get_no_copy_list: function(doctype) { | get_no_copy_list: function(doctype) { | ||||
var no_copy_list = ['name','amended_from','amendment_date','cancel_reason']; | var no_copy_list = ['name','amended_from','amendment_date','cancel_reason']; | ||||
$.each(frappe.model.get("DocField", {parent:doctype}), function(i, df) { | |||||
$.each(frappe.model.get_doc("DocType", doctype).fields || [], function(i, df) { | |||||
if(cint(df.no_copy)) no_copy_list.push(df.fieldname); | if(cint(df.no_copy)) no_copy_list.push(df.fieldname); | ||||
}) | }) | ||||
return no_copy_list; | return no_copy_list; | ||||
}, | }, | ||||
// args: source (doclist), target (doctype), table_map, field_map, callback | |||||
// args: source (doc), target (doc), table_map, field_map, callback | |||||
map: function(args) { | map: function(args) { | ||||
frappe.model.with_doctype(args.target, function() { | frappe.model.with_doctype(args.target, function() { | ||||
var map_info = frappe.model.map_info[args.target] | var map_info = frappe.model.map_info[args.target] | ||||
@@ -436,7 +398,7 @@ $.extend(frappe.model, { | |||||
}, | }, | ||||
callback: function(r, rt) { | callback: function(r, rt) { | ||||
if(!r.exc) { | if(!r.exc) { | ||||
frappe.model.clear_doclist(doctype, docname); | |||||
frappe.model.clear_doc(doctype, docname); | |||||
if(frappe.ui.toolbar.recent) | if(frappe.ui.toolbar.recent) | ||||
frappe.ui.toolbar.recent.remove(doctype, docname); | frappe.ui.toolbar.recent.remove(doctype, docname); | ||||
if(callback) callback(r,rt); | if(callback) callback(r,rt); | ||||
@@ -499,9 +461,20 @@ $.extend(frappe.model, { | |||||
frappe.throw(frappe._("Please specify") + ": " + | frappe.throw(frappe._("Please specify") + ": " + | ||||
frappe._(frappe.meta.get_label(doc.doctype, fieldname, doc.parent || doc.name))); | frappe._(frappe.meta.get_label(doc.doctype, fieldname, doc.parent || doc.name))); | ||||
} | } | ||||
}, | |||||
get_all_docs: function(doc) { | |||||
var all = [doc]; | |||||
for(key in doc) { | |||||
if($.isArray(doc[key])) { | |||||
$.each(doc[key], function(i, d) { | |||||
all.push(d); | |||||
}); | |||||
} | |||||
} | |||||
return all; | |||||
} | } | ||||
}); | }); | ||||
// legacy | // legacy | ||||
getchildren = frappe.model.get_children | getchildren = frappe.model.get_children | ||||
make_doclist = frappe.model.get_doclist |
@@ -38,17 +38,9 @@ $.extend(frappe.perm, { | |||||
var perm = [{read: 0}]; | var perm = [{read: 0}]; | ||||
var meta = frappe.model.get_doc("DocType", doctype); | var meta = frappe.model.get_doc("DocType", doctype); | ||||
if(!meta) { | if(!meta) { | ||||
return perm; | return perm; | ||||
} else if(meta.istable) { | |||||
// if a child table, use permissions of parent form | |||||
var parent_df = frappe.model.get("DocField", {fieldtype: "Table", options: doctype}); | |||||
if(parent_df.length) { | |||||
if(docname) { | |||||
docname = frappe.model.get_doc(doctype, docname).parent; | |||||
} | |||||
doctype = parent_df[0].parent; | |||||
} | |||||
} | } | ||||
if(user==="Administrator" || user_roles.indexOf("Administrator")!==-1) { | if(user==="Administrator" || user_roles.indexOf("Administrator")!==-1) { | ||||
@@ -60,7 +52,7 @@ $.extend(frappe.perm, { | |||||
return perm; | return perm; | ||||
} | } | ||||
var docperms = frappe.model.get("DocPerm", {parent: doctype}); | |||||
var docperms = frappe.model.get_doc("DocType", doctype).permissions || []; | |||||
$.each(docperms, function(i, p) { | $.each(docperms, function(i, p) { | ||||
// if user has this role | // if user has this role | ||||
if(user_roles.indexOf(p.role)!==-1) { | if(user_roles.indexOf(p.role)!==-1) { | ||||
@@ -5,35 +5,21 @@ $.extend(frappe.model, { | |||||
docinfo: {}, | docinfo: {}, | ||||
sync: function(r) { | sync: function(r) { | ||||
/* docs: | /* docs: | ||||
extract doclist, docinfo (attachments, comments, assignments) | |||||
extract docs, docinfo (attachments, comments, assignments) | |||||
from incoming request and set in `locals` and `frappe.model.docinfo` | from incoming request and set in `locals` and `frappe.model.docinfo` | ||||
*/ | */ | ||||
if(!r.docs && !r.docinfo) r = {docs:r}; | if(!r.docs && !r.docinfo) r = {docs:r}; | ||||
if(r.docs) { | if(r.docs) { | ||||
var doclist = r.docs; | |||||
if(doclist._kl) | |||||
doclist = frappe.model.expand(doclist); | |||||
if(doclist && doclist.length) | |||||
frappe.model.clear_doclist(doclist[0].doctype, doclist[0].name) | |||||
var last_parent_name = null; | var last_parent_name = null; | ||||
var dirty = []; | var dirty = []; | ||||
$.each(doclist, function(i, d) { | |||||
$.each(r.docs, function(i, d) { | |||||
if(!d.name && d.__islocal) { // get name (local if required) | if(!d.name && d.__islocal) { // get name (local if required) | ||||
frappe.model.clear_doc(d) | |||||
d.name = frappe.model.get_new_name(d.doctype); | d.name = frappe.model.get_new_name(d.doctype); | ||||
frappe.provide("frappe.model.docinfo." + d.doctype + "." + d.name); | frappe.provide("frappe.model.docinfo." + d.doctype + "." + d.name); | ||||
if(!d.parenttype) | |||||
last_parent_name = d.name; | |||||
if(dirty.indexOf(d.parenttype || d.doctype)===-1) dirty.push(d.parenttype || d.doctype); | |||||
} | |||||
// set parent for subsequent orphans | |||||
if(d.parenttype && !d.parent && d.__islocal) { | |||||
d.parent = last_parent_name; | |||||
} | } | ||||
if(!locals[d.doctype]) | if(!locals[d.doctype]) | ||||
@@ -41,14 +27,15 @@ $.extend(frappe.model, { | |||||
locals[d.doctype][d.name] = d; | locals[d.doctype][d.name] = d; | ||||
d.__last_sync_on = new Date(); | d.__last_sync_on = new Date(); | ||||
if(d.doctype==="DocType") { | |||||
frappe.meta.sync(d); | |||||
} | |||||
if(cur_frm && cur_frm.doctype==d.doctype && cur_frm.docname==d.name) { | if(cur_frm && cur_frm.doctype==d.doctype && cur_frm.docname==d.name) { | ||||
cur_frm.doc = d; | cur_frm.doc = d; | ||||
} | } | ||||
if(d.doctype=='DocField') frappe.meta.add_field(d); | |||||
if(d.doctype=='DocType') frappe.meta.sync_messages(d); | |||||
if(d.localname) { | if(d.localname) { | ||||
frappe.model.new_names[d.localname] = d.name; | frappe.model.new_names[d.localname] = d.name; | ||||
$(document).trigger('rename', [d.doctype, d.localname, d.name]); | $(document).trigger('rename', [d.doctype, d.localname, d.name]); | ||||
@@ -66,10 +53,10 @@ $.extend(frappe.model, { | |||||
} | } | ||||
// set docinfo | |||||
// set docinfo (comments, assign, attachments) | |||||
if(r.docinfo) { | if(r.docinfo) { | ||||
if(doclist) { | |||||
var doc = doclist[0]; | |||||
if(r.docs) { | |||||
var doc = r.docs[0]; | |||||
} else { | } else { | ||||
var doc = cur_frm.doc; | var doc = cur_frm.doc; | ||||
} | } | ||||
@@ -78,68 +65,7 @@ $.extend(frappe.model, { | |||||
frappe.model.docinfo[doc.doctype][doc.name] = r.docinfo; | frappe.model.docinfo[doc.doctype][doc.name] = r.docinfo; | ||||
} | } | ||||
return doclist; | |||||
return r.docs; | |||||
}, | }, | ||||
expand: function(data) { | |||||
function zip(k,v) { | |||||
var obj = {}; | |||||
for(var i=0;i<k.length;i++) { | |||||
obj[k[i]] = v[i]; | |||||
} | |||||
return obj; | |||||
} | |||||
var l = []; | |||||
for(var i=0;i<data._vl.length;i++) { | |||||
l.push(zip(data._kl[data._vl[i][0]], data._vl[i])); | |||||
} | |||||
return l; | |||||
}, | |||||
compress: function(doclist) { | |||||
var all_keys = {}; var values = []; | |||||
function get_key_list(doctype) { | |||||
// valid standard keys | |||||
var key_list = ['doctype', 'name', 'docstatus', 'owner', 'parent', | |||||
'parentfield', 'parenttype', 'idx', 'creation', 'modified', | |||||
'modified_by', '__islocal', '__newname', '__modified', | |||||
'_user_tags', '__temp', '_comments']; | |||||
for(key in frappe.meta.docfield_map[doctype]) { // all other values | |||||
if(!in_list(key_list, key) | |||||
&& !in_list(frappe.model.no_value_type, frappe.meta.docfield_map[doctype][key].fieldtype) | |||||
&& !frappe.meta.docfield_map[doctype][key].no_column) { | |||||
key_list[key_list.length] = key | |||||
} | |||||
} | |||||
return key_list; | |||||
} | |||||
for(var i=0; i<doclist.length;i++) { | |||||
var doc = doclist[i]; | |||||
// make keys | |||||
if(!all_keys[doc.doctype]) { | |||||
all_keys[doc.doctype] = get_key_list(doc.doctype); | |||||
// doctype must be first | |||||
} | |||||
var row = [] | |||||
var key_list = all_keys[doc.doctype]; | |||||
// make data rows | |||||
for(var j=0;j<key_list.length;j++) { | |||||
row.push(doc[key_list[j]]); | |||||
} | |||||
values.push(row); | |||||
} | |||||
return JSON.stringify({'_vl':values, '_kl':all_keys}); | |||||
} | |||||
}); | }); | ||||
// legacy | |||||
compress_doclist = frappe.model.compress; |
@@ -23,31 +23,19 @@ frappe.workflow = { | |||||
}, | }, | ||||
get_default_state: function(doctype) { | get_default_state: function(doctype) { | ||||
frappe.workflow.setup(doctype); | frappe.workflow.setup(doctype); | ||||
return frappe.model.get("Workflow Document State", { | |||||
parent: frappe.workflow.workflows[doctype].name, | |||||
idx: 1 | |||||
})[0].state; | |||||
return frappe.workflow.workflows[doctype].workflow_document_states[0].state; | |||||
}, | }, | ||||
get_transitions: function(doctype, state) { | get_transitions: function(doctype, state) { | ||||
frappe.workflow.setup(doctype); | frappe.workflow.setup(doctype); | ||||
return frappe.model.get("Workflow Transition", { | |||||
parent: frappe.workflow.workflows[doctype].name, | |||||
state: state | |||||
}); | |||||
return frappe.model.get_children(frappe.workflow.workflows[doctype], "workflow_transitions", {state:state}); | |||||
}, | }, | ||||
get_document_state: function(doctype, state) { | get_document_state: function(doctype, state) { | ||||
frappe.workflow.setup(doctype); | frappe.workflow.setup(doctype); | ||||
return frappe.model.get("Workflow Document State", { | |||||
parent: frappe.workflow.workflows[doctype].name, | |||||
state: state | |||||
})[0]; | |||||
return frappe.model.get_children(frappe.workflow.workflows[doctype], "workflow_document_states", {state:state})[0]; | |||||
}, | }, | ||||
get_next_state: function(doctype, state, action) { | get_next_state: function(doctype, state, action) { | ||||
return frappe.model.get("Workflow Transition", { | |||||
parent: frappe.workflow.workflows[doctype].name, | |||||
state: state, | |||||
action: action | |||||
})[0].next_state; | |||||
return frappe.model.get_children(frappe.workflow.workflows[doctype], "workflow_transitions", { | |||||
state:state, action:action})[0].next_state; | |||||
}, | }, | ||||
is_read_only: function(doctype, name) { | is_read_only: function(doctype, name) { | ||||
var state_fieldname = frappe.workflow.get_state_fieldname(doctype); | var state_fieldname = frappe.workflow.get_state_fieldname(doctype); | ||||
@@ -60,13 +48,7 @@ frappe.workflow = { | |||||
var state = locals[doctype][name][state_fieldname] || | var state = locals[doctype][name][state_fieldname] || | ||||
frappe.workflow.get_default_state(doctype); | frappe.workflow.get_default_state(doctype); | ||||
var workflow_doc_state = frappe.model.get("Workflow Document State", | |||||
{ | |||||
parent: frappe.workflow.workflows[doctype].name, | |||||
state: state | |||||
}); | |||||
var allow_edit = workflow_doc_state.length ? | |||||
workflow_doc_state[0].allow_edit : null; | |||||
var allow_edit = state ? frappe.workflow.get_document_state(doctype, state).allow_edit : null; | |||||
if(user_roles.indexOf(allow_edit)==-1) { | if(user_roles.indexOf(allow_edit)==-1) { | ||||
return true; | return true; | ||||
@@ -75,8 +57,8 @@ frappe.workflow = { | |||||
return false; | return false; | ||||
}, | }, | ||||
get_update_fields: function(doctype) { | get_update_fields: function(doctype) { | ||||
var update_fields = $.unique($.map(frappe.model.get("Workflow Document State", | |||||
{parent:frappe.workflow.workflows[doctype].name}), function(d) { | |||||
var update_fields = $.unique($.map(frappe.workflow.workflows[doctype].workflow_document_states || [], | |||||
function(d) { | |||||
return d.update_field; | return d.update_field; | ||||
})); | })); | ||||
return update_fields; | return update_fields; | ||||
@@ -16,8 +16,7 @@ frappe.call = function(opts) { | |||||
} else if(opts.doc) { | } else if(opts.doc) { | ||||
$.extend(args, { | $.extend(args, { | ||||
cmd: "runserverobj", | cmd: "runserverobj", | ||||
docs: frappe.model.compress(frappe.model.get_doclist(opts.doc.doctype, | |||||
opts.doc.name)), | |||||
docs: frappe.model.get_doc(opts.doc.doctype, opts.doc.name), | |||||
method: opts.method, | method: opts.method, | ||||
args: opts.args, | args: opts.args, | ||||
}); | }); | ||||
@@ -337,13 +337,13 @@ frappe.views.ReportView = frappe.ui.Listing.extend({ | |||||
callback: function(r) { | callback: function(r) { | ||||
if(!r.exc) { | if(!r.exc) { | ||||
d.hide(); | d.hide(); | ||||
var doclist = r.message; | |||||
var doc = r.message; | |||||
$.each(me.dataView.getItems(), function(i, item) { | $.each(me.dataView.getItems(), function(i, item) { | ||||
if (item.name === doclist[0].name) { | |||||
var new_item = $.extend({}, item, doclist[0]); | |||||
$.each(doclist, function(i, doc) { | |||||
if(item[doc.doctype + ":name"]===doc.name) { | |||||
$.each(doc, function(k, v) { | |||||
if (item.name === doc.name) { | |||||
var new_item = $.extend({}, item); | |||||
$.each(frappe.model.get_all_docs(doc), function(i, d) { | |||||
if(item[d.doctype + ":name"]===d.name) { | |||||
$.each(d, function(k, v) { | |||||
if(frappe.model.std_fields_list.indexOf(k)===-1) { | if(frappe.model.std_fields_list.indexOf(k)===-1) { | ||||
new_item[k] = v; | new_item[k] = v; | ||||
} | } | ||||
@@ -4,10 +4,7 @@ | |||||
get_server_fields = function(method, arg, table_field, doc, dt, dn, allow_edit, call_back) { | get_server_fields = function(method, arg, table_field, doc, dt, dn, allow_edit, call_back) { | ||||
frappe.dom.freeze(); | frappe.dom.freeze(); | ||||
return $c('runserverobj', | return $c('runserverobj', | ||||
args={'method':method, | |||||
'docs':frappe.model.compress(make_doclist(doc.doctype, doc.name)), | |||||
'arg':arg | |||||
}, | |||||
args={'method': method, 'docs': doc, 'arg': arg }, | |||||
function(r, rt) { | function(r, rt) { | ||||
frappe.dom.unfreeze(); | frappe.dom.unfreeze(); | ||||
if (r.message) { | if (r.message) { | ||||
@@ -125,10 +122,6 @@ _f.Frm.prototype.get_doc = function() { | |||||
return locals[this.doctype][this.docname]; | return locals[this.doctype][this.docname]; | ||||
} | } | ||||
_f.Frm.prototype.get_doclist = function(filters) { | |||||
return frappe.model.get_doclist(this.doctype, this.docname, filters); | |||||
} | |||||
_f.Frm.prototype.field_map = function(fnames, fn) { | _f.Frm.prototype.field_map = function(fnames, fn) { | ||||
if(typeof fnames==='string') { | if(typeof fnames==='string') { | ||||
if(fnames == '*') { | if(fnames == '*') { | ||||
@@ -170,7 +163,7 @@ _f.Frm.prototype.toggle_display = function(fnames, show) { | |||||
} | } | ||||
_f.Frm.prototype.call_server = function(method, args, callback) { | _f.Frm.prototype.call_server = function(method, args, callback) { | ||||
return $c_obj(cur_frm.get_doclist(), method, args, callback); | |||||
return $c_obj(cur_frm.doc, method, args, callback); | |||||
} | } | ||||
_f.Frm.prototype.get_files = function() { | _f.Frm.prototype.get_files = function() { | ||||
@@ -548,13 +548,11 @@ _f.Frm.prototype.setnewdoc = function() { | |||||
_f.Frm.prototype.runscript = function(scriptname, callingfield, onrefresh) { | _f.Frm.prototype.runscript = function(scriptname, callingfield, onrefresh) { | ||||
var me = this; | var me = this; | ||||
if(this.docname) { | if(this.docname) { | ||||
// make doc list | |||||
var doclist = frappe.model.compress(make_doclist(this.doctype, this.docname)); | |||||
// send to run | // send to run | ||||
if(callingfield) | if(callingfield) | ||||
$(callingfield.input).set_working(); | $(callingfield.input).set_working(); | ||||
return $c('runserverobj', {'docs':doclist, 'method':scriptname }, | |||||
return $c('runserverobj', {'docs':this.doc, 'method':scriptname }, | |||||
function(r, rtxt) { | function(r, rtxt) { | ||||
// run refresh | // run refresh | ||||
if(onrefresh) | if(onrefresh) | ||||
@@ -577,45 +575,10 @@ _f.Frm.prototype.copy_doc = function(onload, from_amend) { | |||||
return; | return; | ||||
} | } | ||||
var dn = this.docname; | |||||
// copy parent | |||||
var newdoc = frappe.model.copy_doc(this.doctype, dn, from_amend); | |||||
newdoc.idx = null; | |||||
// copy chidren | |||||
var dl = make_doclist(this.doctype, dn); | |||||
// table fields dict - for no_copy check | |||||
var tf_dict = {}; | |||||
for(var d in dl) { | |||||
d1 = dl[d]; | |||||
// get tabel field | |||||
if(d1.parentfield && !tf_dict[d1.parentfield]) { | |||||
tf_dict[d1.parentfield] = frappe.meta.get_docfield(d1.parenttype, d1.parentfield); | |||||
} | |||||
if(d1.parent==dn && cint(tf_dict[d1.parentfield].no_copy)!=1) { | |||||
var ch = frappe.model.copy_doc(d1.doctype, d1.name, from_amend); | |||||
ch.parent = newdoc.name; | |||||
ch.docstatus = 0; | |||||
ch.owner = user; | |||||
ch.creation = ''; | |||||
ch.modified_by = user; | |||||
ch.modified = ''; | |||||
} | |||||
} | |||||
newdoc.__islocal = 1; | |||||
newdoc.docstatus = 0; | |||||
newdoc.owner = user; | |||||
newdoc.creation = ''; | |||||
newdoc.modified_by = user; | |||||
newdoc.modified = ''; | |||||
var newdoc = frappe.model.copy_doc(this.doc, from_amend); | |||||
newdoc.idx = null; | |||||
if(onload)onload(newdoc); | if(onload)onload(newdoc); | ||||
loaddoc(newdoc.doctype, newdoc.name); | loaddoc(newdoc.doctype, newdoc.name); | ||||
} | } | ||||
@@ -651,19 +614,15 @@ _f.Frm.prototype._save = function(save_action, callback, btn, on_error) { | |||||
scroll(0, 0); | scroll(0, 0); | ||||
// validate | // validate | ||||
if(save_action!="Cancel") { | |||||
validated = true; | |||||
this.script_manager.trigger("validate"); | |||||
if(!validated) { | |||||
if(on_error) | |||||
on_error(); | |||||
return; | |||||
} | |||||
validated = true; | |||||
this.script_manager.trigger("validate"); | |||||
if(!validated) { | |||||
if(on_error) | |||||
on_error(); | |||||
return; | |||||
} | } | ||||
var doclist = new frappe.model.DocList(this.doctype, this.docname); | |||||
doclist.save(save_action || "Save", function(r) { | |||||
var after_save = function(r) { | |||||
if(!r.exc) { | if(!r.exc) { | ||||
me.refresh(); | me.refresh(); | ||||
} else { | } else { | ||||
@@ -680,7 +639,9 @@ _f.Frm.prototype._save = function(save_action, callback, btn, on_error) { | |||||
} | } | ||||
frappe._from_link = null; | frappe._from_link = null; | ||||
} | } | ||||
}, btn); | |||||
} | |||||
frappe.ui.form.save(this, save_action || "Save", after_save, btn); | |||||
} | } | ||||
@@ -713,14 +674,16 @@ _f.Frm.prototype.savecancel = function(btn, on_error) { | |||||
on_error(); | on_error(); | ||||
return; | return; | ||||
} | } | ||||
var doclist = new frappe.model.DocList(me.doctype, me.docname); | |||||
doclist.cancel(function(r) { | |||||
var after_cancel = function(r) { | |||||
if(!r.exc) { | if(!r.exc) { | ||||
me.refresh(); | me.refresh(); | ||||
me.script_manager.trigger("after_cancel"); | me.script_manager.trigger("after_cancel"); | ||||
} else { | |||||
on_error(); | |||||
} | } | ||||
}, btn, on_error); | |||||
} | |||||
frappe.ui.form.save(this, "cancel", after_cancel, btn); | |||||
}); | }); | ||||
} | } | ||||
@@ -13,7 +13,7 @@ function $c(command, args, callback, error, no_spinner, freeze_msg, btn) { | |||||
} | } | ||||
// For calling an object | // For calling an object | ||||
function $c_obj(doclist, method, arg, callback, no_spinner, freeze_msg, btn) { | |||||
function $c_obj(doc, method, arg, callback, no_spinner, freeze_msg, btn) { | |||||
if(arg && typeof arg!='string') arg = JSON.stringify(arg); | if(arg && typeof arg!='string') arg = JSON.stringify(arg); | ||||
args = { | args = { | ||||
@@ -22,10 +22,11 @@ function $c_obj(doclist, method, arg, callback, no_spinner, freeze_msg, btn) { | |||||
method: method | method: method | ||||
}; | }; | ||||
if(typeof doclist=='string') | |||||
args.doctype = doclist; | |||||
else | |||||
args.docs = frappe.model.compress(doclist) | |||||
if(typeof doc=='string') { | |||||
args.doctype = doc; | |||||
} else { | |||||
args.docs = doc | |||||
} | |||||
return frappe.request.call({ | return frappe.request.call({ | ||||
args: args, | args: args, | ||||
@@ -53,7 +54,7 @@ function $c_page(module, page, method, arg, callback, no_spinner, freeze_msg, bt | |||||
} | } | ||||
// For calling an for output as csv | // For calling an for output as csv | ||||
function $c_obj_csv(doclist, method, arg) { | |||||
function $c_obj_csv(doc, method, arg) { | |||||
// single | // single | ||||
var args = {} | var args = {} | ||||
@@ -62,10 +63,10 @@ function $c_obj_csv(doclist, method, arg) { | |||||
args.method = method; | args.method = method; | ||||
args.arg = arg; | args.arg = arg; | ||||
if(doclist.substr) | |||||
args.doctype = doclist; | |||||
if(doc.substr) | |||||
args.doctype = doc; | |||||
else | else | ||||
args.docs = frappe.model.compress(doclist); | |||||
args.docs = doc; | |||||
// open | // open | ||||
open_url_post(frappe.request.url, args); | open_url_post(frappe.request.url, args); | ||||
@@ -120,5 +120,6 @@ class TestDocument(unittest.TestCase): | |||||
d.starts_on = "2014-01-01" | d.starts_on = "2014-01-01" | ||||
d.ends_on = "2013-01-01" | d.ends_on = "2013-01-01" | ||||
self.assertRaises(frappe.ValidationError, d.validate) | self.assertRaises(frappe.ValidationError, d.validate) | ||||
self.assertRaises(frappe.ValidationError, d.run_method, "validate") | |||||
self.assertRaises(frappe.ValidationError, d.save) | self.assertRaises(frappe.ValidationError, d.save) | ||||
@@ -0,0 +1,16 @@ | |||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||||
# MIT License. See license.txt | |||||
import frappe, unittest | |||||
from frappe.widgets.form.meta import get_meta | |||||
from frappe.widgets.form.load import getdoctype, getdoc | |||||
class TestFormLoad(unittest.TestCase): | |||||
def test_load(self): | |||||
getdoctype("DocType") | |||||
self.assertEquals(frappe.response.docs[0].name, "DocType") | |||||
self.assertTrue(frappe.response.docs[0].get("__js")) | |||||
frappe.response.docs = [] | |||||
d = getdoctype("Event") | |||||
self.assertTrue(frappe.response.docs[0].get("__calendar_js")) |
@@ -9,7 +9,8 @@ import mimetypes | |||||
import os | import os | ||||
import frappe | import frappe | ||||
from frappe import _ | from frappe import _ | ||||
from frappe.model.doc import Document | |||||
import frappe.model.doc | |||||
import frappe.model.document | |||||
import frappe.utils | import frappe.utils | ||||
import frappe.sessions | import frappe.sessions | ||||
import frappe.model.utils | import frappe.model.utils | ||||
@@ -28,6 +29,9 @@ def report_error(status_code): | |||||
return response | return response | ||||
def build_response(response_type=None): | def build_response(response_type=None): | ||||
if "docs" in frappe.local.response and not frappe.local.response.docs: | |||||
del frappe.local.response["docs"] | |||||
response_type_map = { | response_type_map = { | ||||
'csv': as_csv, | 'csv': as_csv, | ||||
'download': as_raw, | 'download': as_raw, | ||||
@@ -54,7 +58,6 @@ def as_raw(): | |||||
def as_json(): | def as_json(): | ||||
make_logs() | make_logs() | ||||
cleanup_docs() | |||||
response = Response() | response = Response() | ||||
response.headers["Content-Type"] = "application/json; charset: utf-8" | response.headers["Content-Type"] = "application/json; charset: utf-8" | ||||
response = gzip(json.dumps(frappe.local.response, default=json_handler, separators=(',',':')), | response = gzip(json.dumps(frappe.local.response, default=json_handler, separators=(',',':')), | ||||
@@ -68,14 +71,11 @@ def make_logs(): | |||||
frappe.response['exc'] = json.dumps([frappe.utils.cstr(d) for d in frappe.local.error_log]) | frappe.response['exc'] = json.dumps([frappe.utils.cstr(d) for d in frappe.local.error_log]) | ||||
if frappe.local.message_log: | if frappe.local.message_log: | ||||
frappe.response['_server_messages'] = json.dumps([frappe.utils.cstr(d) for d in frappe.local.message_log]) | |||||
frappe.response['_server_messages'] = json.dumps([frappe.utils.cstr(d) for | |||||
d in frappe.local.message_log]) | |||||
if frappe.debug_log and frappe.conf.get("logging") or False: | if frappe.debug_log and frappe.conf.get("logging") or False: | ||||
frappe.response['_debug_messages'] = json.dumps(frappe.local.debug_log) | frappe.response['_debug_messages'] = json.dumps(frappe.local.debug_log) | ||||
def cleanup_docs(): | |||||
if frappe.response.get('docs') and type(frappe.response['docs'])!=dict: | |||||
frappe.response['docs'] = frappe.model.utils.compress(frappe.response['docs']) | |||||
def gzip(data, response): | def gzip(data, response): | ||||
data = data.encode('utf-8') | data = data.encode('utf-8') | ||||
@@ -107,8 +107,10 @@ def json_handler(obj): | |||||
return unicode(obj) | return unicode(obj) | ||||
elif isinstance(obj, LocalProxy): | elif isinstance(obj, LocalProxy): | ||||
return unicode(obj) | return unicode(obj) | ||||
elif isinstance(obj, Document): | |||||
elif isinstance(obj, frappe.model.doc.Document): | |||||
return obj.fields | return obj.fields | ||||
elif isinstance(obj, frappe.model.document.Document): | |||||
return obj.as_dict() | |||||
else: | else: | ||||
raise TypeError, """Object of type %s with value of %s is not JSON serializable""" % \ | raise TypeError, """Object of type %s with value of %s is not JSON serializable""" % \ | ||||
(type(obj), repr(obj)) | (type(obj), repr(obj)) | ||||
@@ -5,7 +5,7 @@ cur_frm.cscript.refresh = function(doc) { | |||||
if(!doc.__islocal && doc.published) { | if(!doc.__islocal && doc.published) { | ||||
if(!doc.email_sent) { | if(!doc.email_sent) { | ||||
cur_frm.add_custom_button('Email Subscribers', function() { | cur_frm.add_custom_button('Email Subscribers', function() { | ||||
$c_obj(make_doclist(doc.doctype, doc.name), 'send_emails', '', function(r) { | |||||
$c_obj(doc, 'send_emails', '', function(r) { | |||||
cur_frm.refresh(); | cur_frm.refresh(); | ||||
}); | }); | ||||
}); | }); | ||||
@@ -5,6 +5,7 @@ from __future__ import unicode_literals | |||||
import frappe, json | import frappe, json | ||||
import frappe.model.doc | import frappe.model.doc | ||||
import frappe.utils | import frappe.utils | ||||
import frappe.widgets.form.meta | |||||
@frappe.whitelist() | @frappe.whitelist() | ||||
def getdoc(doctype, name, user=None): | def getdoc(doctype, name, user=None): | ||||
@@ -13,8 +14,6 @@ def getdoc(doctype, name, user=None): | |||||
Requries "doctype", "name" as form variables. | Requries "doctype", "name" as form variables. | ||||
Will also call the "onload" method on the document. | Will also call the "onload" method on the document. | ||||
""" | """ | ||||
import frappe | |||||
if not (doctype and name): | if not (doctype and name): | ||||
raise Exception, 'doctype and name required!' | raise Exception, 'doctype and name required!' | ||||
@@ -26,14 +25,12 @@ def getdoc(doctype, name, user=None): | |||||
return [] | return [] | ||||
try: | try: | ||||
bean = frappe.bean(doctype, name) | |||||
bean.run_method("onload") | |||||
doc = frappe.get_doc(doctype, name) | |||||
doc.run_method("onload") | |||||
if not bean.has_read_perm(): | |||||
if not doc.has_permission("read"): | |||||
raise frappe.PermissionError | raise frappe.PermissionError | ||||
doclist = bean.doclist | |||||
# add file list | # add file list | ||||
get_docinfo(doctype, name) | get_docinfo(doctype, name) | ||||
@@ -42,35 +39,38 @@ def getdoc(doctype, name, user=None): | |||||
frappe.msgprint('Did not load.') | frappe.msgprint('Did not load.') | ||||
raise | raise | ||||
if bean and not name.startswith('_'): | |||||
if doc and not name.startswith('_'): | |||||
frappe.user.update_recent(doctype, name) | frappe.user.update_recent(doctype, name) | ||||
frappe.response['docs'] = doclist | |||||
frappe.response.docs.append(doc) | |||||
@frappe.whitelist() | @frappe.whitelist() | ||||
def getdoctype(doctype, with_parent=False, cached_timestamp=None): | def getdoctype(doctype, with_parent=False, cached_timestamp=None): | ||||
"""load doctype""" | """load doctype""" | ||||
import frappe.model.doctype | |||||
import frappe.model.meta | |||||
doclist = [] | |||||
docs = [] | |||||
# with parent (called from report builder) | # with parent (called from report builder) | ||||
if with_parent: | if with_parent: | ||||
parent_dt = frappe.model.meta.get_parent_dt(doctype) | parent_dt = frappe.model.meta.get_parent_dt(doctype) | ||||
if parent_dt: | if parent_dt: | ||||
doclist = frappe.model.doctype.get(parent_dt, processed=True) | |||||
docs = get_meta_bundle(parent_dt) | |||||
frappe.response['parent_dt'] = parent_dt | frappe.response['parent_dt'] = parent_dt | ||||
if not doclist: | |||||
doclist = frappe.model.doctype.get(doctype, processed=True) | |||||
if not docs: | |||||
docs = get_meta_bundle(doctype) | |||||
frappe.response['restrictions'] = get_restrictions(doclist) | |||||
frappe.response['restrictions'] = get_restrictions(docs[0]) | |||||
if cached_timestamp and doclist[0].modified==cached_timestamp: | |||||
if cached_timestamp and docs[0].modified==cached_timestamp: | |||||
return "use_cache" | return "use_cache" | ||||
frappe.response['docs'] = doclist | |||||
frappe.response.docs.extend(docs) | |||||
def get_meta_bundle(doctype): | |||||
bundle = [frappe.widgets.form.meta.get_meta(doctype)] | |||||
for df in bundle[0].get_table_fields(): | |||||
bundle.append(frappe.widgets.form.meta.get_meta(df.options)) | |||||
return bundle | |||||
def get_docinfo(doctype, name): | def get_docinfo(doctype, name): | ||||
frappe.response["docinfo"] = { | frappe.response["docinfo"] = { | ||||
@@ -0,0 +1,157 @@ | |||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||||
# MIT License. See license.txt | |||||
# metadata | |||||
from __future__ import unicode_literals | |||||
import frappe, os | |||||
from frappe.utils import cstr, cint | |||||
from frappe.model.meta import Meta | |||||
from frappe.modules import scrub, get_module_path | |||||
from frappe.model.workflow import get_workflow_name | |||||
###### | |||||
def get_meta(doctype, cached=True): | |||||
if cached: | |||||
meta = frappe.cache().get_value("form_meta:" + doctype, lambda: FormMeta(doctype)) | |||||
else: | |||||
meta = FormMeta(doctype) | |||||
if frappe.local.lang != 'en': | |||||
meta.set("__messages", frappe.get_lang_dict("doctype", doctype)) | |||||
return meta | |||||
class FormMeta(Meta): | |||||
def __init__(self, doctype): | |||||
super(FormMeta, self).__init__(doctype) | |||||
self.load_assets() | |||||
def load_assets(self): | |||||
self.expand_selects() | |||||
self.add_search_fields() | |||||
if not self.istable: | |||||
self.add_linked_with() | |||||
self.add_code() | |||||
self.load_print_formats() | |||||
self.load_workflows() | |||||
def as_dict(self): | |||||
d = super(FormMeta, self).as_dict() | |||||
for k in ("__js", "__css", "__list_js", "__calendar_js", "__map_js", "__linked_with", "__messages"): | |||||
d[k] = self.get(k) | |||||
for i, df in enumerate(d.get("fields")): | |||||
for k in ("link_doctype", "search_fields"): | |||||
df[k] = self.get("fields")[i].get(k) | |||||
return d | |||||
def add_code(self): | |||||
path = os.path.join(get_module_path(self.module), 'doctype', scrub(self.name)) | |||||
def _get_path(fname): | |||||
return os.path.join(path, scrub(fname)) | |||||
self._add_code(_get_path(self.name + '.js'), '__js') | |||||
self._add_code(_get_path(self.name + '.css'), "__css") | |||||
self._add_code(_get_path(self.name + '_list.js'), '__list_js') | |||||
self._add_code(_get_path(self.name + '_calendar.js'), '__calendar_js') | |||||
self._add_code(_get_path(self.name + '_map.js'), '__map_js') | |||||
self.add_custom_script() | |||||
self.add_code_via_hook("doctype_js", "__js") | |||||
def _add_code(self, path, fieldname): | |||||
js = frappe.read_file(path) | |||||
if js: | |||||
self.set(fieldname, (self.get(fieldname) or "") + "\n\n" + render_jinja(js)) | |||||
def add_code_via_hook(self, hook, fieldname): | |||||
hook = "{}:{}".format(hook, self.name) | |||||
for app_name in frappe.get_installed_apps(): | |||||
for file in frappe.get_hooks(hook, app_name=app_name): | |||||
path = frappe.get_app_path(app_name, *file.strip("/").split("/")) | |||||
self._add_code(path, fieldname) | |||||
def add_custom_script(self): | |||||
"""embed all require files""" | |||||
# custom script | |||||
custom = frappe.db.get_value("Custom Script", {"dt": self.name, | |||||
"script_type": "Client"}, "script") or "" | |||||
self.set("__js", (self.get('__js') or '') + "\n\n" + custom) | |||||
def render_jinja(content): | |||||
if "{% include" in content: | |||||
content = frappe.get_jenv().from_string(content).render() | |||||
return content | |||||
def expand_selects(self): | |||||
for df in self.get("fields", {"fieldtype": "Select"}): | |||||
if df.options and df.options.startswith("link:"): | |||||
df.link_doctype = df.options.split("\n")[0][5:] | |||||
df.options = '\n'.join([''] + [o.name for o in frappe.db.sql("""select | |||||
name from `tab%s` where docstatus<2 order by name asc""" % df.link_doctype, as_dict=1)]) | |||||
def add_search_fields(self): | |||||
"""add search fields found in the doctypes indicated by link fields' options""" | |||||
for df in self.get("fields", {"fieldtype": "Link", "options":["!=", "[Select]"]}): | |||||
if df.options: | |||||
search_fields = frappe.get_meta(df.options).search_fields | |||||
if search_fields: | |||||
df.search_fields = map(lambda sf: sf.strip(), search_fields.split(",")) | |||||
def add_linked_with(self): | |||||
"""add list of doctypes this doctype is 'linked' with""" | |||||
links = frappe.db.sql("""select parent, fieldname from tabDocField | |||||
where (fieldtype="Link" and options=%s) | |||||
or (fieldtype="Select" and options=%s)""", (self.name, "link:"+ self.name)) | |||||
links += frappe.db.sql("""select dt as parent, fieldname from `tabCustom Field` | |||||
where (fieldtype="Link" and options=%s) | |||||
or (fieldtype="Select" and options=%s)""", (self.name, "link:"+ self.name)) | |||||
links = dict(links) | |||||
if not links: | |||||
return {} | |||||
ret = {} | |||||
for dt in links: | |||||
ret[dt] = { "fieldname": links[dt] } | |||||
for grand_parent, options in frappe.db.sql("""select parent, options from tabDocField | |||||
where fieldtype="Table" | |||||
and options in (select name from tabDocType | |||||
where istable=1 and name in (%s))""" % ", ".join(["%s"] * len(links)) ,tuple(links)): | |||||
ret[grand_parent] = {"child_doctype": options, "fieldname": links[options] } | |||||
if options in ret: | |||||
del ret[options] | |||||
self.set("__linked_with", ret) | |||||
def load_print_formats(self): | |||||
frappe.response.docs.extend(frappe.db.sql("""select * FROM `tabPrint Format` | |||||
WHERE doc_type=%s AND docstatus<2""", (self.name,), as_dict=1, update={"doctype":"Print Format"})) | |||||
def load_workflows(self): | |||||
# get active workflow | |||||
workflow_name = get_workflow_name(self.name) | |||||
if workflow_name and frappe.db.exists("Workflow", workflow_name): | |||||
workflow = frappe.get_doc("Workflow", workflow_name) | |||||
frappe.response.docs.append(workflow) | |||||
for d in workflow.get("workflow_document_states"): | |||||
frappe.response.docs.append(frappe.get_doc("Workflow State", d.state)) | |||||
def render_jinja(content): | |||||
if "{% include" in content: | |||||
content = frappe.get_jenv().from_string(content).render() | |||||
return content | |||||
@@ -20,8 +20,6 @@ def runserverobj(): | |||||
dt = frappe.form_dict.get('doctype') | dt = frappe.form_dict.get('doctype') | ||||
dn = frappe.form_dict.get('docname') | dn = frappe.form_dict.get('docname') | ||||
frappe.response["docs"] = [] | |||||
if dt: # not called from a doctype (from a page) | if dt: # not called from a doctype (from a page) | ||||
if not dn: dn = dt # single | if not dn: dn = dt # single | ||||
so = frappe.model.code.get_obj(dt, dn) | so = frappe.model.code.get_obj(dt, dn) | ||||
@@ -112,8 +112,6 @@ def get_linked_docs(doctype, name, metadata_loaded=None): | |||||
results[dt] = ret | results[dt] = ret | ||||
if not dt in metadata_loaded: | if not dt in metadata_loaded: | ||||
if not "docs" in frappe.local.response: | |||||
frappe.local.response.docs = [] | |||||
frappe.local.response.docs += linkmeta | frappe.local.response.docs += linkmeta | ||||
return results | return results |
@@ -11,14 +11,14 @@ def get(name): | |||||
""" | """ | ||||
Return the :term:`doclist` of the `Page` specified by `name` | Return the :term:`doclist` of the `Page` specified by `name` | ||||
""" | """ | ||||
page = frappe.bean("Page", name) | |||||
if has_permission(page.doclist): | |||||
page.run_method("get_from_files") | |||||
return page.doclist | |||||
page = frappe.get_doc('Page', name) | |||||
if has_permission(page): | |||||
page.load_assets() | |||||
return page | |||||
else: | else: | ||||
frappe.response['403'] = 1 | frappe.response['403'] = 1 | ||||
raise frappe.PermissionError, 'No read permission for Page %s' % \ | raise frappe.PermissionError, 'No read permission for Page %s' % \ | ||||
(page.doclist[0].title or name,) | |||||
(page.title or name) | |||||
@frappe.whitelist(allow_guest=True) | @frappe.whitelist(allow_guest=True) | ||||
def getpage(): | def getpage(): | ||||
@@ -26,24 +26,19 @@ def getpage(): | |||||
Load the page from `frappe.form` and send it via `frappe.response` | Load the page from `frappe.form` and send it via `frappe.response` | ||||
""" | """ | ||||
page = frappe.form_dict.get('name') | page = frappe.form_dict.get('name') | ||||
doclist = get(page) | |||||
doc = get(page) | |||||
if has_permission(doclist): | |||||
# load translations | |||||
if frappe.lang != "en": | |||||
frappe.response["__messages"] = frappe.get_lang_dict("page", page) | |||||
# load translations | |||||
if frappe.lang != "en": | |||||
frappe.response["__messages"] = frappe.get_lang_dict("page", page) | |||||
frappe.response['docs'] = doclist | |||||
else: | |||||
frappe.response['403'] = 1 | |||||
raise frappe.PermissionError, 'No read permission for Page %s' % \ | |||||
(doclist[0].title or page, ) | |||||
def has_permission(page_doclist): | |||||
frappe.response.docs.append(doc) | |||||
def has_permission(page): | |||||
if frappe.user.name == "Administrator" or "System Manager" in frappe.user.get_roles(): | if frappe.user.name == "Administrator" or "System Manager" in frappe.user.get_roles(): | ||||
return True | return True | ||||
page_roles = [d.role for d in page_doclist if d.fields.get("doctype")=="Page Role"] | |||||
page_roles = [d.role for d in page.get("roles")] | |||||
if page_roles: | if page_roles: | ||||
if frappe.session.user == "Guest" and "Guest" not in page_roles: | if frappe.session.user == "Guest" and "Guest" not in page_roles: | ||||
return False | return False | ||||
@@ -51,7 +46,7 @@ def has_permission(page_doclist): | |||||
# check if roles match | # check if roles match | ||||
return False | return False | ||||
if not frappe.has_permission("Page", ptype="read", refdoc=page_doclist[0].name): | |||||
if not frappe.has_permission("Page", ptype="read", doc=page): | |||||
# check if there are any restrictions | # check if there are any restrictions | ||||
return False | return False | ||||
else: | else: | ||||