@@ -73,8 +73,10 @@ frappe.ui.form.on("Customize Form", "refresh", function(frm) { | |||
// } | |||
if(frappe.route_options) { | |||
frappe.model.set_value("Customize Form", null, "doc_type", frappe.route_options.doctype) | |||
frappe.route_options = null; | |||
setTimeout(function() { | |||
frm.set_value("doc_type", frappe.route_options.doctype); | |||
frappe.route_options = null; | |||
}, 1000); | |||
} | |||
}); | |||
@@ -1,339 +1,92 @@ | |||
{ | |||
"_last_update": null, | |||
"_user_tags": null, | |||
"allow_attach": null, | |||
"allow_copy": null, | |||
"allow_email": null, | |||
"allow_import": null, | |||
"allow_print": null, | |||
"allow_rename": null, | |||
"allow_trash": null, | |||
"autoname": null, | |||
"change_log": null, | |||
"client_script": null, | |||
"client_script_core": null, | |||
"client_string": null, | |||
"colour": null, | |||
"creation": "2014-04-17 16:53:52.640856", | |||
"custom": null, | |||
"default_print_format": null, | |||
"description": null, | |||
"docstatus": 0, | |||
"doctype": "DocType", | |||
"document_type": "System", | |||
"dt_template": null, | |||
"fields": [ | |||
{ | |||
"allow_on_submit": null, | |||
"default": null, | |||
"depends_on": null, | |||
"description": null, | |||
"fieldname": "localization", | |||
"fieldtype": "Section Break", | |||
"hidden": null, | |||
"ignore_restrictions": null, | |||
"in_filter": null, | |||
"in_list_view": null, | |||
"label": "Localization", | |||
"no_column": null, | |||
"no_copy": null, | |||
"oldfieldname": null, | |||
"oldfieldtype": null, | |||
"options": null, | |||
"permlevel": 0, | |||
"print_hide": null, | |||
"print_width": null, | |||
"read_only": null, | |||
"report_hide": null, | |||
"reqd": null, | |||
"search_index": null, | |||
"set_only_once": null, | |||
"trigger": null, | |||
"width": null | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"allow_on_submit": null, | |||
"default": null, | |||
"depends_on": null, | |||
"description": null, | |||
"fieldname": "language", | |||
"fieldtype": "Select", | |||
"hidden": null, | |||
"ignore_restrictions": null, | |||
"in_filter": null, | |||
"in_list_view": 1, | |||
"label": "Language", | |||
"no_column": null, | |||
"no_copy": null, | |||
"oldfieldname": null, | |||
"oldfieldtype": null, | |||
"options": "Loading...", | |||
"permlevel": 0, | |||
"print_hide": null, | |||
"print_width": null, | |||
"read_only": null, | |||
"report_hide": null, | |||
"reqd": 1, | |||
"search_index": 0, | |||
"set_only_once": null, | |||
"trigger": null, | |||
"width": null | |||
"search_index": 0 | |||
}, | |||
{ | |||
"allow_on_submit": null, | |||
"default": null, | |||
"depends_on": null, | |||
"description": null, | |||
"fieldname": "time_zone", | |||
"fieldtype": "Select", | |||
"hidden": null, | |||
"ignore_restrictions": null, | |||
"in_filter": null, | |||
"in_list_view": null, | |||
"label": "Time Zone", | |||
"no_column": null, | |||
"no_copy": null, | |||
"oldfieldname": null, | |||
"oldfieldtype": null, | |||
"options": null, | |||
"permlevel": 0, | |||
"print_hide": null, | |||
"print_width": null, | |||
"read_only": null, | |||
"report_hide": null, | |||
"reqd": 1, | |||
"search_index": null, | |||
"set_only_once": null, | |||
"trigger": null, | |||
"width": null | |||
"reqd": 1 | |||
}, | |||
{ | |||
"allow_on_submit": null, | |||
"default": null, | |||
"depends_on": null, | |||
"description": null, | |||
"fieldname": "date_and_number_format", | |||
"fieldtype": "Section Break", | |||
"hidden": null, | |||
"ignore_restrictions": null, | |||
"in_filter": null, | |||
"in_list_view": null, | |||
"label": "Date and Number Format", | |||
"no_column": null, | |||
"no_copy": null, | |||
"oldfieldname": null, | |||
"oldfieldtype": null, | |||
"options": null, | |||
"permlevel": 0, | |||
"print_hide": null, | |||
"print_width": null, | |||
"read_only": null, | |||
"report_hide": null, | |||
"reqd": null, | |||
"search_index": null, | |||
"set_only_once": null, | |||
"trigger": null, | |||
"width": null | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"allow_on_submit": null, | |||
"default": null, | |||
"depends_on": null, | |||
"description": null, | |||
"fieldname": "date_format", | |||
"fieldtype": "Select", | |||
"hidden": null, | |||
"ignore_restrictions": null, | |||
"in_filter": null, | |||
"in_list_view": null, | |||
"label": "Date Format", | |||
"no_column": null, | |||
"no_copy": null, | |||
"oldfieldname": null, | |||
"oldfieldtype": null, | |||
"options": "yyyy-mm-dd\ndd-mm-yyyy\ndd/mm/yyyy\nmm/dd/yyyy\nmm-dd-yyyy", | |||
"options": "yyyy-mm-dd\ndd-mm-yyyy\ndd/mm/yyyy\ndd.mm.yyyy\nmm/dd/yyyy\nmm-dd-yyyy", | |||
"permlevel": 0, | |||
"print_hide": null, | |||
"print_width": null, | |||
"read_only": null, | |||
"report_hide": null, | |||
"reqd": 1, | |||
"search_index": null, | |||
"set_only_once": null, | |||
"trigger": null, | |||
"width": null | |||
"reqd": 1 | |||
}, | |||
{ | |||
"allow_on_submit": null, | |||
"default": null, | |||
"depends_on": null, | |||
"description": null, | |||
"fieldname": "number_format", | |||
"fieldtype": "Select", | |||
"hidden": null, | |||
"ignore_restrictions": null, | |||
"in_filter": null, | |||
"in_list_view": null, | |||
"label": "Number Format", | |||
"no_column": null, | |||
"no_copy": null, | |||
"oldfieldname": null, | |||
"oldfieldtype": null, | |||
"options": "#,###.##\n#.###,##\n# ###.##\n#,###.###\n#,##,###.##\n#.###\n#,###", | |||
"options": "#,###.##\n#.###,##\n# ###.##\n# ###,##\n#,###.###\n#,##,###.##\n#.###\n#,###", | |||
"permlevel": 0, | |||
"print_hide": null, | |||
"print_width": null, | |||
"read_only": null, | |||
"report_hide": null, | |||
"reqd": 1, | |||
"search_index": null, | |||
"set_only_once": null, | |||
"trigger": null, | |||
"width": null | |||
"reqd": 1 | |||
}, | |||
{ | |||
"allow_on_submit": null, | |||
"default": null, | |||
"depends_on": null, | |||
"description": null, | |||
"fieldname": "float_precision", | |||
"fieldtype": "Select", | |||
"hidden": null, | |||
"ignore_restrictions": null, | |||
"in_filter": null, | |||
"in_list_view": null, | |||
"label": "Float Precision", | |||
"no_column": null, | |||
"no_copy": null, | |||
"oldfieldname": null, | |||
"oldfieldtype": null, | |||
"options": "\n2\n3\n4\n5\n6", | |||
"permlevel": 0, | |||
"print_hide": null, | |||
"print_width": null, | |||
"read_only": null, | |||
"report_hide": null, | |||
"reqd": null, | |||
"search_index": null, | |||
"set_only_once": null, | |||
"trigger": null, | |||
"width": null | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"allow_on_submit": null, | |||
"default": null, | |||
"depends_on": null, | |||
"description": null, | |||
"fieldname": "security", | |||
"fieldtype": "Section Break", | |||
"hidden": null, | |||
"ignore_restrictions": null, | |||
"in_filter": null, | |||
"in_list_view": null, | |||
"label": "Security", | |||
"no_column": null, | |||
"no_copy": null, | |||
"oldfieldname": null, | |||
"oldfieldtype": null, | |||
"options": null, | |||
"permlevel": 0, | |||
"print_hide": null, | |||
"print_width": null, | |||
"read_only": null, | |||
"report_hide": null, | |||
"reqd": null, | |||
"search_index": null, | |||
"set_only_once": null, | |||
"trigger": null, | |||
"width": null | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"allow_on_submit": null, | |||
"default": "06:00", | |||
"depends_on": null, | |||
"description": "Session Expiry in Hours e.g. 06:00", | |||
"fieldname": "session_expiry", | |||
"fieldtype": "Data", | |||
"hidden": null, | |||
"ignore_restrictions": null, | |||
"in_filter": null, | |||
"in_list_view": null, | |||
"label": "Session Expiry", | |||
"no_column": null, | |||
"no_copy": null, | |||
"oldfieldname": null, | |||
"oldfieldtype": null, | |||
"options": "", | |||
"permlevel": 0, | |||
"print_hide": null, | |||
"print_width": null, | |||
"read_only": null, | |||
"report_hide": null, | |||
"reqd": null, | |||
"search_index": null, | |||
"set_only_once": null, | |||
"trigger": null, | |||
"width": null | |||
"permlevel": 0 | |||
} | |||
], | |||
"hide_heading": null, | |||
"hide_toolbar": null, | |||
"icon": "icon-cog", | |||
"idx": null, | |||
"in_create": null, | |||
"in_dialog": null, | |||
"is_submittable": null, | |||
"is_transaction_doc": null, | |||
"issingle": 1, | |||
"istable": null, | |||
"max_attachments": null, | |||
"menu_index": null, | |||
"modified": "2014-04-17 17:52:27.046530", | |||
"modified": "2014-05-27 07:58:24.700595", | |||
"modified_by": "Administrator", | |||
"module": "Core", | |||
"name": "System Settings", | |||
"name_case": "", | |||
"owner": "Administrator", | |||
"parent": null, | |||
"parent_node": null, | |||
"parentfield": null, | |||
"parenttype": null, | |||
"permissions": [ | |||
{ | |||
"amend": null, | |||
"cancel": null, | |||
"create": 1, | |||
"delete": null, | |||
"email": null, | |||
"export": null, | |||
"import": null, | |||
"match": null, | |||
"permlevel": 0, | |||
"print": null, | |||
"read": 1, | |||
"report": null, | |||
"restrict": null, | |||
"restricted": null, | |||
"role": "System Manager", | |||
"submit": null, | |||
"write": 1 | |||
} | |||
], | |||
"plugin": null, | |||
"print_outline": null, | |||
"read_only": null, | |||
"read_only_onload": null, | |||
"search_fields": null, | |||
"section_style": null, | |||
"server_code": null, | |||
"server_code_compiled": null, | |||
"server_code_core": null, | |||
"server_code_error": null, | |||
"show_in_menu": null, | |||
"smallicon": null, | |||
"subject": null, | |||
"tag_fields": null, | |||
"title_field": null, | |||
"use_template": null, | |||
"version": null | |||
] | |||
} |
@@ -13,6 +13,7 @@ class Workflow(Document): | |||
self.set_active() | |||
self.create_custom_field_for_workflow_state() | |||
self.update_default_workflow_status() | |||
self.validate_docstatus() | |||
def on_update(self): | |||
frappe.clear_cache(doctype=self.document_type) | |||
@@ -46,6 +47,27 @@ class Workflow(Document): | |||
'%s', self.workflow_state_field, "%s"), (d.state, d.doc_status)) | |||
docstatus_map[d.doc_status] = d.state | |||
def validate_docstatus(self): | |||
def get_state(state): | |||
for s in self.workflow_document_states: | |||
if s.state==state: | |||
return s | |||
frappe.throw(frappe._("{0} not a valid State").format(state)) | |||
for t in self.workflow_transitions: | |||
state = get_state(t.state) | |||
next_state = get_state(t.next_state) | |||
if state.doc_status=="2": | |||
frappe.throw(frappe._("Cannot change state of Cancelled Document. Transition row {0}").format(t.idx)) | |||
if state.doc_status=="1" and next_state.doc_status=="0": | |||
frappe.throw(frappe._("Submitted Document cannot be converted back to draft. Transition row {0}").format(t.idx)) | |||
if state.doc_status=="0" and next_state.doc_status=="2": | |||
frappe.throw(frappe._("Cannot cancel before submitting. See Transition {0}").format(t.idx)) | |||
def set_active(self): | |||
if int(self.is_active or 0): | |||
# clear all other | |||
@@ -1,6 +1,6 @@ | |||
{ | |||
"allow_import": 1, | |||
"creation": "2013-02-22 01:27:36.000000", | |||
"creation": "2013-02-22 01:27:36", | |||
"description": "Represents the states allowed in one document and role assigned to change the state.", | |||
"docstatus": 0, | |||
"doctype": "DocType", | |||
@@ -18,6 +18,7 @@ | |||
"width": "160px" | |||
}, | |||
{ | |||
"description": "0 - Draft; 1 - Submitted; 2 - Cancelled", | |||
"fieldname": "doc_status", | |||
"fieldtype": "Select", | |||
"in_list_view": 1, | |||
@@ -65,9 +66,10 @@ | |||
], | |||
"idx": 1, | |||
"istable": 1, | |||
"modified": "2013-12-20 19:21:55.000000", | |||
"modified": "2014-05-27 06:35:01.070157", | |||
"modified_by": "Administrator", | |||
"module": "Core", | |||
"name": "Workflow Document State", | |||
"owner": "Administrator" | |||
"owner": "Administrator", | |||
"permissions": [] | |||
} |
@@ -38,7 +38,7 @@ | |||
} | |||
.titlebar-item.text-right { | |||
margin-top: 5px; | |||
margin-top: 3px; | |||
} | |||
.titlebar-left-item { | |||
@@ -3,9 +3,9 @@ | |||
if(!window.frappe) window.frappe = {}; | |||
function flt(v, decimals, number_format) { | |||
function flt(v, decimals, number_format) { | |||
if(v==null || v=='')return 0; | |||
if(typeof v!=="number") { | |||
v = v + ""; | |||
@@ -20,27 +20,27 @@ function flt(v, decimals, number_format) { | |||
if(isNaN(v)) | |||
v=0; | |||
} | |||
if(decimals!=null) | |||
return _round(v, decimals); | |||
return v; | |||
} | |||
function cint(v, def) { | |||
if(v===true) | |||
function cint(v, def) { | |||
if(v===true) | |||
return 1; | |||
if(v===false) | |||
return 0; | |||
v=v+''; | |||
if(v!=="0")v=lstrip(v, ['0']); | |||
v=parseInt(v); | |||
if(v!=="0")v=lstrip(v, ['0']); | |||
v=parseInt(v); | |||
if(isNaN(v))v=def===undefined?0:def; | |||
return v; | |||
return v; | |||
} | |||
function strip_number_groups(v, number_format) { | |||
if(!number_format) number_format = get_number_format(); | |||
// strip groups (,) | |||
if(get_number_format_info(number_format).group_sep==".") { | |||
v = v.replace(/\./g,''); | |||
@@ -50,7 +50,7 @@ function strip_number_groups(v, number_format) { | |||
} else { | |||
v=v.replace(/,/g,''); | |||
} | |||
return v; | |||
} | |||
@@ -59,32 +59,33 @@ frappe.number_format_info = { | |||
"#,###.##": {decimal_str:".", group_sep:",", precision:2}, | |||
"#.###,##": {decimal_str:",", group_sep:".", precision:2}, | |||
"# ###.##": {decimal_str:".", group_sep:" ", precision:2}, | |||
"# ###,##": {decimal_str:",", group_sep:" ", precision:2}, | |||
"#,###.###": {decimal_str:".", group_sep:",", precision:3}, | |||
"#,##,###.##": {decimal_str:".", group_sep:",", precision:2}, | |||
"#.###": {decimal_str:"", group_sep:".", precision:0}, | |||
"#,###": {decimal_str:"", group_sep:",", precision:0}, | |||
} | |||
window.format_number = function(v, format, decimals){ | |||
window.format_number = function(v, format, decimals){ | |||
if (!format) { | |||
format = get_number_format(); | |||
if(decimals == null) decimals = cint(frappe.defaults.get_default("float_precision")) || 3; | |||
} | |||
info = get_number_format_info(format); | |||
//Fix the decimal first, toFixed will auto fill trailing zero. | |||
decimals = decimals || info.precision; | |||
v = flt(v, decimals, format); | |||
if(v<0) var is_negative = true; | |||
if(v<0) var is_negative = true; | |||
v = Math.abs(v); | |||
v = v.toFixed(decimals); | |||
var part = v.split('.'); | |||
// get group position and parts | |||
var group_position = info.group_sep ? 3 : 0; | |||
@@ -92,14 +93,14 @@ window.format_number = function(v, format, decimals){ | |||
var integer = part[0]; | |||
var str = ''; | |||
var offset = integer.length % group_position; | |||
for (var i=integer.length; i>=0; i--) { | |||
for (var i=integer.length; i>=0; i--) { | |||
var l = replace_all(str, info.group_sep, "").length; | |||
if(format=="#,##,###.##" && str.indexOf(",")!=-1) { // INR | |||
group_position = 2; | |||
l += 1; | |||
} | |||
str += integer.charAt(i); | |||
str += integer.charAt(i); | |||
if (l && !((l+1) % group_position) && i!=0 ) { | |||
str += info.group_sep; | |||
@@ -110,10 +111,10 @@ window.format_number = function(v, format, decimals){ | |||
if(part[0]+""=="") { | |||
part[0]="0"; | |||
} | |||
// join decimal | |||
part[1] = part[1] ? (info.decimal_str + part[1]) : ""; | |||
// join | |||
return (is_negative ? "-" : "") + part[0] + part[1]; | |||
}; | |||
@@ -150,13 +151,13 @@ function get_number_format(currency) { | |||
|| frappe.model.get_value("Currency", frappe.boot.sysdefaults.currency, "number_format") | |||
|| "#,###.##"; | |||
} | |||
var number_format; | |||
if(currency && frappe.boot) { | |||
number_format = frappe.model.get_value("Currency", currency, | |||
number_format = frappe.model.get_value("Currency", currency, | |||
"number_format"); | |||
} | |||
return number_format || global_number_format; | |||
} | |||
@@ -205,4 +206,4 @@ function in_list(list, item) { | |||
for(var i=0, j=list.length; i<j; i++) | |||
if(list[i]==item) return true; | |||
return false; | |||
} | |||
} |
@@ -3,13 +3,13 @@ function prettyDate(time){ | |||
var date = time; | |||
if(typeof(time)=="string") | |||
date = new Date((time || "").replace(/-/g,"/").replace(/[TZ]/g," ").replace(/\.[0-9]*/, "")); | |||
var diff = (((new Date()).getTime() - date.getTime()) / 1000), | |||
day_diff = Math.floor(diff / 86400); | |||
if ( isNaN(day_diff) || day_diff < 0 ) | |||
return ''; | |||
return when = day_diff == 0 && ( | |||
diff < 60 && "just now" || | |||
diff < 120 && "1 minute ago" || | |||
@@ -21,12 +21,14 @@ function prettyDate(time){ | |||
day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks ago" || | |||
day_diff < 365 && Math.ceil( day_diff / 30) + " months ago" || | |||
"> " + Math.floor( day_diff / 365 ) + " year(s) ago"; | |||
} | |||
var comment_when = function(datetime) { | |||
return '<span class="frappe-timestamp" data-timestamp="'+datetime+'">' + prettyDate(datetime) + '</span>'; | |||
return '<span class="frappe-timestamp" data-timestamp="'+datetime | |||
+'" title="'+datetime+'">' | |||
+ prettyDate(datetime) + '</span>'; | |||
}; | |||
frappe.provide("frappe.datetime"); | |||
@@ -16,7 +16,7 @@ frappe.ui.AppFrame = Class.extend({ | |||
<span class="title-text"></span>\ | |||
</span>').appendTo($center); | |||
this.$sub_title_area = $('<div class="title-sub"></div>') | |||
this.$sub_title_area = $('<div class="title-sub hide"></div>') | |||
.appendTo($center); | |||
this.setup_iconbar(); | |||
@@ -53,7 +53,7 @@ frappe.ui.AppFrame = Class.extend({ | |||
set_title_sub: function(txt) { | |||
// strip icon | |||
this.$sub_title_area.html(txt); | |||
this.$sub_title_area.html(txt).toggleClass("hide", !!!txt); | |||
}, | |||
set_title_left: function(click) { | |||
@@ -21,8 +21,10 @@ frappe.ui.FilterList = Class.extend({ | |||
show_filters: function() { | |||
this.$w.find('.show_filters').toggle(); | |||
if(!this.filters.length) | |||
if(!this.filters.length) { | |||
this.add_filter(); | |||
this.filters[0].$w.find(".filter_field input").focus(); | |||
} | |||
}, | |||
clear_filters: function() { | |||
@@ -116,7 +118,9 @@ frappe.ui.Filter = Class.extend({ | |||
me.set_field(doctype, fieldname); | |||
} | |||
}); | |||
this.fieldselect.set_value(this.doctype, this.fieldname); | |||
if(this.fieldname) { | |||
this.fieldselect.set_value(this.doctype, this.fieldname); | |||
} | |||
}, | |||
set_events: function() { | |||
var me = this; | |||
@@ -141,14 +145,19 @@ frappe.ui.Filter = Class.extend({ | |||
// add help for "in" codition | |||
me.$w.find('.condition').change(function() { | |||
if($(this).val()=='in') { | |||
me.set_field(me.field.df.parent, me.field.df.fieldname, 'Data'); | |||
if(!me.field.desc_area) | |||
me.field.desc_area = $a(me.field.wrapper, 'span', 'help', null, | |||
'values separated by comma'); | |||
var condition = $(this).val(); | |||
if(in_list(["in", "like"], condition)) { | |||
me.set_field(me.field.df.parent, me.field.df.fieldname, 'Data', condition); | |||
if(!me.field.desc_area) { | |||
me.field.desc_area = $('<div class="text-muted small">').appendTo(me.field.wrapper); | |||
} | |||
// set description | |||
me.field.desc_area.html((condition==="in" | |||
? __("values separated by commas") | |||
: __("use % as wildcard"))+'</div>'); | |||
} else { | |||
me.set_field(me.field.df.parent, me.field.df.fieldname, null, | |||
me.$w.find('.condition').val()); | |||
condition); | |||
} | |||
}); | |||
@@ -300,7 +309,7 @@ frappe.ui.FieldSelect = Class.extend({ | |||
source: me.options, | |||
minLength: 0, | |||
focus: function(event, ui) { | |||
me.$select.val(ui.item.label); | |||
ui.item && me.$select.val(ui.item.label); | |||
return false; | |||
}, | |||
select: function(event, ui) { | |||
@@ -64,6 +64,20 @@ frappe.ui.Listing = Class.extend({ | |||
$.extend(this, this.opts); | |||
$(this.parent).html(repl('\ | |||
<div class="show-docstatus hide" style="min-height: 40px;">\ | |||
<div class="pull-right" style="margin-left: 15px;"><div class="checkbox"><label>\ | |||
<input type="checkbox" data-docstatus="2">\ | |||
<span class="text-muted small">'+__('Cancelled')+'</span>\ | |||
</label></div></div>\ | |||
<div class="pull-right" style="margin-left: 15px;"><div class="checkbox"><label>\ | |||
<input type="checkbox" data-docstatus="1" checked="checked">\ | |||
<span class="text-muted small">'+__('Submitted')+'</span>\ | |||
</label></div></div>\ | |||
<div class="pull-right" style="margin-left: 15px;"><div class="checkbox"><label>\ | |||
<input type="checkbox" data-docstatus="0" checked="checked">\ | |||
<span class="text-muted small">'+__('Drafts')+'</span>\ | |||
</label></div></div>\ | |||
</div>\ | |||
<div class="frappe-list">\ | |||
<h3 class="title hide">%(title)s</h3>\ | |||
\ | |||
@@ -120,6 +134,7 @@ frappe.ui.Listing = Class.extend({ | |||
if(this.show_filters) { | |||
this.make_filters(); | |||
} | |||
this.setup_docstatus_filter(); | |||
}, | |||
add_button: function(label, click, icon) { | |||
if(this.appframe) { | |||
@@ -213,6 +228,17 @@ frappe.ui.Listing = Class.extend({ | |||
}); | |||
}, | |||
setup_docstatus_filter: function() { | |||
var me = this; | |||
this.can_submit = frappe.model.is_submittable(me.doctype); | |||
if(this.can_submit) { | |||
$(this.parent).find('.show-docstatus').removeClass('hide'); | |||
$(this.parent).find('.show-docstatus input').click(function() { | |||
me.run(); | |||
}) | |||
} | |||
}, | |||
clear: function() { | |||
this.data = []; | |||
this.$w.find('.result-list').empty(); | |||
@@ -263,6 +289,11 @@ frappe.ui.Listing = Class.extend({ | |||
} | |||
} | |||
args.docstatus = this.can_submit ? $.map($(this.parent).find('.show-docstatus :checked'), | |||
function(inp) { | |||
return $(inp).attr('data-docstatus'); | |||
}) : [] | |||
// append user-defined arguments | |||
if(this.args) | |||
$.extend(args, this.args) | |||
@@ -57,25 +57,6 @@ frappe.views.DocListView = frappe.ui.Listing.extend({ | |||
<div class="help">'+__('Loading')+'...</div></div>') | |||
.appendTo(this.$page.find(".layout-main-section")); | |||
$('<div class="show-docstatus hide side-panel">\ | |||
<h5 class="text-muted">Show</h5>\ | |||
<div class="side-panel-body">\ | |||
<div class="checkbox"><label>\ | |||
<input type="checkbox" data-docstatus="0" checked="checked">\ | |||
<span class="text-muted">'+__('Drafts')+'</span>\ | |||
</label></div>\ | |||
<div class="checkbox"><label>\ | |||
<input type="checkbox" data-docstatus="1" checked="checked">\ | |||
<span class="text-muted">'+__('Submitted')+'</span>\ | |||
</label></div>\ | |||
<div class="checkbox"><label>\ | |||
<input type="checkbox" data-docstatus="2">\ | |||
<span class="text-muted">'+__('Cancelled')+'</span>\ | |||
</label></div>\ | |||
</div>\ | |||
</div>') | |||
.appendTo(this.$page.find(".layout-side-section")); | |||
this.$page.find(".layout-main-section") | |||
.addClass("listview-main-section") | |||
.parent().css({"margin-top":"-15px"}); | |||
@@ -93,7 +74,6 @@ frappe.views.DocListView = frappe.ui.Listing.extend({ | |||
this.meta = locals.DocType[this.doctype]; | |||
this.$page.find('.frappe-list-area').empty(), | |||
this.setup_listview(); | |||
this.setup_docstatus_filter(); | |||
this.init_list(false); | |||
this.init_stats(); | |||
this.init_minbar(); | |||
@@ -149,19 +129,6 @@ frappe.views.DocListView = frappe.ui.Listing.extend({ | |||
this.appframe.add_help_button(this.meta.description); | |||
} | |||
}, | |||
setup_docstatus_filter: function() { | |||
var me = this; | |||
this.can_submit = $.map(locals.DocPerm || [], function(d) { | |||
if(d.parent==me.meta.name && d.submit) return 1 | |||
else return null; | |||
}).length; | |||
if(this.can_submit) { | |||
this.$page.find('.show-docstatus').removeClass('hide'); | |||
this.$page.find('.show-docstatus input').click(function() { | |||
me.run(); | |||
}) | |||
} | |||
}, | |||
setup_listview: function() { | |||
this.listview = frappe.views.get_listview(this.doctype, this); | |||
this.wrapper = this.$page.find('.frappe-list-area'); | |||
@@ -252,16 +219,10 @@ frappe.views.DocListView = frappe.ui.Listing.extend({ | |||
this.listview.render(row, data, this); | |||
}, | |||
get_args: function() { | |||
var docstatus_list = this.can_submit ? $.map(this.$page.find('.show-docstatus :checked'), | |||
function(inp) { | |||
return $(inp).attr('data-docstatus'); | |||
}) : [] | |||
var args = { | |||
doctype: this.doctype, | |||
fields: this.listview.fields, | |||
filters: this.filter_list.get_filters(), | |||
docstatus: docstatus_list, | |||
order_by: this.listview.order_by || undefined, | |||
group_by: this.listview.group_by || undefined, | |||
} | |||
@@ -374,11 +374,9 @@ frappe.views.GridReport = Class.extend({ | |||
$('<div style="text-align: right;"> \ | |||
<div class="processing" style="background-color: #fec; display: none; \ | |||
float: left; margin: 2px">Updated! </div> \ | |||
<a href="#" class="grid-report-export"> \ | |||
<i class="icon icon-download-alt"></i> Export</a> \ | |||
</div>').appendTo(this.wrapper); | |||
this.wrapper.find(".grid-report-export").click(function() { return me.export(); }); | |||
this.appframe.add_primary_action(__("Export"), function() { return me.export(); }, "icon-download"); | |||
// grid wrapper | |||
this.grid_wrapper = $("<div style='height: 500px; border: 1px solid #aaa; \ | |||
@@ -246,6 +246,7 @@ frappe.views.ListView = Class.extend({ | |||
var col = $("<div class='col'>") | |||
.appendTo(body) | |||
.addClass("col-sm-" + cint(colspan)) | |||
.addClass("col-xs-" + (cint(colspan) + 2)) | |||
.css({ | |||
"white-space": "nowrap", | |||
"text-overflow": "ellipsis", | |||
@@ -171,7 +171,6 @@ frappe.views.ReportView = frappe.ui.Listing.extend({ | |||
fields: $.map(this.columns, function(v) { return me.get_full_column_name(v) }), | |||
order_by: this.get_order_by(), | |||
filters: this.filter_list.get_filters(), | |||
docstatus: ['0','1','2'], | |||
with_childnames: 1 | |||
} | |||
}, | |||
@@ -128,6 +128,8 @@ frappe.datetime = { | |||
val = d[2]+'-'+d[1]+'-'+d[0] + time_str; | |||
else if(user_fmt=='dd/mm/yyyy') | |||
val = d[2]+'/'+d[1]+'/'+d[0] + time_str; | |||
else if(user_fmt=='dd.mm.yyyy') | |||
val = d[2]+'.'+d[1]+'.'+d[0] + time_str; | |||
else if(user_fmt=='yyyy-mm-dd') | |||
val = d[0]+'-'+d[1]+'-'+d[2] + time_str; | |||
else if(user_fmt=='mm/dd/yyyy') | |||
@@ -162,6 +164,10 @@ frappe.datetime = { | |||
var d = d.split('/'); | |||
var val = d[2]+'-'+d[1]+'-'+d[0]; | |||
} | |||
else if(user_fmt=='dd.mm.yyyy') { | |||
var d = d.split('.'); | |||
var val = d[2]+'-'+d[1]+'-'+d[0]; | |||
} | |||
else if(user_fmt=='yyyy-mm-dd') { | |||
var val = d; | |||
} | |||
@@ -1,7 +1,6 @@ | |||
<!DOCTYPE html> | |||
<!-- | |||
Built on Frappe.io. Free and Open Source Framework for the Web. | |||
https://frappe.io/apps/frappe | |||
Built on Frappe.io. Free and Open Source Framework for the Web. https://frappe.io/ | |||
--> | |||
<html lang="en"> | |||
<head> | |||
@@ -29,10 +29,6 @@ body { | |||
} | |||
{% endif %} | |||
div.outer { | |||
background-color: #{{ doc.page_background }}; | |||
} | |||
{% if doc.google_web_font_for_heading or doc.heading_font %}h1, h2, h3, h4, h5 { | |||
font-family: '{{ doc.google_web_font_for_heading or doc.heading_font }}', 'Helvetica Neue', Arial !important; | |||
}{% endif %} | |||
@@ -41,29 +37,27 @@ div.outer { | |||
text-transform: {{ doc.heading_text_style }}; | |||
}{% endif %} | |||
{% if doc.page_headings %}h1, h2, h3, h4, h5 { | |||
color: #{{ doc.page_headings }}; | |||
}{% endif %} | |||
{% if doc.page_border %} | |||
/* Page Border*/ | |||
div.outer { | |||
box-shadow: 0 0 8px rgba(0, 0, 0, 0.2); | |||
-moz-box-shadow: 0 0 8px rgba(0, 0, 0, 0.2); | |||
-webkibox-shadow: 0 0 8px rgba(0, 0, 0, 0.2); | |||
{% if doc.page_header_color -%} | |||
.page-header h1, .page-header h2, .page-header h3, .page-header h4, .page-header h5, .page-header { | |||
color: #{{ doc.page_header_color }}; | |||
} | |||
{% else %} | |||
{% if doc.background_color.lower() == doc.page_background.lower() %} | |||
.web-footer { | |||
padding-top: 10px; | |||
{%- endif %} | |||
{% if doc.page_header_background -%} | |||
.page-header { | |||
background-color: #{{ doc.page_header_background }}; | |||
} | |||
{% endif %} | |||
{% endif %} | |||
{%- endif %} | |||
{% if doc.footer_color -%} | |||
.web-footer, .web-footer a { | |||
font-size: 90%; | |||
color: #{{ doc.background_color | get_hex_shade(100) }}; | |||
color: #{{ doc.footer_color }} !important; | |||
} | |||
{% endif -%} | |||
{% if doc.footer_background -%} | |||
.web-footer { | |||
background-color: #{{ doc.footer_background }}; | |||
} | |||
{% endif -%} | |||
/* Bootstrap Navbar */ | |||
.navbar-default { | |||
@@ -74,11 +68,6 @@ div.outer { | |||
background-color: #{{ doc.top_bar_background}}; | |||
background-repeat: repeat-x; | |||
background-image: none; | |||
border-bottom: 1px solid {% if doc.top_bar_background.lower() == doc.page_background.lower() -%} | |||
#{{ doc.page_background | get_hex_shade(15) }}; | |||
{%- else -%} | |||
transparent; | |||
{%- endif %} | |||
} | |||
.navbar .navbar-brand, | |||
@@ -185,7 +174,7 @@ div.outer { | |||
} | |||
.breadcrumb { | |||
background-color: #{{ doc.page_background | get_hex_shade(5) }}; | |||
background-color: #{{ doc.background_color | get_hex_shade(5) }}; | |||
} | |||
.breadcrumb > li { | |||
@@ -195,41 +184,41 @@ div.outer { | |||
.table-striped tbody > tr:nth-child(odd) > td, | |||
.table-striped tbody > tr:nth-child(odd) > th { | |||
background-color: #{{ doc.page_background | get_hex_shade(5) }}; | |||
background-color: #{{ doc.background_color | get_hex_shade(5) }}; | |||
} | |||
.table-hover tbody tr:hover td, | |||
.table-hover tbody tr:hover th { | |||
background-color: #{{ doc.page_background | get_hex_shade(10) }}; | |||
background-color: #{{ doc.background_color | get_hex_shade(10) }}; | |||
} | |||
.table-bordered { | |||
border: 1px solid #{{ doc.page_background | get_hex_shade(15) }}; | |||
border: 1px solid #{{ doc.background_color | get_hex_shade(15) }}; | |||
} | |||
.table th, | |||
.table td { | |||
border-top: 1px solid #{{ doc.page_background | get_hex_shade(15) }}; | |||
border-top: 1px solid #{{ doc.background_color | get_hex_shade(15) }}; | |||
} | |||
.table-bordered th, | |||
.table-bordered td { | |||
border-left: 1px solid #{{ doc.page_background | get_hex_shade(15) }}; | |||
border-left: 1px solid #{{ doc.background_color | get_hex_shade(15) }}; | |||
} | |||
.hero-unit { | |||
background-color: #{{ doc.page_background | get_hex_shade(15) }}; | |||
background-color: #{{ doc.background_color | get_hex_shade(15) }}; | |||
} | |||
pre, code { | |||
background-color: #{{ doc.page_background | get_hex_shade(5) }}; | |||
background-color: #{{ doc.background_color | get_hex_shade(5) }}; | |||
} | |||
hr { | |||
border-top: 1px solid #{{ doc.page_background | get_hex_shade(15) }}; | |||
border-bottom: 1px solid #{{ doc.page_background | get_hex_shade(5) }}; | |||
border-top: 1px solid #{{ doc.background_color | get_hex_shade(15) }}; | |||
border-bottom: 1px solid #{{ doc.background_color | get_hex_shade(5) }}; | |||
} | |||
{% if doc.add_css -%} | |||
@@ -1,5 +1,5 @@ | |||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
# MIT License. See license.txt | |||
from __future__ import unicode_literals | |||
import frappe | |||
@@ -11,55 +11,54 @@ def get_context(context): | |||
"""returns web style""" | |||
doc = frappe.get_doc("Style Settings", "Style Settings") | |||
prepare(doc) | |||
return { "doc": doc.as_dict() } | |||
print doc.page_header_color | |||
return { "doc": doc.as_dict() } | |||
def prepare(doc): | |||
from frappe.utils import cint, cstr | |||
# set default colours | |||
default_colours = { | |||
"background_color": "FFFFFF", | |||
"page_background": "FFFFFF", | |||
"top_bar_background": "FFFFFF", | |||
"top_bar_foreground": "444444", | |||
"page_headings": "222222", | |||
"page_text": "000000" | |||
} | |||
for d in default_colours: | |||
if not doc.get(d): | |||
doc.set(d, default_colours[d]) | |||
if not doc.font_size: | |||
doc.font_size = "14px" | |||
doc.small_font_size = cstr(cint(doc.font_size[:-2])-2) + 'px' | |||
doc.page_border = cint(doc.page_border) | |||
fonts = [] | |||
if doc.google_web_font_for_heading: | |||
fonts.append(doc.google_web_font_for_heading) | |||
if doc.google_web_font_for_text: | |||
fonts.append(doc.google_web_font_for_text) | |||
fonts = list(set(fonts)) | |||
if doc.heading_text_as: | |||
doc.heading_text_style = { | |||
"UPPERCASE": "uppercase", | |||
"Title Case":"capitalize", | |||
"lowercase": "lowercase" | |||
}.get(doc.heading_text_as) or "" | |||
doc.at_import = "" | |||
for f in fonts: | |||
doc.at_import += "\n@import url(https://fonts.googleapis.com/css?family=%s:400,700);" % f.replace(" ", "+") | |||
# move @import from add_css field to the top of the css file | |||
if doc.add_css and "@import url" in doc.add_css: | |||
import re | |||
at_imports = list(set(re.findall("@import url\([^\(\)]*\);", doc.add_css))) | |||
doc.at_import += "\n" + "\n".join(at_imports) | |||
for imp in at_imports: | |||
doc.add_css = doc.add_css.replace(imp, "") | |||
doc.add_css = doc.add_css.replace(imp, "") |
@@ -12,21 +12,22 @@ dateformats = { | |||
'yyyy-mm-dd': '%Y-%m-%d', | |||
'mm/dd/yyyy': '%m/%d/%Y', | |||
'mm-dd-yyyy': '%m-%d-%Y', | |||
"mm/dd/yy": "%m/%d/%y", | |||
"mm/dd/yy": "%m/%d/%y", | |||
'dd-mmm-yyyy': '%d-%b-%Y', # numbers app format | |||
'dd/mm/yyyy': '%d/%m/%Y', | |||
'dd.mm.yyyy': '%d.%m.%Y', | |||
'dd-mm-yyyy': '%d-%m-%Y', | |||
"dd/mm/yy": "%d/%m/%y", | |||
} | |||
def user_to_str(date, date_format=None): | |||
if not date: return date | |||
if not date_format: | |||
date_format = get_user_date_format() | |||
try: | |||
return datetime.datetime.strptime(date, | |||
return datetime.datetime.strptime(date, | |||
dateformats[date_format]).strftime('%Y-%m-%d') | |||
except ValueError, e: | |||
raise ValueError, "Date %s must be in format %s" % (date, date_format) | |||
@@ -34,11 +35,11 @@ def user_to_str(date, date_format=None): | |||
def parse_date(date): | |||
"""tries to parse given date to system's format i.e. yyyy-mm-dd. returns a string""" | |||
parsed_date = None | |||
# why the sorting? checking should be done in a predictable order | |||
check_formats = [None] + sorted(dateformats.keys(), | |||
reverse=not get_user_date_format().startswith("dd")) | |||
for f in check_formats: | |||
try: | |||
parsed_date = user_to_str(date, f) | |||
@@ -53,17 +54,17 @@ def parse_date(date): | |||
(date, get_user_date_format()) | |||
return parsed_date | |||
def get_user_date_format(): | |||
if getattr(frappe.local, "user_date_format", None) is None: | |||
frappe.local.user_date_format = frappe.defaults.get_global_default("date_format") or "yyyy-mm-dd" | |||
return frappe.local.user_date_format | |||
def datetime_in_user_format(date_time): | |||
if not date_time: | |||
return "" | |||
if isinstance(date_time, basestring): | |||
date_time = get_datetime(date_time) | |||
from frappe.utils import formatdate | |||
return formatdate(date_time.date()) + " " + date_time.strftime("%H:%M") | |||
return formatdate(date_time.date()) + " " + date_time.strftime("%H:%M") |
@@ -49,6 +49,7 @@ img { | |||
.web-footer { | |||
padding: 20px 0px; | |||
min-height: 140px; | |||
} | |||
.avatar { | |||
@@ -4,9 +4,11 @@ | |||
cur_frm.cscript.onload_post_render = function() { | |||
frappe.require('assets/frappe/js/lib/jscolor/jscolor.js'); | |||
$.each(["background_color", "page_background", "page_text", "page_links", | |||
"top_bar_background", "top_bar_foreground", "page_headings"], function(i, v) { | |||
$.each(["background_color", "page_text", "page_links", | |||
"top_bar_background", "top_bar_foreground", | |||
"page_header_background", "page_header_color", | |||
"footer_background", "footer_color"], function(i, v) { | |||
$(cur_frm.fields_dict[v].input).addClass('color'); | |||
}) | |||
jscolor.bind(); | |||
} | |||
} |
@@ -8,7 +8,7 @@ | |||
{ | |||
"fieldname": "enable", | |||
"fieldtype": "Section Break", | |||
"in_list_view": 1, | |||
"in_list_view": 0, | |||
"label": "Enable", | |||
"permlevel": 0 | |||
}, | |||
@@ -23,8 +23,8 @@ | |||
{ | |||
"fieldname": "color", | |||
"fieldtype": "Section Break", | |||
"in_list_view": 1, | |||
"label": "Color", | |||
"in_list_view": 0, | |||
"label": "Page Background", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
@@ -45,38 +45,31 @@ | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"fieldname": "page_background", | |||
"fieldname": "page_text", | |||
"fieldtype": "Data", | |||
"label": "Page Background", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"fieldname": "page_border", | |||
"fieldtype": "Check", | |||
"label": "Page Border", | |||
"label": "Page Text", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"fieldname": "page_headings", | |||
"fieldname": "page_links", | |||
"fieldtype": "Data", | |||
"label": "Page Headings", | |||
"label": "Page Links", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"fieldname": "page_text", | |||
"fieldtype": "Data", | |||
"label": "Page Text", | |||
"fieldname": "column_break_8", | |||
"fieldtype": "Column Break", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"fieldname": "page_links", | |||
"fieldtype": "Data", | |||
"label": "Page Links", | |||
"fieldname": "html_9", | |||
"fieldtype": "HTML", | |||
"options": "<img class=\"img-responsive\" src=\"/assets/frappe/images/help/style-settings-help.png\">", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"fieldname": "cb0", | |||
"fieldtype": "Column Break", | |||
"fieldtype": "Section Break", | |||
"label": "Top Bar", | |||
"permlevel": 0, | |||
"print_width": "50%", | |||
@@ -88,6 +81,11 @@ | |||
"label": "Top Bar Background", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"fieldname": "column_break_12", | |||
"fieldtype": "Column Break", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"description": "000 is black, fff is white", | |||
"fieldname": "top_bar_foreground", | |||
@@ -95,6 +93,52 @@ | |||
"label": "Top Bar Text", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"fieldname": "page_header", | |||
"fieldtype": "Section Break", | |||
"label": "Page Header", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"fieldname": "page_header_background", | |||
"fieldtype": "Data", | |||
"label": "Page Header Background", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"fieldname": "column_break_16", | |||
"fieldtype": "Column Break", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"fieldname": "page_header_color", | |||
"fieldtype": "Data", | |||
"label": "Page Header Text", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"fieldname": "footer", | |||
"fieldtype": "Section Break", | |||
"label": "Footer", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"fieldname": "footer_background", | |||
"fieldtype": "Data", | |||
"label": "Footer Background", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"fieldname": "column_break_20", | |||
"fieldtype": "Column Break", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"fieldname": "footer_color", | |||
"fieldtype": "Data", | |||
"label": "Footer Text", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"fieldname": "fonts", | |||
"fieldtype": "Section Break", | |||
@@ -174,7 +218,7 @@ | |||
"idx": 1, | |||
"issingle": 1, | |||
"max_attachments": 1, | |||
"modified": "2014-05-03 14:57:55.879426", | |||
"modified": "2014-05-28 01:58:45.392210", | |||
"modified_by": "Administrator", | |||
"module": "Website", | |||
"name": "Style Settings", | |||
@@ -10,22 +10,17 @@ from frappe import _ | |||
from frappe.model.document import Document | |||
class StyleSettings(Document): | |||
def validate(self): | |||
"""make custom css""" | |||
self.validate_colors() | |||
def validate_colors(self): | |||
if (self.page_background or self.page_text) and \ | |||
self.page_background==self.page_text: | |||
frappe.msgprint(_("Page text and background is same color. Please change."), | |||
raise_exception=1) | |||
def validate_colors(self): | |||
if (self.top_bar_background or self.top_bar_foreground) and \ | |||
self.top_bar_background==self.top_bar_foreground: | |||
frappe.msgprint(_("Top Bar text and background is same color. Please change."), | |||
raise_exception=1) | |||
def on_update(self): | |||
"""clear cache""" | |||
from frappe.sessions import clear_cache | |||
@@ -2,10 +2,36 @@ | |||
# MIT License. See license.txt | |||
from __future__ import unicode_literals | |||
import frappe, os, time | |||
import frappe, os, time, re | |||
import requests, requests.exceptions | |||
from frappe.website.website_generator import WebsiteGenerator | |||
from frappe.website.utils import cleanup_page_name | |||
from frappe.utils import cint | |||
class WebPage(WebsiteGenerator): | |||
save_versions = True | |||
def check_broken_links(): | |||
cnt = 0 | |||
for p in frappe.db.sql("select name, main_section from `tabWeb Page`", as_dict=True): | |||
for link in re.findall('href=["\']([^"\']*)["\']', p.main_section): | |||
if link.startswith("http"): | |||
try: | |||
res = requests.get(link) | |||
except requests.exceptions.SSLError: | |||
res = frappe._dict({"status_code": "SSL Error"}) | |||
except requests.exceptions.ConnectionError: | |||
res = frappe._dict({"status_code": "Connection Error"}) | |||
if res.status_code!=200: | |||
print "[{0}] {1}: {2}".format(res.status_code, p.name, link) | |||
cnt += 1 | |||
else: | |||
link = link[1:] # remove leading / | |||
link = link.split("#")[0] | |||
if not frappe.db.exists("Website Route", link): | |||
print p.name + ":" + link | |||
cnt += 1 | |||
print "{0} links broken".format(cnt) |