Commit 0ece804c authored by Anand Doshi's avatar Anand Doshi
Browse files

[fix] Linked With should also search in Dynamic Links. Fixes #1192

parent cf25e466
develop v11.1.5 v11.1.4 v11.1.3 v11.1.2 v11.1.1 v11.1.0 v11.0.3 v11.0.3-beta.51 v11.0.3-beta.50 v11.0.3-beta.49 v11.0.3-beta.48 v11.0.3-beta.47 v11.0.3-beta.46 v11.0.3-beta.45 v11.0.3-beta.44 v11.0.3-beta.43 v11.0.3-beta.42 v11.0.3-beta.41 v11.0.3-beta.40 v11.0.3-beta.39 v11.0.3-beta.38 v11.0.3-beta.37 v11.0.3-beta.36 v11.0.3-beta.35 v11.0.3-beta.34 v11.0.3-beta.33 v11.0.3-beta.32 v11.0.3-beta.31 v11.0.3-beta.30 v11.0.3-beta.29 v11.0.3-beta.28 v11.0.3-beta.27 v11.0.3-beta.26 v11.0.3-beta.25 v11.0.3-beta.24 v11.0.3-beta.23 v11.0.3-beta.22 v11.0.3-beta.21 v11.0.3-beta.20 v11.0.3-beta.19 v11.0.3-beta.18 v11.0.3-beta.17 v11.0.3-beta.16 v11.0.3-beta.15 v11.0.3-beta.14 v11.0.3-beta.13 v11.0.3-beta.12 v11.0.3-beta.11 v11.0.3-beta.10 v11.0.3-beta.9 v11.0.3-beta.8 v11.0.3-beta.7 v11.0.3-beta.6 v11.0.3-beta.5 v11.0.3-beta.4 v11.0.3-beta.3 v11.0.3-beta.2 v11.0.3-beta.1 v11.0.2 v11.0.1 v11.0.0-beta v10.1.71 v10.1.70 v10.1.69 v10.1.68 v10.1.67 v10.1.66 v10.1.65 v10.1.64 v10.1.63 v10.1.62 v10.1.61 v10.1.60 v10.1.59 v10.1.58 v10.1.57 v10.1.56 v10.1.55 v10.1.54 v10.1.53 v10.1.52 v10.1.51 v10.1.50 v10.1.49 v10.1.49-beta.1 v10.1.48 v10.1.47 v10.1.46 v10.1.45 v10.1.44 v10.1.43 v10.1.42 v10.1.41 v10.1.40 v10.1.39 v10.1.38 v10.1.37 v10.1.36 v10.1.35 v10.1.34 v10.1.33 v10.1.32 v10.1.31 v10.1.30 v10.1.29 v10.1.28 v10.1.27 v10.1.26 v10.1.25 v10.1.24 v10.1.23 v10.1.22 v10.1.21 v10.1.20 v10.1.19 v10.1.18 v10.1.17 v10.1.16 v10.1.15 v10.1.14 v10.1.13 v10.1.12 v10.1.11 v10.1.10 v10.1.9 v10.1.8 v10.1.7 v10.1.6 v10.1.5 v10.1.4 v10.1.3 v10.1.2 v10.1.1 v10.1.0 v10.0.25 v10.0.24 v10.0.23 v10.0.22 v10.0.21 v10.0.20 v10.0.19 v10.0.18 v10.0.17 v10.0.16 v10.0.15 v10.0.14 v10.0.13 v10.0.12 v10.0.11 v10.0.10 v10.0.9 v10.0.8 v10.0.7 v10.0.6 v10.0.5 v10.0.4 v10.0.3 v10.0.2 v10.0.1 v10.0.0 v9.2.25 v9.2.24 v9.2.23 v9.2.22 v9.2.21 v9.2.20 v9.2.19 v9.2.18 v9.2.17 v9.2.16 v9.2.15 v9.2.14 v9.2.13 v9.2.12 v9.2.11 v9.2.10 v9.2.9 v9.2.8 v9.2.7 v9.2.6 v9.2.5 v9.2.4 v9.2.3 v9.2.2 v9.2.1 v9.2.0 v9.1.11 v9.1.10 v9.1.9 v9.1.8 v9.1.7 v9.1.6 v9.1.5 v9.1.4 v9.1.3 v9.1.2 v9.1.1 v9.1.0 v9.0.10 v9.0.9 v9.0.8 v9.0.7 v9.0.6 v9.0.5 v9.0.4 v9.0.3 v9.0.2 v9.0.1 v9.0.0 v8.10.9 v8.10.8 v8.10.7 v8.10.6 v8.10.5 v8.10.4 v8.10.3 v8.10.2 v8.10.1 v8.10.0 v8.9.4 v8.9.3 v8.9.2 v8.9.1 v8.9.0 v8.8.5 v8.8.4 v8.8.3 v8.8.2 v8.8.1 v8.8.0 v8.7.11 v8.7.10 v8.7.9 v8.7.8 v8.7.7 v8.7.6 v8.7.5 v8.7.4 v8.7.3 v8.7.2 v8.7.1 v8.7.0 v8.6.8 v8.6.7 v8.6.6 v8.6.5 v8.6.4 v8.6.3 v8.6.2 v8.6.1 v8.6.0 v8.5.8 v8.5.7 v8.5.6 v8.5.5 v8.5.4 v8.5.3 v8.5.2 v8.5.1 v8.5.0 v8.4.1 v8.4.0 v8.3.10 v8.3.9 v8.3.8 v8.3.7 v8.3.6 v8.3.5 v8.3.4 v8.3.3 v8.3.2 v8.3.1 v8.3.0 v8.2.7 v8.2.6 v8.2.5 v8.2.4 v8.2.3 v8.2.2 v8.2.1 v8.2.0 v8.1.4 v8.1.3 v8.1.2 v8.1.1 v8.1.0 v8.0.71 v8.0.70 v8.0.69 v8.0.68 v8.0.67 v8.0.66 v8.0.65 v8.0.64 v8.0.63 v8.0.62 v8.0.61 v8.0.60 v8.0.59 v8.0.58 v8.0.57 v8.0.56 v8.0.55 v8.0.54 v8.0.53 v8.0.52 v8.0.51 v8.0.50 v8.0.49 v8.0.48 v8.0.47 v8.0.46 v8.0.45 v8.0.44 v8.0.43 v8.0.42 v8.0.41 v8.0.40 v8.0.39 v8.0.38 v8.0.37 v8.0.36 v8.0.35 v8.0.34 v8.0.33 v8.0.32 v8.0.31 v8.0.30 v8.0.29 v8.0.28 v8.0.27 v8.0.26 v8.0.25 v8.0.24 v8.0.23 v8.0.22 v8.0.21 v8.0.20 v8.0.19 v8.0.18 v8.0.17 v8.0.16 v8.0.15 v8.0.14 v8.0.13 v8.0.12 v8.0.11 v8.0.10 v8.0.9 v8.0.8 v8.0.7 v8.0.6 v8.0.5 v8.0.4 v8.0.3 v8.0.2 v8.0.1 v8.0.0 v7.2.31 v7.2.30 v7.2.29 v7.2.28 v7.2.27 v7.2.26 v7.2.25 v7.2.24 v7.2.23 v7.2.22 v7.2.21 v7.2.20 v7.2.19 v7.2.18 v7.2.17 v7.2.16 v7.2.15 v7.2.14 v7.2.13 v7.2.12 v7.2.11 v7.2.10 v7.2.9 v7.2.8 v7.2.7 v7.2.6 v7.2.5 v7.2.4 v7.2.3 v7.2.2 v7.2.1 v7.2.0 v7.1.29 v7.1.28 v7.1.27 v7.1.26 v7.1.25 v7.1.24 v7.1.23 v7.1.22 v7.1.21 v7.1.20 v7.1.19 v7.1.18 v7.1.17 v7.1.16 v7.1.15 v7.1.14 v7.1.13 v7.1.12 v7.1.11 v7.1.10 v7.1.9 v7.1.8 v7.1.7 v7.1.6 v7.1.5 v7.1.4 v7.1.3 v7.1.2 v7.1.1 v7.1.0 v7.0.47 v7.0.46 v7.0.45 v7.0.44 v7.0.43 v7.0.42 v7.0.41 v7.0.40 v7.0.39 v7.0.38 v7.0.37 v7.0.36 v7.0.35 v7.0.34 v7.0.33 v7.0.32 v7.0.31 v7.0.30 v7.0.29 v7.0.28 v7.0.27 v7.0.26 v7.0.25 v7.0.24 v7.0.23 v7.0.22 v7.0.21 v7.0.20 v7.0.19 v7.0.18 v7.0.17 v7.0.16 v7.0.15 v7.0.14 v7.0.13 v7.0.12 v7.0.11 v7.0.10 v7.0.9 v7.0.8 v7.0.7 v7.0.6 v7.0.5 v7.0.4 v7.0.3 v7.0.2 v7.0.1 v7.0.0 v6.27.24 v6.27.23 v6.27.22 v6.27.21 v6.27.20 v6.27.19 v6.27.18 v6.27.17 v6.27.16 v6.27.15 v6.27.14 v6.27.13 v6.27.12 v6.27.11 v6.27.10 v6.27.9 v6.27.8 v6.27.7 v6.27.6 v6.27.5 v6.27.4 v6.27.3 v6.27.2 v6.27.1 v6.27.0 v6.26.6 v6.26.5 v6.26.4 v6.26.3 v6.26.2 v6.26.1 v6.26.0 v6.25.6 v6.25.5 v6.25.4 v6.25.3 v6.25.2 v6.25.1 v6.25.0 v6.24.10 v6.24.9 v6.24.8 v6.24.7 v6.24.6 v6.24.5 v6.24.4 v6.24.3 v6.24.2 v6.24.1 v6.24.0 v6.23.3 v6.23.2 v6.23.1 v6.23.0 v6.22.7 v6.22.6 v6.22.5 v6.22.4 v6.22.3 v6.22.2 v6.22.1 v6.22.0 v6.21.0 v6.20.2 v6.20.1 v6.20.0 v6.19.3 v6.19.2 v6.19.1 v6.19.0 v6.18.1 v6.18.0 v6.17.6 v6.17.5 v6.17.4 v6.17.3 v6.17.2 v6.17.1 v6.17.0 v6.16.4 v6.16.3 v6.16.2 v6.16.1 v6.16.0 v6.15.4 v6.15.3 v6.15.2 v6.15.1 v6.15.0 v6.14.1 v6.14.0 v6.13.5 v6.13.4 v6.13.3 v6.13.2 v6.13.1 v6.13.0 v6.12.4 v6.12.3 v6.12.2 v6.12.1 v6.12.0 v6.11.0 v6.10.4 v6.10.3 v6.10.2 v6.10.1 v6.10.0 v6.9.3 v6.9.2 v6.9.1 v6.9.0 v6.8.2 v6.8.1 v6.8.0 v6.7.11 v6.7.10 v6.7.9 v6.7.8 v6.7.7 v6.7.6 v6.7.5 v6.7.4 v6.7.3 v6.7.2 v6.7.1 v6.7.0 v6.6.5 v6.6.4 v6.6.3 v6.6.2 v6.6.1 v6.6.0 v6.5.4 v6.5.3 v6.5.2 v6.5.1 v6.5.0
No related merge requests found
Showing with 293 additions and 147 deletions
+293 -147
......@@ -9,6 +9,8 @@ from frappe.model.document import Document
from frappe.model.db_schema import add_column
from frappe.utils import get_fullname
exclude_from_linked_with = True
class Comment(Document):
"""Comments are added to Documents via forms or views like blogs etc."""
no_feed_on_delete = True
......
......@@ -7,6 +7,8 @@ from frappe.model.document import Document
from frappe import _
from frappe.utils import get_fullname
exclude_from_linked_with = True
class DocShare(Document):
no_feed_on_delete = True
......
......@@ -17,6 +17,8 @@ import json
class FolderNotEmpty(frappe.ValidationError): pass
exclude_from_linked_with = True
class File(NestedSet):
nsm_parent_field = 'folder'
no_feed_on_delete = True
......
......@@ -9,6 +9,8 @@ from frappe.model.document import Document
from frappe.utils import get_fullname
from frappe import _
exclude_from_linked_with = True
class Feed(Document):
pass
......
......@@ -10,6 +10,7 @@ from frappe.utils import get_fullname
subject_field = "description"
sender_field = "sender"
exclude_from_linked_with = True
class ToDo(Document):
def validate(self):
......
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
from __future__ import unicode_literals
import frappe, json
from frappe.model.meta import is_single
from frappe.modules import load_doctype_module
import frappe.desk.form.meta
import frappe.desk.form.load
@frappe.whitelist()
def get_linked_docs(doctype, name, linkinfo):
meta = frappe.desk.form.meta.get_meta(doctype)
results = {}
if isinstance(linkinfo, basestring):
# additional fields are added in linkinfo
linkinfo = json.loads(linkinfo)
if not linkinfo:
return results
me = frappe.db.get_value(doctype, name, ["parenttype", "parent"], as_dict=True)
for dt, link in linkinfo.items():
link["doctype"] = dt
link_meta_bundle = frappe.desk.form.load.get_meta_bundle(dt)
linkmeta = link_meta_bundle[0]
if not linkmeta.get("issingle"):
fields = [d.fieldname for d in linkmeta.get("fields", {"in_list_view":1,
"fieldtype": ["not in", ["Image", "HTML", "Button", "Table"]]})] \
+ ["name", "modified", "docstatus"]
if link.get("add_fields"):
fields += link["add_fields"]
fields = ["`tab{dt}`.`{fn}`".format(dt=dt, fn=sf.strip()) for sf in fields if sf
and "`tab" not in sf]
try:
if link.get("get_parent"):
if me and me.parent and me.parenttype == dt:
ret = frappe.get_list(doctype=dt, fields=fields,
filters=[[dt, "name", '=', me.parent]])
else:
ret = None
elif link.get("child_doctype"):
filters = [[link.get('child_doctype'), link.get("fieldname"), '=', name]]
# dynamic link
if link.get("doctype_fieldname"):
filters.append([link.get('child_doctype'), link.get("doctype_fieldname"), "=", doctype])
ret = frappe.get_list(doctype=dt, fields=fields, filters=filters)
else:
filters = [[dt, link.get("fieldname"), '=', name]]
# dynamic link
if link.get("doctype_fieldname"):
filters.append([dt, link.get("doctype_fieldname"), "=", doctype])
ret = frappe.get_list(doctype=dt, fields=fields, filters=filters)
except frappe.PermissionError:
if frappe.local.message_log:
frappe.local.message_log.pop()
continue
if ret:
results[dt] = ret
return results
@frappe.whitelist()
def get_linked_doctypes(doctype):
"""add list of doctypes this doctype is 'linked' with.
Example, for Customer:
{"Address": {"fieldname": "customer"}..}
"""
return frappe.cache().hget("linked_doctypes", doctype, lambda: _get_linked_doctypes(doctype))
def _get_linked_doctypes(doctype):
ret = {}
# find fields where this doctype is linked
ret.update(get_linked_fields(doctype))
ret.update(get_dynamic_linked_fields(doctype))
# find links of parents
links = frappe.db.sql("""select dt from `tabCustom Field`
where (fieldtype="Table" and options=%s)""", (doctype))
links += frappe.db.sql("""select parent from tabDocField
where (fieldtype="Table" and options=%s)""", (doctype))
for dt, in links:
if not dt in ret:
ret[dt] = {"get_parent": True}
for dt in ret.keys():
doctype_module = load_doctype_module(dt)
if getattr(doctype_module, "exclude_from_linked_with", False):
del ret[dt]
return ret
def get_linked_fields(doctype):
links = frappe.db.sql("""select parent, fieldname from tabDocField
where (fieldtype="Link" and options=%s)
or (fieldtype="Select" and options=%s)""", (doctype, "link:"+ doctype))
links += frappe.db.sql("""select dt as parent, fieldname from `tabCustom Field`
where (fieldtype="Link" and options=%s)
or (fieldtype="Select" and options=%s)""", (doctype, "link:"+ doctype))
links = dict(links)
ret = {}
if links:
for dt in links:
ret[dt] = { "fieldname": links[dt] }
# find out if linked in a child table
for 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[parent] = {"child_doctype": options, "fieldname": links[options] }
if options in ret:
del ret[options]
return ret
def get_dynamic_linked_fields(doctype):
ret = {}
links = frappe.db.sql("""select parent as doctype, fieldname, options as doctype_fieldname
from `tabDocField` where fieldtype='Dynamic Link'""", as_dict=True)
links += frappe.db.sql("""select dt as doctype, fieldname, options as doctype_fieldname
from `tabCustom Field` where fieldtype='Dynamic Link'""", as_dict=True)
for df in links:
if is_single(df.doctype):
continue
# optimized to get both link exists and parenttype
possible_link = frappe.db.sql("""select distinct `{doctype_fieldname}`, parenttype
from `tab{doctype}` where `{doctype_fieldname}`=%s""".format(**df), doctype, as_dict=True)
if possible_link:
for d in possible_link:
# is child
if d.parenttype:
ret[d.parenttype] = {
"child_doctype": df.doctype,
"fieldname": df.fieldname,
"doctype_fieldname": df.doctype_fieldname
}
else:
ret[df.doctype] = {
"fieldname": df.fieldname,
"doctype_fieldname": df.doctype_fieldname
}
return ret
......@@ -36,7 +36,6 @@ class FormMeta(Meta):
self.add_linked_document_type()
if not self.istable:
self.add_linked_with()
self.add_code()
self.load_print_formats()
self.load_workflows()
......@@ -130,52 +129,6 @@ class FormMeta(Meta):
# edge case where options="[Select]"
pass
def add_linked_with(self):
"""add list of doctypes this doctype is 'linked' with.
Example, for Customer:
{"Address": {"fieldname": "customer"}..}
"""
# find fields where this doctype is linked
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)
ret = {}
for dt in links:
ret[dt] = { "fieldname": links[dt] }
if links:
# find out if linked in a child table
for 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[parent] = {"child_doctype": options, "fieldname": links[options] }
if options in ret:
del ret[options]
# find links of parents
links = frappe.db.sql("""select dt from `tabCustom Field`
where (fieldtype="Table" and options=%s)""", (self.name))
links += frappe.db.sql("""select parent from tabDocField
where (fieldtype="Table" and options=%s)""", (self.name))
for dt, in links:
if not dt in ret:
ret[dt] = {"get_parent": True}
self.set("__linked_with", ret, as_value=True)
def load_print_formats(self):
print_formats = frappe.db.sql("""select * FROM `tabPrint Format`
WHERE doc_type=%s AND docstatus<2 and ifnull(disabled, 0)=0""", (self.name,), as_dict=1,
......
......@@ -105,54 +105,3 @@ def get_next(doctype, value, prev, filters=None, order_by="modified desc"):
else:
return res[0][0]
@frappe.whitelist()
def get_linked_docs(doctype, name, metadata_loaded=None, no_metadata=False):
if not metadata_loaded: metadata_loaded = []
meta = frappe.desk.form.meta.get_meta(doctype)
linkinfo = meta.get("__linked_with")
results = {}
if not linkinfo:
return results
me = frappe.db.get_value(doctype, name, ["parenttype", "parent"], as_dict=True)
for dt, link in linkinfo.items():
link["doctype"] = dt
link_meta_bundle = frappe.desk.form.load.get_meta_bundle(dt)
linkmeta = link_meta_bundle[0]
if not linkmeta.get("issingle"):
fields = [d.fieldname for d in linkmeta.get("fields", {"in_list_view":1,
"fieldtype": ["not in", ["Image", "HTML", "Button", "Table"]]})] \
+ ["name", "modified", "docstatus"]
fields = ["`tab{dt}`.`{fn}`".format(dt=dt, fn=sf.strip()) for sf in fields if sf]
try:
if link.get("get_parent"):
if me and me.parent and me.parenttype == dt:
ret = frappe.get_list(doctype=dt, fields=fields,
filters=[[dt, "name", '=', me.parent]])
else:
ret = None
elif link.get("child_doctype"):
ret = frappe.get_list(doctype=dt, fields=fields,
filters=[[link.get('child_doctype'), link.get("fieldname"), '=', name]])
else:
ret = frappe.get_list(doctype=dt, fields=fields,
filters=[[dt, link.get("fieldname"), '=', name]])
except frappe.PermissionError:
if frappe.local.message_log:
frappe.local.message_log.pop()
continue
if ret:
results[dt] = ret
if not no_metadata and not dt in metadata_loaded:
frappe.local.response.docs.extend(link_meta_bundle)
return results
......@@ -619,6 +619,10 @@ class Document(BaseDocument):
self.run_method("on_update_after_submit")
frappe.cache().hdel("last_modified", self.doctype)
# to clear linked_with_doctypes of others
frappe.cache().hdel("linked_with_doctypes", self.doctype)
self.notify_update()
self.latest = None
......
......@@ -332,7 +332,7 @@ def clear_cache(doctype=None):
frappe.cache().delete_value("is_table")
frappe.cache().delete_value("doctype_modules")
groups = ["meta", "form_meta", "table_columns", "last_modified"]
groups = ["meta", "form_meta", "table_columns", "last_modified", "linked_doctypes"]
def clear_single(dt):
for name in groups:
......
......@@ -16,16 +16,6 @@ frappe.ui.form.LinkedWith = Class.extend({
},
make_dialog: function() {
var me = this;
this.linked_with = this.frm.meta.__linked_with;
var links = [];
$.each(this.linked_with, function(doctype, tmp) {
if(frappe.model.can_get_report(doctype)) {
links.push({label: __(doctype), value: doctype});
}
});
links = frappe.utils.sort(links, "label");
this.dialog = new frappe.ui.Dialog({
hide_on_page_refresh: true,
......@@ -37,49 +27,119 @@ frappe.ui.form.LinkedWith = Class.extend({
this.dialog.$wrapper.find(".modal-dialog").addClass("linked-with-dialog");
if(!links) {
this.dialog.fields_dict.list.$wrapper.html("<div class='alert alert-warning'>"
+ this.frm.doctype + ": "
+ (this.linked_with ? __("Not Linked to any record.") : __("Not enough permission to see links."))
+ "</div>")
return;
}
this.dialog.on_page_show = function() {
me.dialog.fields_dict.list.$wrapper.html('<div class="text-muted text-center">'
+ __("Loading") + '...</div>');
frappe.call({
method:"frappe.desk.form.utils.get_linked_docs",
args: {
doctype: me.frm.doctype,
name: me.frm.docname,
metadata_loaded: keys(locals.DocType)
},
callback: function(r) {
var parent = me.dialog.fields_dict.list.$wrapper.empty();
if(keys(r.message || {}).length) {
$.each(keys(r.message).sort(), function(i, doctype) {
var listview = frappe.views.get_listview(doctype, me);
listview.no_delete = true;
var wrapper = $('<div class="panel panel-default"><div>').appendTo(parent);
$('<div class="panel-heading">').html(__(doctype).bold()).appendTo(wrapper);
var body = $('<div class="panel-body">').appendTo(wrapper);
$.each(r.message[doctype], function(i, d) {
d.doctype = doctype;
listview.render($('<div class="list-row"></div>')
.appendTo(body), d, me);
})
})
} else {
parent.html(__("Not Linked to any record."));
// execute ajax calls sequentially
// 1. get linked doctypes
// 2. load all doctypes
// 3. load linked docs
$.when(me.get_linked_doctypes())
.then(function() { return me.load_doctypes() })
.then(function() {
if (me.links_not_permitted_or_missing()) {
return;
}
return me.get_linked_docs();
});
}
},
load_doctypes: function() {
var me = this;
var already_loaded = Object.keys(locals.DocType);
var doctypes_to_load = [];
$.each(Object.keys(me.frm.__linked_doctypes), function(i, v) {
if (already_loaded.indexOf(v)===-1) {
doctypes_to_load.push(v);
}
});
// load all doctypes sequentially using with_doctype
return $.when.apply($, $.map(doctypes_to_load, function(dt) {
return frappe.model.with_doctype(dt, function() {
if (frappe.listview_settings[dt]) {
// add additional fields to __linked_doctypes
me.frm.__linked_doctypes[dt].add_fields = frappe.listview_settings[dt].add_fields;
}
})
});
}));
},
links_not_permitted_or_missing: function() {
var me = this;
var links = [];
$.each(me.frm.__linked_doctypes, function(doctype, tmp) {
if(frappe.model.can_get_report(doctype)) {
links.push({label: __(doctype), value: doctype});
}
});
links = frappe.utils.sort(links, "label");
if(!links) {
me.dialog.fields_dict.list.$wrapper.html("<div class='alert alert-warning'>"
+ me.frm.doctype + ": "
+ (me.frm.__linked_doctypes ? __("Not Linked to any record.") : __("Not enough permission to see links."))
+ "</div>")
return true;
}
return false;
},
get_linked_doctypes: function() {
var me = this;
if (this.frm.__linked_doctypes) {
return;
}
return frappe.call({
method: "frappe.desk.form.linked_with.get_linked_doctypes",
args: {
doctype: this.frm.doctype
},
callback: function(r) {
me.frm.__linked_doctypes = r.message;
}
});
},
get_linked_docs: function() {
var me = this;
return frappe.call({
method:"frappe.desk.form.linked_with.get_linked_docs",
args: {
doctype: me.frm.doctype,
name: me.frm.docname,
linkinfo: me.frm.__linked_doctypes
},
callback: function(r) {
var parent = me.dialog.fields_dict.list.$wrapper.empty();
if(keys(r.message || {}).length) {
$.each(keys(r.message).sort(), function(i, doctype) {
var listview = frappe.views.get_listview(doctype, me);
listview.no_delete = true;
var wrapper = $('<div class="panel panel-default"><div>').appendTo(parent);
$('<div class="panel-heading">').html(__(doctype).bold()).appendTo(wrapper);
var body = $('<div class="panel-body">').appendTo(wrapper);
$.each(r.message[doctype], function(i, d) {
d.doctype = doctype;
listview.render($('<div class="list-row"></div>')
.appendTo(body), d, me);
})
})
} else {
parent.html(__("Not Linked to any record."));
}
}
});
}
});
......@@ -83,7 +83,7 @@ $.extend(frappe.model, {
with_doctype: function(doctype, callback) {
if(locals.DocType[doctype]) {
callback();
callback && callback();
} else {
var cached_timestamp = null;
if(localStorage["_doctype:" + doctype]) {
......@@ -112,7 +112,7 @@ $.extend(frappe.model, {
}
frappe.model.init_doctype(doctype);
frappe.defaults.set_user_permissions(r.user_permissions);
callback(r);
callback && callback(r);
}
});
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment