Ver código fonte

fixes

version-14
Rushabh Mehta 11 anos atrás
pai
commit
9aa3d1c53c
7 arquivos alterados com 111 adições e 103 exclusões
  1. +12
    -13
      frappe/core/doctype/page/page.py
  2. +1
    -1
      frappe/core/page/data_import_tool/data_import_tool.py
  3. +8
    -2
      frappe/model/base_document.py
  4. +19
    -17
      frappe/utils/response.py
  5. +38
    -38
      frappe/website/js/website.js
  6. +4
    -2
      frappe/website/sitemap.py
  7. +29
    -30
      frappe/widgets/form/meta.py

+ 12
- 13
frappe/core/doctype/page/page.py Ver arquivo

@@ -1,5 +1,5 @@
# 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


from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
@@ -17,7 +17,7 @@ class Page(Document):
self.name = self.page_name.lower().replace('"','').replace("'",'').\ self.name = self.page_name.lower().replace('"','').replace("'",'').\
replace(' ', '-')[:20] replace(' ', '-')[:20]
if frappe.db.exists('Page',self.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.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
@@ -34,29 +34,29 @@ class Page(Document):
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, "roles") make_module_and_roles(self, "roles")
if not frappe.flags.in_import and getattr(conf,'developer_mode', 0) and self.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.name]]) export_to_files(record_list=[['Page', self.name]])
# write files # write files
path = os.path.join(get_module_path(self.module), 'page', scrub(self.name), scrub(self.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'):
with open(path + '.js', 'w') as f: with open(path + '.js', 'w') as f:
f.write("""frappe.pages['%s'].onload = function(wrapper) {
f.write("""frappe.pages['%s'].onload = function(wrapper) {
frappe.ui.make_app_page({ frappe.ui.make_app_page({
parent: wrapper, parent: wrapper,
title: '%s', title: '%s',
single_column: true single_column: true
});
});
}""" % (self.name, self.title)) }""" % (self.name, self.title))


def as_dict(self):
d = super(Page, self).as_dict()
def as_dict(self, no_nulls=False):
d = super(Page, self).as_dict(no_nulls=no_nulls)
for key in ("script", "style", "content"): for key in ("script", "style", "content"):
d[key] = self.get(key) d[key] = self.get(key)
return d return d
@@ -64,7 +64,7 @@ class Page(Document):
def load_assets(self): 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.module), 'page', scrub(self.name)) path = os.path.join(get_module_path(self.module), 'page', scrub(self.name))


# script # script
@@ -78,14 +78,13 @@ class Page(Document):
if os.path.exists(fpath): if os.path.exists(fpath):
with open(fpath, 'r') as f: with open(fpath, 'r') as f:
self.style = f.read() self.style = f.read()
# html # html
fpath = os.path.join(path, scrub(self.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.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.script += get_lang_js("page", self.name) self.script += get_lang_js("page", self.name)

+ 1
- 1
frappe/core/page/data_import_tool/data_import_tool.py Ver arquivo

@@ -54,7 +54,7 @@ def export_json(doctype, name, path):
d.set("parent", None) d.set("parent", None)
d.set("name", None) d.set("name", None)
d.set("__islocal", 1) d.set("__islocal", 1)
outfile.write(json.dumps([d], default=json_handler, indent=1, sort_keys=True))
outfile.write(json.dumps(doc, default=json_handler, indent=1, sort_keys=True))


@frappe.whitelist() @frappe.whitelist()
def export_fixture(doctype, name, app): def export_fixture(doctype, name, app):


+ 8
- 2
frappe/model/base_document.py Ver arquivo

@@ -138,12 +138,18 @@ class BaseDocument(object):
def is_new(self): def is_new(self):
return self.get("__islocal") return self.get("__islocal")


def as_dict(self):
def as_dict(self, no_nulls=False):
doc = self.get_valid_dict() doc = self.get_valid_dict()
doc["doctype"] = self.doctype doc["doctype"] = self.doctype
for df in self.meta.get_table_fields(): for df in self.meta.get_table_fields():
children = self.get(df.fieldname) or [] children = self.get(df.fieldname) or []
doc[df.fieldname] = [d.as_dict() for d in children]
doc[df.fieldname] = [d.as_dict(no_nulls=no_nulls) for d in children]

if no_nulls:
for k in doc.keys():
if doc[k] is None:
del doc[k]

return doc return doc


def get_table_field_doctype(self, fieldname): def get_table_field_doctype(self, fieldname):


+ 19
- 17
frappe/utils/response.py Ver arquivo

@@ -1,5 +1,5 @@
# 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


from __future__ import unicode_literals from __future__ import unicode_literals
import json import json
@@ -22,7 +22,7 @@ from werkzeug.exceptions import NotFound, Forbidden
def report_error(status_code): def report_error(status_code):
if status_code!=404 or frappe.conf.logging: if status_code!=404 or frappe.conf.logging:
frappe.errprint(frappe.utils.get_traceback()) frappe.errprint(frappe.utils.get_traceback())
response = build_response("json") response = build_response("json")
response.status_code = status_code response.status_code = status_code
return response return response
@@ -30,7 +30,7 @@ def report_error(status_code):
def build_response(response_type=None): def build_response(response_type=None):
if "docs" in frappe.local.response and not frappe.local.response.docs: if "docs" in frappe.local.response and not frappe.local.response.docs:
del 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,
@@ -38,9 +38,9 @@ def build_response(response_type=None):
'page': as_page, 'page': as_page,
'redirect': redirect 'redirect': redirect
} }
return response_type_map[frappe.response.get('type') or response_type]() return response_type_map[frappe.response.get('type') or response_type]()
def as_csv(): def as_csv():
response = Response() response = Response()
response.headers["Content-Type"] = "text/csv; charset: utf-8" response.headers["Content-Type"] = "text/csv; charset: utf-8"
@@ -62,7 +62,7 @@ def as_json():
response = gzip(json.dumps(frappe.local.response, default=json_handler, separators=(',',':')), response = gzip(json.dumps(frappe.local.response, default=json_handler, separators=(',',':')),
response=response) response=response)
return response return response
def make_logs(): def make_logs():
"""make strings for msgprint and errprint""" """make strings for msgprint and errprint"""
if frappe.error_log: if frappe.error_log:
@@ -72,21 +72,21 @@ def make_logs():
if frappe.local.message_log: if frappe.local.message_log:
frappe.response['_server_messages'] = json.dumps([frappe.utils.cstr(d) for frappe.response['_server_messages'] = json.dumps([frappe.utils.cstr(d) for
d in frappe.local.message_log]) 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 gzip(data, response): def gzip(data, response):
data = data.encode('utf-8') data = data.encode('utf-8')
orig_len = len(data) orig_len = len(data)
if accept_gzip() and orig_len>512: if accept_gzip() and orig_len>512:
data = compressBuf(data) data = compressBuf(data)
response.headers["Content-Encoding"] = "gzip" response.headers["Content-Encoding"] = "gzip"
response.headers["Content-Length"] = str(len(data)) response.headers["Content-Length"] = str(len(data))
response.data = data response.data = data
return response return response
def accept_gzip(): def accept_gzip():
if "gzip" in frappe.get_request_header("HTTP_ACCEPT_ENCODING", ""): if "gzip" in frappe.get_request_header("HTTP_ACCEPT_ENCODING", ""):
return True return True
@@ -97,7 +97,7 @@ def compressBuf(buf):
zfile.write(buf) zfile.write(buf)
zfile.close() zfile.close()
return zbuf.getvalue() return zbuf.getvalue()
def json_handler(obj): def json_handler(obj):
"""serialize non-serializable data for json""" """serialize non-serializable data for json"""
# serialize date # serialize date
@@ -105,20 +105,22 @@ 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, frappe.model.document.Document):
return obj.as_dict()
elif isinstance(obj, frappe.model.document.BaseDocument):
doc = obj.as_dict(no_nulls=True)

return doc
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))
def as_page(): def as_page():
"""print web page""" """print web page"""
from frappe.website.render import render from frappe.website.render import render
return render(frappe.response['page_name'], http_status_code=frappe.response.get("http_status_code")) return render(frappe.response['page_name'], http_status_code=frappe.response.get("http_status_code"))
def redirect(): def redirect():
return werkzeug.utils.redirect(frappe.response.location) return werkzeug.utils.redirect(frappe.response.location)
def download_backup(path): def download_backup(path):
try: try:
frappe.only_for(("System Manager", "Administrator")) frappe.only_for(("System Manager", "Administrator"))
@@ -145,7 +147,7 @@ def send_private_file(path):
response = Response(wrap_file(frappe.local.request.environ, f)) response = Response(wrap_file(frappe.local.request.environ, f))
response.headers.add('Content-Disposition', 'attachment', filename=filename) response.headers.add('Content-Disposition', 'attachment', filename=filename)
response.headers['Content-Type'] = mimetypes.guess_type(filename)[0] or 'application/octet-stream' response.headers['Content-Type'] = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
return response return response


def handle_session_stopped(): def handle_session_stopped():


+ 38
- 38
frappe/website/js/website.js Ver arquivo

@@ -9,8 +9,8 @@ $.extend(frappe, {
if(frappe._assets_loaded.indexOf(url)!==-1) return; if(frappe._assets_loaded.indexOf(url)!==-1) return;
$.ajax({ $.ajax({
url: url, url: url,
async: false,
dataType: "text",
async: false,
dataType: "text",
success: function(data) { success: function(data) {
if(url.split(".").splice(-1) == "js") { if(url.split(".").splice(-1) == "js") {
var el = document.createElement('script'); var el = document.createElement('script');
@@ -58,13 +58,13 @@ $.extend(frappe, {
if(opts.btn) { if(opts.btn) {
$(opts.btn).prop("disabled", true); $(opts.btn).prop("disabled", true);
} }
if(opts.msg) { if(opts.msg) {
$(opts.msg).toggle(false); $(opts.msg).toggle(false);
} }
if(!opts.args) opts.args = {}; if(!opts.args) opts.args = {};
// get or post? // get or post?
if(!opts.args._type) { if(!opts.args._type) {
opts.args._type = opts.type || "GET"; opts.args._type = opts.type || "GET";
@@ -82,17 +82,17 @@ $.extend(frappe, {
} }
}); });


if(!opts.no_spinner) {
if(!opts.no_spinner) {
NProgress.start(); NProgress.start();
} }
}, },
process_response: function(opts, data) { process_response: function(opts, data) {
if(!opts.no_spinner) NProgress.done(); if(!opts.no_spinner) NProgress.done();
if(opts.btn) { if(opts.btn) {
$(opts.btn).prop("disabled", false); $(opts.btn).prop("disabled", false);
} }
if(data.exc) { if(data.exc) {
if(opts.btn) { if(opts.btn) {
$(opts.btn).addClass("btn-danger"); $(opts.btn).addClass("btn-danger");
@@ -145,7 +145,7 @@ $.extend(frappe, {
</div>\ </div>\
</div>\ </div>\
</div>').appendTo(document.body); </div>').appendTo(document.body);
return modal; return modal;
}, },
msgprint: function(html, title) { msgprint: function(html, title) {
@@ -189,19 +189,19 @@ $.extend(frappe, {
if(frappe.supports_pjax()) { if(frappe.supports_pjax()) {
// hack for chrome's onload popstate call // hack for chrome's onload popstate call
window.initial_href = window.location.href window.initial_href = window.location.href
$(document).on("click", "#wrap a", frappe.handle_click); $(document).on("click", "#wrap a", frappe.handle_click);
$(window).on("popstate", function(event) { $(window).on("popstate", function(event) {
// hack for chrome's onload popstate call // hack for chrome's onload popstate call
if(window.initial_href==location.href && window.previous_href==undefined) { if(window.initial_href==location.href && window.previous_href==undefined) {
frappe.set_force_reload(true); frappe.set_force_reload(true);
return; return;
} }
window.previous_href = location.href; window.previous_href = location.href;
var state = event.originalEvent.state; var state = event.originalEvent.state;
if(state) { if(state) {
frappe.render_json(state); frappe.render_json(state);
} else { } else {
@@ -213,7 +213,7 @@ $.extend(frappe, {
handle_click: function(event) { handle_click: function(event) {
// taken from jquery pjax // taken from jquery pjax
var link = event.currentTarget var link = event.currentTarget
if (link.tagName.toUpperCase() !== 'A') if (link.tagName.toUpperCase() !== 'A')
throw "using pjax requires an anchor element" throw "using pjax requires an anchor element"


@@ -221,7 +221,7 @@ $.extend(frappe, {
// links in a new tab as normal. // links in a new tab as normal.
if ( event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey ) if ( event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey )
return return
// Ignore cross origin links // Ignore cross origin links
if ( location.protocol !== link.protocol || location.hostname !== link.hostname ) if ( location.protocol !== link.protocol || location.hostname !== link.hostname )
return return
@@ -230,15 +230,15 @@ $.extend(frappe, {
if (link.hash && link.href.replace(link.hash, '') === if (link.hash && link.href.replace(link.hash, '') ===
location.href.replace(location.hash, '')) location.href.replace(location.hash, ''))
return return
// Ignore empty anchor "foo.html#" // Ignore empty anchor "foo.html#"
if (link.href === location.href + '#') if (link.href === location.href + '#')
return return
// our custom logic // our custom logic
if (link.href.indexOf("cmd=")!==-1 || link.hasAttribute("no-pjax")) if (link.href.indexOf("cmd=")!==-1 || link.hasAttribute("no-pjax"))
return return
event.preventDefault() event.preventDefault()
frappe.load_via_ajax(link.href); frappe.load_via_ajax(link.href);


@@ -247,12 +247,12 @@ $.extend(frappe, {
// console.log("calling ajax"); // console.log("calling ajax");
window.previous_href = href; window.previous_href = href;
history.pushState(null, null, href); history.pushState(null, null, href);
//NProgress.start(); //NProgress.start();
$.ajax({ url: href, cache: false }).done(function(data) { $.ajax({ url: href, cache: false }).done(function(data) {
history.replaceState(data, data.title, href); history.replaceState(data, data.title, href);
$("html, body").animate({ scrollTop: 0 }, "slow"); $("html, body").animate({ scrollTop: 0 }, "slow");
frappe.render_json(data);
frappe.render_json(data);
}).always(function() { }).always(function() {
//NProgress.done(); //NProgress.done();
}).fail(function(xhr, status, error) { }).fail(function(xhr, status, error) {
@@ -289,17 +289,17 @@ $.extend(frappe, {
} }
}); });
if(data.title) $("title").html(data.title); if(data.title) $("title").html(data.title);
// change id of current page // change id of current page
$(".page-container").attr("id", "page-" + data.path); $(".page-container").attr("id", "page-" + data.path);
window.ga && ga('send', 'pageview', location.pathname); window.ga && ga('send', 'pageview', location.pathname);
$(document).trigger("page-change"); $(document).trigger("page-change");
} }
}, },
set_force_reload: function(reload) { set_force_reload: function(reload) {
// learned this from twitter's implementation // learned this from twitter's implementation
window.history.replaceState({"reload": reload},
window.history.replaceState({"reload": reload},
window.document.title, location.href); window.document.title, location.href);
}, },
supports_pjax: function() { supports_pjax: function() {
@@ -345,19 +345,19 @@ $.extend(frappe, {
$("[data-html-block='breadcrumbs'] .breadcrumb").toggleClass("hidden", $("[data-html-block='breadcrumbs'] .breadcrumb").toggleClass("hidden",
!$("[data-html-block='breadcrumbs']").text().trim() || !$("[data-html-block='breadcrumbs']").text().trim() ||
$("[data-html-block='breadcrumbs']").text().trim()==$("[data-html-block='header']").text().trim()); $("[data-html-block='breadcrumbs']").text().trim()==$("[data-html-block='header']").text().trim());
// to show full content width, when no sidebar content // to show full content width, when no sidebar content
var sidebar_has_content = !!$("[data-html-block='sidebar']").html().trim();
$(".page-sidebar, .toggle-sidebar").toggleClass("hidden", !sidebar_has_content);
$(".page-sidebar").toggleClass("col-sm-push-9", sidebar_has_content);
$(".page-content").toggleClass("col-sm-12", !sidebar_has_content);
$(".page-content").toggleClass("col-sm-9 col-sm-pull-3", sidebar_has_content);
// var sidebar_has_content = !!$("[data-html-block='sidebar']").html().trim();
// $(".page-sidebar, .toggle-sidebar").toggleClass("hidden", !sidebar_has_content);
// $(".page-sidebar").toggleClass("col-sm-push-9", sidebar_has_content);
// $(".page-content").toggleClass("col-sm-12", !sidebar_has_content);
// $(".page-content").toggleClass("col-sm-9 col-sm-pull-3", sidebar_has_content);
// if everything in the sub-header is hidden, hide the sub-header // if everything in the sub-header is hidden, hide the sub-header
var hide_sub_header = $(".page-sub-header .row").children().length === $(".page-sub-header .row").find(".hidden").length; var hide_sub_header = $(".page-sub-header .row").children().length === $(".page-sub-header .row").find(".hidden").length;
$(".page-sub-header").toggleClass("hidden", hide_sub_header); $(".page-sub-header").toggleClass("hidden", hide_sub_header);
// collapse sidebar in mobile view on page change // collapse sidebar in mobile view on page change
if(!$(".page-sidebar").hasClass("hidden-xs")) { if(!$(".page-sidebar").hasClass("hidden-xs")) {
$(".toggle-sidebar").trigger("click"); $(".toggle-sidebar").trigger("click");
@@ -388,7 +388,7 @@ function get_url_arg(name) {
if(results == null) if(results == null)
return ""; return "";
else else
return decodeURIComponent(results[1]);
return decodeURIComponent(results[1]);
} }


function make_query_string(obj) { function make_query_string(obj) {
@@ -468,7 +468,7 @@ function remove_script_and_style(txt) {
} }


function is_html(txt) { function is_html(txt) {
if(txt.indexOf("<br>")==-1 && txt.indexOf("<p")==-1
if(txt.indexOf("<br>")==-1 && txt.indexOf("<p")==-1
&& txt.indexOf("<img")==-1 && txt.indexOf("<div")==-1) { && txt.indexOf("<img")==-1 && txt.indexOf("<div")==-1) {
return false; return false;
} }
@@ -491,21 +491,21 @@ $(document).ready(function() {
window.logged_in = getCookie("sid") && getCookie("sid")!=="Guest"; window.logged_in = getCookie("sid") && getCookie("sid")!=="Guest";
$("#website-login").toggleClass("hide", logged_in ? true : false); $("#website-login").toggleClass("hide", logged_in ? true : false);
$("#website-post-login").toggleClass("hide", logged_in ? false : true); $("#website-post-login").toggleClass("hide", logged_in ? false : true);
$(".toggle-sidebar").on("click", function() { $(".toggle-sidebar").on("click", function() {
$(".page-sidebar").toggleClass("hidden-xs"); $(".page-sidebar").toggleClass("hidden-xs");
$(".toggle-sidebar i").toggleClass("icon-rotate-180"); $(".toggle-sidebar i").toggleClass("icon-rotate-180");
}); });
// switch to app link // switch to app link
if(getCookie("system_user")==="yes") { if(getCookie("system_user")==="yes") {
$("#website-post-login .dropdown-menu").append('<li class="divider"></li>\ $("#website-post-login .dropdown-menu").append('<li class="divider"></li>\
<li><a href="/desk" no-pjax><i class="icon-fixed-width icon-th-large"></i> Switch To Desk</a></li>'); <li><a href="/desk" no-pjax><i class="icon-fixed-width icon-th-large"></i> Switch To Desk</a></li>');
} }
frappe.render_user(); frappe.render_user();
frappe.setup_push_state() frappe.setup_push_state()
$(document).trigger("page-change"); $(document).trigger("page-change");
}); });




+ 4
- 2
frappe/website/sitemap.py Ver arquivo

@@ -42,7 +42,9 @@ def build_sitemap_options(path):


if not sitemap_options.no_sidebar: if not sitemap_options.no_sidebar:
sitemap_options.children = get_route_children(sitemap_options.pathname, home_page) sitemap_options.children = get_route_children(sitemap_options.pathname, home_page)
if not sitemap_options.children:

if not sitemap_options.children and sitemap_options.parent_website_route \
and sitemap_options.parent_website_route!=home_page:
sitemap_options.children = get_route_children(sitemap_options.parent_website_route, home_page) sitemap_options.children = get_route_children(sitemap_options.parent_website_route, home_page)


# determine templates to be used # determine templates to be used
@@ -80,4 +82,4 @@ def get_route_children(pathname, home_page=None):


children = [frappe.get_doc("Website Route", pathname)] + children children = [frappe.get_doc("Website Route", pathname)] + children


return children
return children

+ 29
- 30
frappe/widgets/form/meta.py Ver arquivo

@@ -1,5 +1,5 @@
# 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


# metadata # metadata


@@ -20,14 +20,14 @@ def get_meta(doctype, cached=True):


if frappe.local.lang != 'en': if frappe.local.lang != 'en':
meta.set("__messages", frappe.get_lang_dict("doctype", doctype)) meta.set("__messages", frappe.get_lang_dict("doctype", doctype))
return meta return meta
class FormMeta(Meta): class FormMeta(Meta):
def __init__(self, doctype): def __init__(self, doctype):
super(FormMeta, self).__init__(doctype) super(FormMeta, self).__init__(doctype)
self.load_assets() self.load_assets()
def load_assets(self): def load_assets(self):
self.expand_selects() self.expand_selects()
self.add_search_fields() self.add_search_fields()
@@ -37,52 +37,52 @@ class FormMeta(Meta):
self.add_code() self.add_code()
self.load_print_formats() self.load_print_formats()
self.load_workflows() self.load_workflows()
def as_dict(self):
d = super(FormMeta, self).as_dict()
def as_dict(self, no_nulls=False):
d = super(FormMeta, self).as_dict(no_nulls=no_nulls)
for k in ("__js", "__css", "__list_js", "__calendar_js", "__map_js", "__linked_with", "__messages"): for k in ("__js", "__css", "__list_js", "__calendar_js", "__map_js", "__linked_with", "__messages"):
d[k] = self.get(k) d[k] = self.get(k)
for i, df in enumerate(d.get("fields")): for i, df in enumerate(d.get("fields")):
for k in ("link_doctype", "search_fields"): for k in ("link_doctype", "search_fields"):
df[k] = self.get("fields")[i].get(k) df[k] = self.get("fields")[i].get(k)
return d return d
def add_code(self): def add_code(self):
path = os.path.join(get_module_path(self.module), 'doctype', scrub(self.name)) path = os.path.join(get_module_path(self.module), 'doctype', scrub(self.name))
def _get_path(fname): def _get_path(fname):
return os.path.join(path, scrub(fname)) return os.path.join(path, scrub(fname))
self._add_code(_get_path(self.name + '.js'), '__js') 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 + '.css'), "__css")
self._add_code(_get_path(self.name + '_list.js'), '__list_js') 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 + '_calendar.js'), '__calendar_js')
self._add_code(_get_path(self.name + '_map.js'), '__map_js') self._add_code(_get_path(self.name + '_map.js'), '__map_js')
self.add_custom_script() self.add_custom_script()
self.add_code_via_hook("doctype_js", "__js") self.add_code_via_hook("doctype_js", "__js")
def _add_code(self, path, fieldname): def _add_code(self, path, fieldname):
js = frappe.read_file(path) js = frappe.read_file(path)
if js: if js:
self.set(fieldname, (self.get(fieldname) or "") + "\n\n" + render_jinja(js)) self.set(fieldname, (self.get(fieldname) or "") + "\n\n" + render_jinja(js))
def add_code_via_hook(self, hook, fieldname): def add_code_via_hook(self, hook, fieldname):
hook = "{}:{}".format(hook, self.name) hook = "{}:{}".format(hook, self.name)
for app_name in frappe.get_installed_apps(): for app_name in frappe.get_installed_apps():
for file in frappe.get_hooks(hook, app_name=app_name): for file in frappe.get_hooks(hook, app_name=app_name):
path = frappe.get_app_path(app_name, *file.strip("/").split("/")) path = frappe.get_app_path(app_name, *file.strip("/").split("/"))
self._add_code(path, fieldname) self._add_code(path, fieldname)
def add_custom_script(self): def add_custom_script(self):
"""embed all require files""" """embed all require files"""
# custom script # custom script
custom = frappe.db.get_value("Custom Script", {"dt": self.name,
custom = frappe.db.get_value("Custom Script", {"dt": self.name,
"script_type": "Client"}, "script") or "" "script_type": "Client"}, "script") or ""
self.set("__js", (self.get('__js') or '') + "\n\n" + custom) self.set("__js", (self.get('__js') or '') + "\n\n" + custom)
def render_jinja(content): def render_jinja(content):
if "{% include" in content: if "{% include" in content:
content = frappe.get_jenv().from_string(content).render() content = frappe.get_jenv().from_string(content).render()
@@ -92,9 +92,9 @@ class FormMeta(Meta):
for df in self.get("fields", {"fieldtype": "Select"}): for df in self.get("fields", {"fieldtype": "Select"}):
if df.options and df.options.startswith("link:"): if df.options and df.options.startswith("link:"):
df.link_doctype = df.options.split("\n")[0][5:] df.link_doctype = df.options.split("\n")[0][5:]
df.options = '\n'.join([''] + [o.name for o in frappe.db.sql("""select
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)]) name from `tab%s` where docstatus<2 order by name asc""" % df.link_doctype, as_dict=1)])
def add_search_fields(self): def add_search_fields(self):
"""add search fields found in the doctypes indicated by link fields' options""" """add search fields found in the doctypes indicated by link fields' options"""
for df in self.get("fields", {"fieldtype": "Link", "options":["!=", "[Select]"]}): for df in self.get("fields", {"fieldtype": "Link", "options":["!=", "[Select]"]}):
@@ -114,7 +114,7 @@ class FormMeta(Meta):


links = dict(links) links = dict(links)


if not links:
if not links:
return {} return {}


ret = {} ret = {}
@@ -122,21 +122,21 @@ class FormMeta(Meta):
for dt in links: for dt in links:
ret[dt] = { "fieldname": links[dt] } 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
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)): where istable=1 and name in (%s))""" % ", ".join(["%s"] * len(links)) ,tuple(links)):


ret[grand_parent] = {"child_doctype": options, "fieldname": links[options] } ret[grand_parent] = {"child_doctype": options, "fieldname": links[options] }
if options in ret: if options in ret:
del ret[options] del ret[options]
self.set("__linked_with", ret) self.set("__linked_with", ret)
def load_print_formats(self): def load_print_formats(self):
frappe.response.docs.extend(frappe.db.sql("""select * FROM `tabPrint Format` 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"})) WHERE doc_type=%s AND docstatus<2""", (self.name,), as_dict=1, update={"doctype":"Print Format"}))
def load_workflows(self): def load_workflows(self):
# get active workflow # get active workflow
workflow_name = get_workflow_name(self.name) workflow_name = get_workflow_name(self.name)
@@ -144,14 +144,13 @@ class FormMeta(Meta):
if workflow_name and frappe.db.exists("Workflow", workflow_name): if workflow_name and frappe.db.exists("Workflow", workflow_name):
workflow = frappe.get_doc("Workflow", workflow_name) workflow = frappe.get_doc("Workflow", workflow_name)
frappe.response.docs.append(workflow) frappe.response.docs.append(workflow)
for d in workflow.get("workflow_document_states"): for d in workflow.get("workflow_document_states"):
frappe.response.docs.append(frappe.get_doc("Workflow State", d.state)) frappe.response.docs.append(frappe.get_doc("Workflow State", d.state))


def render_jinja(content): def render_jinja(content):
if "{% include" in content: if "{% include" in content:
content = frappe.get_jenv().from_string(content).render() content = frappe.get_jenv().from_string(content).render()
return content return content



Carregando…
Cancelar
Salvar