diff --git a/frappe/core/doctype/customize_form/customize_form.js b/frappe/core/doctype/customize_form/customize_form.js index c3f7f15d3a..152943e588 100644 --- a/frappe/core/doctype/customize_form/customize_form.js +++ b/frappe/core/doctype/customize_form/customize_form.js @@ -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); } }); diff --git a/frappe/core/doctype/system_settings/system_settings.json b/frappe/core/doctype/system_settings/system_settings.json index df30c669e9..940b9ab63b 100644 --- a/frappe/core/doctype/system_settings/system_settings.json +++ b/frappe/core/doctype/system_settings/system_settings.json @@ -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 + ] } \ No newline at end of file diff --git a/frappe/core/doctype/workflow/workflow.py b/frappe/core/doctype/workflow/workflow.py index 629b63b9d1..d34b7126a4 100644 --- a/frappe/core/doctype/workflow/workflow.py +++ b/frappe/core/doctype/workflow/workflow.py @@ -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 diff --git a/frappe/core/doctype/workflow_document_state/workflow_document_state.json b/frappe/core/doctype/workflow_document_state/workflow_document_state.json index 67fb37028a..dfe287074d 100644 --- a/frappe/core/doctype/workflow_document_state/workflow_document_state.json +++ b/frappe/core/doctype/workflow_document_state/workflow_document_state.json @@ -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": [] } \ No newline at end of file diff --git a/frappe/public/css/appframe.css b/frappe/public/css/appframe.css index ff4c28d237..464dd49de5 100644 --- a/frappe/public/css/appframe.css +++ b/frappe/public/css/appframe.css @@ -38,7 +38,7 @@ } .titlebar-item.text-right { - margin-top: 5px; + margin-top: 3px; } .titlebar-left-item { diff --git a/frappe/public/images/help/style-settings-help.png b/frappe/public/images/help/style-settings-help.png new file mode 100644 index 0000000000..cc49373b59 Binary files /dev/null and b/frappe/public/images/help/style-settings-help.png differ diff --git a/frappe/public/js/frappe/misc/number_format.js b/frappe/public/js/frappe/misc/number_format.js index 51fedad510..9dad593d68 100644 --- a/frappe/public/js/frappe/misc/number_format.js +++ b/frappe/public/js/frappe/misc/number_format.js @@ -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 " + Math.floor( day_diff / 365 ) + " year(s) ago"; - + } var comment_when = function(datetime) { - return '' + prettyDate(datetime) + ''; + return '' + + prettyDate(datetime) + ''; }; frappe.provide("frappe.datetime"); diff --git a/frappe/public/js/frappe/ui/appframe.js b/frappe/public/js/frappe/ui/appframe.js index d40b8e556a..1c4d9799da 100644 --- a/frappe/public/js/frappe/ui/appframe.js +++ b/frappe/public/js/frappe/ui/appframe.js @@ -16,7 +16,7 @@ frappe.ui.AppFrame = Class.extend({ \ ').appendTo($center); - this.$sub_title_area = $('
') + this.$sub_title_area = $('
') .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) { diff --git a/frappe/public/js/frappe/ui/filters.js b/frappe/public/js/frappe/ui/filters.js index 1b9409e1a6..2370e02f8e 100644 --- a/frappe/public/js/frappe/ui/filters.js +++ b/frappe/public/js/frappe/ui/filters.js @@ -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 = $('
').appendTo(me.field.wrapper); + } + // set description + me.field.desc_area.html((condition==="in" + ? __("values separated by commas") + : __("use % as wildcard"))+'
'); } 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) { diff --git a/frappe/public/js/frappe/ui/listing.js b/frappe/public/js/frappe/ui/listing.js index 31518fff2b..655437874f 100644 --- a/frappe/public/js/frappe/ui/listing.js +++ b/frappe/public/js/frappe/ui/listing.js @@ -64,6 +64,20 @@ frappe.ui.Listing = Class.extend({ $.extend(this, this.opts); $(this.parent).html(repl('\ +
\ +
\ +
\ +
\ +
\
\

%(title)s

\ \ @@ -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) diff --git a/frappe/public/js/frappe/views/doclistview.js b/frappe/public/js/frappe/views/doclistview.js index 86c9b0cf80..8621e5465b 100644 --- a/frappe/public/js/frappe/views/doclistview.js +++ b/frappe/public/js/frappe/views/doclistview.js @@ -57,25 +57,6 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
'+__('Loading')+'...
') .appendTo(this.$page.find(".layout-main-section")); - $('
\ -
Show
\ -
\ -
\ -
\ -
\ -
\ -
') - .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, } diff --git a/frappe/public/js/frappe/views/grid_report.js b/frappe/public/js/frappe/views/grid_report.js index 3dc7314cd0..fb36df5ace 100644 --- a/frappe/public/js/frappe/views/grid_report.js +++ b/frappe/public/js/frappe/views/grid_report.js @@ -374,11 +374,9 @@ frappe.views.GridReport = Class.extend({ $('
\ \ - \ - Export \
').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 = $("
") .appendTo(body) .addClass("col-sm-" + cint(colspan)) + .addClass("col-xs-" + (cint(colspan) + 2)) .css({ "white-space": "nowrap", "text-overflow": "ellipsis", diff --git a/frappe/public/js/frappe/views/reportview.js b/frappe/public/js/frappe/views/reportview.js index 07960f6bc0..b4bbad8b75 100644 --- a/frappe/public/js/frappe/views/reportview.js +++ b/frappe/public/js/frappe/views/reportview.js @@ -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 } }, diff --git a/frappe/public/js/legacy/datetime.js b/frappe/public/js/legacy/datetime.js index ff56951989..7b466c706f 100644 --- a/frappe/public/js/legacy/datetime.js +++ b/frappe/public/js/legacy/datetime.js @@ -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; } diff --git a/frappe/templates/base.html b/frappe/templates/base.html index 343e5111f1..e87ab640b1 100644 --- a/frappe/templates/base.html +++ b/frappe/templates/base.html @@ -1,7 +1,6 @@ diff --git a/frappe/templates/pages/style_settings.css b/frappe/templates/pages/style_settings.css index 3be1204824..566485b4d1 100644 --- a/frappe/templates/pages/style_settings.css +++ b/frappe/templates/pages/style_settings.css @@ -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 -%} diff --git a/frappe/templates/pages/style_settings.py b/frappe/templates/pages/style_settings.py index 23f2fbbe20..d3d534c31f 100644 --- a/frappe/templates/pages/style_settings.py +++ b/frappe/templates/pages/style_settings.py @@ -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, "") \ No newline at end of file + doc.add_css = doc.add_css.replace(imp, "") diff --git a/frappe/utils/dateutils.py b/frappe/utils/dateutils.py index 096fb44aa8..d244d67d13 100644 --- a/frappe/utils/dateutils.py +++ b/frappe/utils/dateutils.py @@ -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") \ No newline at end of file + return formatdate(date_time.date()) + " " + date_time.strftime("%H:%M") diff --git a/frappe/website/css/website.css b/frappe/website/css/website.css index 81ce6de7a1..282a29e63a 100644 --- a/frappe/website/css/website.css +++ b/frappe/website/css/website.css @@ -49,6 +49,7 @@ img { .web-footer { padding: 20px 0px; + min-height: 140px; } .avatar { diff --git a/frappe/website/doctype/style_settings/style_settings.js b/frappe/website/doctype/style_settings/style_settings.js index 9fb95ac8f2..5d5034cb49 100644 --- a/frappe/website/doctype/style_settings/style_settings.js +++ b/frappe/website/doctype/style_settings/style_settings.js @@ -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(); -} \ No newline at end of file +} diff --git a/frappe/website/doctype/style_settings/style_settings.json b/frappe/website/doctype/style_settings/style_settings.json index cfdf5c8d73..97a9c241b6 100644 --- a/frappe/website/doctype/style_settings/style_settings.json +++ b/frappe/website/doctype/style_settings/style_settings.json @@ -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": "", "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", diff --git a/frappe/website/doctype/style_settings/style_settings.py b/frappe/website/doctype/style_settings/style_settings.py index 8eeff8e484..1b4c17f66b 100644 --- a/frappe/website/doctype/style_settings/style_settings.py +++ b/frappe/website/doctype/style_settings/style_settings.py @@ -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 diff --git a/frappe/website/doctype/web_page/web_page.py b/frappe/website/doctype/web_page/web_page.py index 7ec632b776..d2eebc093f 100644 --- a/frappe/website/doctype/web_page/web_page.py +++ b/frappe/website/doctype/web_page/web_page.py @@ -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)