diff --git a/core/doctype/file_data/file_data.py b/core/doctype/file_data/file_data.py index 2f3dbce1db..d1138a0b31 100644 --- a/core/doctype/file_data/file_data.py +++ b/core/doctype/file_data/file_data.py @@ -40,7 +40,6 @@ class DocType(): and attached_to_doctype=%s and attached_to_name=%s""", (self.doc.file_name, self.doc.attached_to_doctype, self.doc.attached_to_name))[0][0] - webnotes.msgprint(n_records) if n_records > 1: webnotes.msgprint(webnotes._("Same file has already been attached to the record")) raise webnotes.DuplicateEntryError diff --git a/core/doctype/profile/profile.py b/core/doctype/profile/profile.py index b1334a7873..10bdd86a8b 100644 --- a/core/doctype/profile/profile.py +++ b/core/doctype/profile/profile.py @@ -187,7 +187,10 @@ Thank you,
'product': startup.product_name, 'user_fullname': get_user_fullname(webnotes.session['user']) } - sendmail_md(self.doc.email, subject=subject, msg=txt % args) + + sender = webnotes.session.user != "Administrator" and webnotes.session.user or None + + sendmail_md(recipients=self.doc.email, sender=sender, subject=subject, msg=txt % args) def on_trash(self): if self.doc.name in ["Administrator", "Guest"]: diff --git a/core/doctype/report/report.txt b/core/doctype/report/report.txt index 98e91bb12f..cc1dbdd052 100644 --- a/core/doctype/report/report.txt +++ b/core/doctype/report/report.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-02-25 13:11:50", + "creation": "2013-03-09 15:45:57", "docstatus": 0, - "modified": "2013-02-25 14:18:36", + "modified": "2013-04-30 17:50:00", "modified_by": "Administrator", "owner": "Administrator" }, @@ -41,6 +41,7 @@ "fieldname": "report_name", "fieldtype": "Data", "label": "Report Name", + "read_only": 0, "reqd": 1 }, { @@ -50,6 +51,7 @@ "in_list_view": 1, "label": "Ref DocType", "options": "DocType", + "read_only": 0, "reqd": 1 }, { @@ -59,12 +61,20 @@ "in_list_view": 1, "label": "Is Standard", "options": "No\nYes", + "read_only": 0, "reqd": 1 }, + { + "doctype": "DocField", + "fieldname": "add_total_row", + "fieldtype": "Check", + "label": "Add Total Row" + }, { "doctype": "DocField", "fieldname": "column_break_4", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "read_only": 0 }, { "doctype": "DocField", @@ -72,25 +82,29 @@ "fieldtype": "Select", "label": "Report Type", "options": "Report Builder\nQuery Report\nScript Report", + "read_only": 0, "reqd": 1 }, { "doctype": "DocField", "fieldname": "disabled", "fieldtype": "Check", - "label": "Disabled" + "label": "Disabled", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "section_break_6", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "read_only": 0 }, { "depends_on": "eval:doc.report_type==\"Query Report\"", "doctype": "DocField", "fieldname": "query", "fieldtype": "Code", - "label": "Query" + "label": "Query", + "read_only": 0 }, { "depends_on": "eval:doc.report_type==\"Report Builder\"", diff --git a/core/doctype/system_console/system_console.js b/core/doctype/system_console/system_console.js index 462082017f..f9a89c4d30 100644 --- a/core/doctype/system_console/system_console.js +++ b/core/doctype/system_console/system_console.js @@ -26,7 +26,7 @@ cur_frm.cscript['server_python'] = function(doc, dt, dn) { $c_obj(make_doclist(doc.doctype, doc.name), 'execute_server', '', function(r, rt) { doc = locals[doc.doctype][doc.name]; if(r.exc) { - doc.response = r.exc; + doc.response = (r.exc || []).join("\n"); } else { doc.response = 'Worked!'.bold() } diff --git a/core/page/data_import_tool/data_import_tool.py b/core/page/data_import_tool/data_import_tool.py index 524b5feab3..7aeff6672d 100644 --- a/core/page/data_import_tool/data_import_tool.py +++ b/core/page/data_import_tool/data_import_tool.py @@ -176,8 +176,12 @@ def upload(): return columns + # extra input params + import json + params = json.loads(webnotes.form_dict.get("params") or '{}') + # header - rows = read_csv_content_from_uploaded_file() + rows = read_csv_content_from_uploaded_file(params.get("ignore_encoding_errors")) start_row = get_start_row() header = rows[:start_row] data = rows[start_row:] @@ -195,7 +199,7 @@ def upload(): webnotes.conn.begin() - overwrite = webnotes.form_dict.get('overwrite') + overwrite = params.get('overwrite') doctype_dl = webnotes.model.doctype.get(doctype) # delete child rows (if parenttype) @@ -226,8 +230,7 @@ def upload(): ret.append('Inserted row for %s at #%s' % (getlink(parenttype, doc.parent), unicode(doc.idx))) else: - ret.append(import_doc(d, doctype, overwrite, row_idx, - webnotes.form_dict.get("_submit")=="on")) + ret.append(import_doc(d, doctype, overwrite, row_idx, params.get("_submit"))) except Exception, e: error = True ret.append('Error for row (#%d) %s : %s' % (row_idx, @@ -307,13 +310,10 @@ def delete_child_rows(rows, doctype): def import_doc(d, doctype, overwrite, row_idx, submit=False): """import main (non child) document""" - from webnotes.model.bean import Bean - if webnotes.conn.exists(doctype, d['name']): if overwrite: - doclist = webnotes.model.doc.get(doctype, d['name']) - doclist[0].fields.update(d) - bean = Bean(doclist) + bean = webnotes.bean(doctype, d['name']) + bean.doc.fields.update(d) if d.get("docstatus") == 1: bean.update_after_submit() else: @@ -323,12 +323,11 @@ def import_doc(d, doctype, overwrite, row_idx, submit=False): return 'Ignored row (#%d) %s (exists)' % (row_idx, getlink(doctype, d['name'])) else: - d['__islocal'] = 1 - dl = Bean([webnotes.model.doc.Document(fielddata = d)]) - dl.save() + bean = webnotes.bean([d]) + bean.insert() if submit: - dl.submit() + bean.submit() return 'Inserted row (#%d) %s' % (row_idx, getlink(doctype, - dl.doc.fields['name'])) + bean.doc.fields['name'])) diff --git a/public/js/wn/form/assign_to.js b/public/js/wn/form/assign_to.js index dd4816e9a6..8d6facadd0 100644 --- a/public/js/wn/form/assign_to.js +++ b/public/js/wn/form/assign_to.js @@ -136,7 +136,8 @@ wn.ui.form.AssignTo = Class.extend({ msgprint("Email sent to " + assign_to); me.render(r.message); } - } + }, + btn: this }); } } diff --git a/public/js/wn/request.js b/public/js/wn/request.js index a40ca93b9e..7e888e111b 100644 --- a/public/js/wn/request.js +++ b/public/js/wn/request.js @@ -85,7 +85,7 @@ wn.request.call = function(opts) { opts.error && opts.error(xhr) } }; - + if(opts.progress_bar) { var interval = null; $.extend(ajax_args, { @@ -109,7 +109,7 @@ wn.request.call = function(opts) { } }) } - + $.ajax(ajax_args); } @@ -151,9 +151,9 @@ wn.request.cleanup = function(opts, r) { } // show messages - if(r.server_messages) { - r.server_messages = JSON.parse(r.server_messages) - msgprint(r.server_messages); + if(r._server_messages) { + r._server_messages = JSON.parse(r._server_messages) + msgprint(r._server_messages); } // show errors @@ -164,10 +164,30 @@ wn.request.cleanup = function(opts, r) { if(v)console.log(v); }) } else { - console.log(r.exc); + console.log(r.exc); } }; + // debug messages + if(r._debug_messages) { + console.log("-") + console.log("-") + console.log("-") + if(opts.args) { + console.log("<<<< arguments "); + console.log(opts.args); + console.log(">>>>") + } + $.each(JSON.parse(r._debug_messages), function(i, v) { console.log(v); }); + console.log("<<<< response"); + delete r._debug_messages; + console.log(r); + console.log(">>>>") + console.log("-") + console.log("-") + console.log("-") + } + if(r['403']) { wn.set_route('403'); } diff --git a/public/js/wn/upload.js b/public/js/wn/upload.js index e21ab936b9..a0de229eab 100644 --- a/public/js/wn/upload.js +++ b/public/js/wn/upload.js @@ -25,10 +25,16 @@ wn.upload = { } // add other inputs in the div as arguments + opts.args.params = {}; $upload.find("input[name]").each(function() { var key = $(this).attr("name"); + var type = $(this).attr("type"); if(key!="filedata" && key!="file_url") { - opts.args[key] = $(this).val(); + if(type === "checkbox") { + opts.args.params[key] = $(this).is(":checked"); + } else { + opts.args.params[key] = $(this).val(); + } } }) diff --git a/public/js/wn/views/query_report.js b/public/js/wn/views/query_report.js index b59f4475d3..3ccb03acf1 100644 --- a/public/js/wn/views/query_report.js +++ b/public/js/wn/views/query_report.js @@ -141,15 +141,14 @@ wn.views.QueryReport = Class.extend({ $(f.wrapper).find("input, button").css({"margin-top":"-4px"}); else if(f.df.fieldtype == "Date") $(f.wrapper).css({"margin-right":"-15px"}); - + if(df.get_query) f.get_query = df.get_query; }); - this.set_filters_by_name(); }, clear_filters: function() { this.filters = []; - this.appframe.toolbar.find(".filters").remove(); + this.appframe.$w.find('.appframe-toolbar').find(".filters").remove(); }, set_filters_by_name: function() { this.filters_by_name = {}; diff --git a/webnotes/__init__.py b/webnotes/__init__.py index 70e3d9fa56..e149dbdb94 100644 --- a/webnotes/__init__.py +++ b/webnotes/__init__.py @@ -68,6 +68,7 @@ incoming_cookies = {} add_cookies = {} # append these to outgoing request cookies = {} response = _dict({'message':'', 'exc':''}) +error_log = [] debug_log = [] message_log = [] mute_emails = False @@ -107,7 +108,16 @@ def errprint(msg): print repr(msg) from utils import cstr - debug_log.append(cstr(msg or '')) + error_log.append(cstr(msg)) + +def log(msg): + if not request_method: + import conf + if getattr(conf, "logging", False): + print repr(msg) + + from utils import cstr + debug_log.append(cstr(msg)) def msgprint(msg, small=0, raise_exception=0, as_table=False): from utils import cstr diff --git a/webnotes/db.py b/webnotes/db.py index 1f62ba844e..d3007a7ce3 100644 --- a/webnotes/db.py +++ b/webnotes/db.py @@ -103,6 +103,12 @@ class Database: webnotes.errprint(query % values) except TypeError: webnotes.errprint([query, values]) + if getattr(conf, "logging", False)==2: + webnotes.log("<<<< query") + webnotes.log(query) + webnotes.log("with values:") + webnotes.log(values) + webnotes.log(">>>>") self._cursor.execute(query, values) @@ -110,6 +116,10 @@ class Database: if debug: self.explain_query(query) webnotes.errprint(query) + if getattr(conf, "logging", False)==2: + webnotes.log("<<<< query") + webnotes.log(query) + webnotes.log(">>>>") self._cursor.execute(query) except Exception, e: @@ -136,14 +146,17 @@ class Database: return self._cursor.fetchall() def explain_query(self, query, values=None): - webnotes.errprint("--- query explain ---") - if values is None: - self._cursor.execute("explain " + query) - else: - self._cursor.execute("explain " + query, values) - import json - webnotes.errprint(json.dumps(self.fetch_as_dict(), indent=1)) - webnotes.errprint("--- query explain end ---") + try: + webnotes.errprint("--- query explain ---") + if values is None: + self._cursor.execute("explain " + query) + else: + self._cursor.execute("explain " + query, values) + import json + webnotes.errprint(json.dumps(self.fetch_as_dict(), indent=1)) + webnotes.errprint("--- query explain end ---") + except: + webnotes.errprint("error in query explain") def sql_list(self, query, values=(), debug=False): return [r[0] for r in self.sql(query, values, debug=debug)] @@ -326,10 +339,10 @@ class Database: return [] if as_dict: - return values + return values and [values] or [] if isinstance(fields, list): - return map(lambda d: values.get(d), fields) + return [map(lambda d: values.get(d), fields)] else: r = self.sql("""select field, value @@ -340,10 +353,7 @@ class Database: if as_dict: return r and [webnotes._dict(r)] or [] else: - if r: - return [[i[1] for i in r]] - else: - return [] + return r and [[i[1] for i in r]] or [] def get_values_from_table(self, fields, filters, doctype, as_dict, debug): fl = fields diff --git a/webnotes/defaults.py b/webnotes/defaults.py index 8c9c0ba265..223d01803c 100644 --- a/webnotes/defaults.py +++ b/webnotes/defaults.py @@ -140,7 +140,7 @@ def get_defaults_for_match(userd): def clear_cache(parent=None): def all_profiles(): - return webnotes.conn.sql_list("select name from tabProfile") + ["Control Panel"] + return webnotes.conn.sql_list("select name from tabProfile") + ["Control Panel", "__global"] if parent=="Control Panel" or not parent: parent = all_profiles() diff --git a/webnotes/handler.py b/webnotes/handler.py index 07bf156e88..d8aa33164c 100755 --- a/webnotes/handler.py +++ b/webnotes/handler.py @@ -211,6 +211,7 @@ def get_method(cmd): method = webnotes.get_method(cmd) else: method = globals()[cmd] + webnotes.log("method:" + cmd) return method def print_response(): @@ -255,7 +256,7 @@ def print_iframe(): eprint("") eprint(webnotes.response.get('result') or '') - if webnotes.debug_log: + if webnotes.error_log: import json eprint("""\ """ % { 'messages': json.dumps(webnotes.message_log).replace("'", "\\'"), - 'errors': json.dumps(webnotes.debug_log).replace("'", "\\'"), + 'errors': json.dumps(webnotes.error_log).replace("'", "\\'"), }) def print_raw(): @@ -287,13 +288,17 @@ def print_raw(): def make_logs(): """make strings for msgprint and errprint""" - import json + import json, conf from webnotes.utils import cstr - if webnotes.debug_log: - webnotes.response['exc'] = json.dumps("\n".join([cstr(d) for d in webnotes.debug_log])) + if webnotes.error_log: + # webnotes.response['exc'] = json.dumps("\n".join([cstr(d) for d in webnotes.error_log])) + webnotes.response['exc'] = json.dumps([cstr(d) for d in webnotes.error_log]) if webnotes.message_log: - webnotes.response['server_messages'] = json.dumps([cstr(d) for d in webnotes.message_log]) + webnotes.response['_server_messages'] = json.dumps([cstr(d) for d in webnotes.message_log]) + + if webnotes.debug_log and getattr(conf, "logging", False): + webnotes.response['_debug_messages'] = json.dumps(webnotes.debug_log) def print_cookie_header(): """if there ar additional cookies defined during the request, add them""" diff --git a/webnotes/model/doc.py b/webnotes/model/doc.py index f0508ea1d0..f27f23d2b4 100755 --- a/webnotes/model/doc.py +++ b/webnotes/model/doc.py @@ -380,7 +380,7 @@ class Document: res = webnotes.model.meta.get_dt_values(self.doctype, 'autoname, issingle, istable, name_case', as_dict=1) res = res and res[0] or {} - + if new: self.fields["__islocal"] = 1 diff --git a/webnotes/model/utils.py b/webnotes/model/utils.py index d4396af83c..bc33881fc2 100644 --- a/webnotes/model/utils.py +++ b/webnotes/model/utils.py @@ -214,9 +214,7 @@ def check_if_doc_is_linked(dt, dn, method="Delete"): link_fields = get_link_fields(dt) link_fields = [[lf['parent'], lf['fieldname']] for lf in link_fields] - for l in link_fields: - link_dt, link_field = l - + for link_dt, link_field in link_fields: item = webnotes.conn.get_value(link_dt, {link_field:dn}, ["name", "parent", "parenttype", "docstatus"], as_dict=True) diff --git a/webnotes/utils/__init__.py b/webnotes/utils/__init__.py index f92aaaac3e..2a94c130a0 100644 --- a/webnotes/utils/__init__.py +++ b/webnotes/utils/__init__.py @@ -193,9 +193,12 @@ def now_datetime(): def get_user_time_zone(): global user_time_zone + if not user_time_zone: + user_time_zone = webnotes.cache().get_value("time_zone") if not user_time_zone: user_time_zone = webnotes.conn.get_value('Control Panel', None, 'time_zone') \ or 'Asia/Calcutta' + webnotes.cache().set_value("time_zone", user_time_zone) return user_time_zone def convert_utc_to_user_timezone(utc_timestamp): diff --git a/webnotes/utils/datautils.py b/webnotes/utils/datautils.py index c106af0b25..0155d73abf 100644 --- a/webnotes/utils/datautils.py +++ b/webnotes/utils/datautils.py @@ -26,10 +26,10 @@ import json import csv, cStringIO from webnotes.utils import encode, cstr -def read_csv_content_from_uploaded_file(): +def read_csv_content_from_uploaded_file(ignore_encoding=False): from webnotes.utils.file_manager import get_uploaded_content fname, fcontent = get_uploaded_content() - return read_csv_content(fcontent) + return read_csv_content(fcontent, ignore_encoding) def read_csv_content_from_attached_file(doc): fileid = webnotes.conn.get_value("File Data", {"attached_to_doctype": doc.doctype, diff --git a/webnotes/webutils.py b/webnotes/webutils.py index 2e50f1f990..41daa64bc8 100644 --- a/webnotes/webutils.py +++ b/webnotes/webutils.py @@ -28,7 +28,7 @@ def get_html(page_name): # load from cache, if auto cache clear is falsy if not (hasattr(conf, 'auto_cache_clear') and conf.auto_cache_clear or 0): - if not get_page_settings().get("page_name", {}).get("no_cache", None): + if not get_page_settings().get(page_name, {}).get("no_cache"): html = webnotes.cache().get_value("page:" + page_name) from_cache = True diff --git a/webnotes/widgets/form/assign_to.py b/webnotes/widgets/form/assign_to.py index 37be5b4616..227d966ab3 100644 --- a/webnotes/widgets/form/assign_to.py +++ b/webnotes/widgets/form/assign_to.py @@ -66,7 +66,7 @@ def add(args=None): # notify if not args.get("no_notification"): - notify_assignment(d.assigned_by, d.owner, d.reference_type, d.reference_name, action='ASSIGN', notify=args.get('notify')) + notify_assignment(d.assigned_by, d.owner, d.reference_type, d.reference_name, action='ASSIGN', description=args.get("description"), notify=args.get('notify')) # update feeed try: @@ -100,9 +100,14 @@ def remove(doctype, name, assign_to): if res and res[0]: notify_assignment(res[0][0], res[0][1], res[0][2], res[0][3]) return get({"doctype": doctype, "name": name}) + +def clear(doctype, name): + for assign_to in webnotes.conn.sql_list("""select owner from `tabToDo` + where reference_type=%(doctype)s and reference_name=%(name)s""", locals()): + remove(doctype, name, assign_to) - -def notify_assignment(assigned_by, owner, doc_type, doc_name, action='CLOSE', notify=0): +def notify_assignment(assigned_by, owner, doc_type, doc_name, action='CLOSE', + description=None, notify=0): """ Notify assignee that there is a change in assignment """ @@ -139,9 +144,10 @@ def notify_assignment(assigned_by, owner, doc_type, doc_name, action='CLOSE', no else: arg = { 'contact': owner, - 'txt': "A new task, %s, has been assigned to you by %s." \ + 'txt': "A new task, %s, has been assigned to you by %s. %s" \ % (assignment, - user_info.get(webnotes.session.get('user'), {}).get('fullname')), + user_info.get(webnotes.session.get('user'), {}).get('fullname'), + description and ("

Description: " + description + "

") or ""), 'notify': notify } diff --git a/webnotes/widgets/query_report.py b/webnotes/widgets/query_report.py index cd381c2fbc..b156e765ea 100644 --- a/webnotes/widgets/query_report.py +++ b/webnotes/widgets/query_report.py @@ -27,6 +27,7 @@ import os, json from webnotes import _ from webnotes.modules import scrub, get_module_path +from webnotes.utils import flt, cint @webnotes.whitelist() def get_script(report_name): @@ -67,7 +68,23 @@ def run(report_name, filters=None): + ".report." + scrub(report.name) + "." + scrub(report.name) + ".execute" columns, result = webnotes.get_method(method_name)(filters or {}) + if cint(report.add_total_row): + result = add_total_row(result, columns) + return { "result": result, "columns": columns - } \ No newline at end of file + } + +def add_total_row(result, columns): + total_row = [""]*len(columns) + for row in result: + for i, col in enumerate(columns): + if col.split(":")[1] in ["Currency", "Int", "Float"] and flt(row[i]): + total_row[i] = flt(total_row[i]) + flt(row[i]) + + if columns[0].split(":")[1] not in ["Currency", "Int", "Float"]: + total_row[0] = "Total" + + result.append(total_row) + return result \ No newline at end of file diff --git a/wnf.py b/wnf.py index 74823b1426..222bc7e378 100755 --- a/wnf.py +++ b/wnf.py @@ -164,6 +164,8 @@ def setup_options(): help="clear web cache") parser.add_option("--clear_cache", default=False, action="store_true", help="clear cache") + parser.add_option("--clear_defaults", default=False, action="store_true", + help="clear cache of defaults") parser.add_option("--domain", metavar="DOMAIN", help="store domain in Website Settings", nargs=1) @@ -433,6 +435,11 @@ def run(): elif options.clear_cache: clear_cache() + elif options.clear_defaults: + import webnotes.defaults + webnotes.defaults.clear_cache() + webnotes.clear_cache() + elif options.append_future_import: append_future_import()