@@ -26,9 +26,6 @@ import webnotes | |||||
from webnotes.utils import now, cint | from webnotes.utils import now, cint | ||||
msgprint = webnotes.msgprint | msgprint = webnotes.msgprint | ||||
class DocType: | class DocType: | ||||
def __init__(self, doc=None, doclist=[]): | def __init__(self, doc=None, doclist=[]): | ||||
self.doc = doc | self.doc = doc | ||||
@@ -68,6 +65,9 @@ class DocType: | |||||
msgprint('<b>Series already in use:</b> The series "%s" is already used in "%s"' % (prefix, used_in[0][0]), raise_exception=1) | msgprint('<b>Series already in use:</b> The series "%s" is already used in "%s"' % (prefix, used_in[0][0]), raise_exception=1) | ||||
def validate(self): | def validate(self): | ||||
for c in [".", "/", "#", "&", "=", ":", "'", '"']: | |||||
if c in self.name: | |||||
webnotes.msgprint(c + " not allowed in name", raise_exception=1) | |||||
self.validate_series() | self.validate_series() | ||||
self.scrub_field_names() | self.scrub_field_names() | ||||
validate_fields(filter(lambda d: d.doctype=="DocField", self.doclist)) | validate_fields(filter(lambda d: d.doctype=="DocField", self.doclist)) | ||||
@@ -182,7 +182,7 @@ def validate_fields_for_doctype(doctype): | |||||
def validate_fields(fields): | def validate_fields(fields): | ||||
def check_illegal_characters(fieldname): | def check_illegal_characters(fieldname): | ||||
for c in ['.', ',', ' ', '-', '&', '%', '=', '"', "'", '*', '$', | for c in ['.', ',', ' ', '-', '&', '%', '=', '"', "'", '*', '$', | ||||
'(', ')', '[', ']']: | |||||
'(', ')', '[', ']', '/']: | |||||
if c in fieldname: | if c in fieldname: | ||||
webnotes.msgprint("'%s' not allowed in fieldname (%s)" % (c, fieldname)) | webnotes.msgprint("'%s' not allowed in fieldname (%s)" % (c, fieldname)) | ||||
@@ -54,13 +54,10 @@ | |||||
"lib/public/js/wn/provide.js", | "lib/public/js/wn/provide.js", | ||||
"lib/public/js/wn/assets.js", | "lib/public/js/wn/assets.js", | ||||
"lib/public/js/wn/dom.js", | "lib/public/js/wn/dom.js", | ||||
"lib/public/js/wn/model.js", | |||||
"lib/public/js/wn/perm.js", | |||||
"lib/public/js/wn/meta.js", | "lib/public/js/wn/meta.js", | ||||
"lib/public/js/wn/misc/user.js", | "lib/public/js/wn/misc/user.js", | ||||
"lib/public/js/wn/misc/utils.js", | "lib/public/js/wn/misc/utils.js", | ||||
"lib/public/js/lib/public/json2.js", | "lib/public/js/lib/public/json2.js", | ||||
"lib/public/js/wn/router.js", | |||||
"lib/public/js/wn/ui/messages.js", | "lib/public/js/wn/ui/messages.js", | ||||
"lib/public/js/wn/ui/listing.js", | "lib/public/js/wn/ui/listing.js", | ||||
"lib/public/js/wn/views/container.js", | "lib/public/js/wn/views/container.js", | ||||
@@ -79,8 +76,6 @@ | |||||
"lib/public/js/wn/ui/button.js", | "lib/public/js/wn/ui/button.js", | ||||
"lib/public/js/legacy/widgets/dialog.js", | "lib/public/js/legacy/widgets/dialog.js", | ||||
"lib/public/js/legacy/webpage/loaders.js", | "lib/public/js/legacy/webpage/loaders.js", | ||||
"lib/public/js/legacy/model/local_data.js", | |||||
"lib/public/js/legacy/model/doclist.js", | |||||
"lib/public/js/wn/app.js" | "lib/public/js/wn/app.js" | ||||
] | ] | ||||
}, | }, | ||||
@@ -98,6 +93,13 @@ | |||||
"lib/public/js/lib/tiny_mce_3.5.7/jquery.tinymce.js:concat", | "lib/public/js/lib/tiny_mce_3.5.7/jquery.tinymce.js:concat", | ||||
"lib/public/js/lib/mousetrap.min.js", | "lib/public/js/lib/mousetrap.min.js", | ||||
"lib/public/js/wn/router.js", | |||||
"lib/public/js/wn/model/model.js", | |||||
"lib/public/js/wn/model/doclist.js", | |||||
"lib/public/js/wn/model/sync.js", | |||||
"lib/public/js/wn/model/create_new.js", | |||||
"lib/public/js/wn/model/perm.js", | |||||
"lib/public/js/wn/misc/tools.js", | "lib/public/js/wn/misc/tools.js", | ||||
"lib/public/js/legacy/utils/printElement.js", | "lib/public/js/legacy/utils/printElement.js", | ||||
"lib/public/js/legacy/widgets/form/fields.js", | "lib/public/js/legacy/widgets/form/fields.js", | ||||
@@ -10,6 +10,8 @@ wn.provide('_r'); | |||||
wn.provide('_c'); | wn.provide('_c'); | ||||
wn.provide('_e'); | wn.provide('_e'); | ||||
wn.provide('_startup_data') | wn.provide('_startup_data') | ||||
wn.provide('locals') | |||||
wn.provide('locals.DocType') | |||||
// setup custom binding for history | // setup custom binding for history | ||||
wn.settings.no_history = 1; | wn.settings.no_history = 1; | ||||
@@ -52,6 +54,4 @@ var FILTER_SEP = '\1'; | |||||
var frms={}; | var frms={}; | ||||
var cur_frm=null; | var cur_frm=null; | ||||
var pscript = {}; | var pscript = {}; | ||||
var validated = true; | |||||
var validation_message = ''; | |||||
var tinymce_loaded = null; | var tinymce_loaded = null; |
@@ -1,175 +0,0 @@ | |||||
// Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com) | |||||
// | |||||
// MIT License (MIT) | |||||
// | |||||
// Permission is hereby granted, free of charge, to any person obtaining a | |||||
// copy of this software and associated documentation files (the "Software"), | |||||
// to deal in the Software without restriction, including without limitation | |||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
// and/or sell copies of the Software, and to permit persons to whom the | |||||
// Software is furnished to do so, subject to the following conditions: | |||||
// | |||||
// The above copyright notice and this permission notice shall be included in | |||||
// all copies or substantial portions of the Software. | |||||
// | |||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |||||
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |||||
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE | |||||
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||||
// | |||||
function compress_doclist(list) { | |||||
var kl = {}; var vl = []; var flx = {}; | |||||
for(var i=0; i<list.length;i++) { | |||||
var o = list[i]; | |||||
var fl = []; | |||||
if(!kl[o.doctype]) { // make key only once # doctype must be first | |||||
var tfl = ['doctype', 'name', 'docstatus', 'owner', 'parent', 'parentfield', 'parenttype', | |||||
'idx', 'creation', 'modified', 'modified_by', '__islocal', '__newname', '__modified', | |||||
'_user_tags', '__temp']; | |||||
var fl = [].concat(tfl); | |||||
for(key in wn.meta.docfield_map[o.doctype]) { // all other values | |||||
if(!in_list(fl, key) | |||||
&& !in_list(no_value_fields, wn.meta.docfield_map[o.doctype][key].fieldtype) | |||||
&& !wn.meta.docfield_map[o.doctype][key].no_column) { | |||||
fl[fl.length] = key; // save value list | |||||
tfl[tfl.length] = key //.replace(/'/g, "\\'").replace(/\n/g, "\\n"); | |||||
} | |||||
} | |||||
flx[o.doctype] = fl; | |||||
kl[o.doctype] = tfl | |||||
} | |||||
var nl = []; | |||||
var fl = flx[o.doctype]; | |||||
// check all | |||||
for(var j=0;j<fl.length;j++) { | |||||
var v = o[fl[j]]; | |||||
nl.push(v); | |||||
} | |||||
vl.push(nl); | |||||
} | |||||
return JSON.stringify({'_vl':vl, '_kl':kl}); | |||||
} | |||||
function expand_doclist(docs) { | |||||
var l = []; | |||||
for(var i=0;i<docs._vl.length;i++) | |||||
l[l.length] = zip(docs._kl[docs._vl[i][0]], docs._vl[i]); | |||||
return l; | |||||
} | |||||
function zip(k,v) { | |||||
var obj = {}; | |||||
for(var i=0;i<k.length;i++) { | |||||
obj[k[i]] = v[i]; | |||||
} | |||||
return obj; | |||||
} | |||||
function save_doclist(dt, dn, save_action, onsave, onerr, btn) { | |||||
var doc = locals[dt][dn]; | |||||
var doctype = locals['DocType'][dt]; | |||||
var tmplist = []; | |||||
// make doc list | |||||
var doclist = make_doclist(dt, dn, 1); | |||||
var all_reqd_ok = true; | |||||
if(save_action!='Cancel') { | |||||
for(var n in doclist) { | |||||
// type / mandatory checking | |||||
var reqd_ok = check_required(doclist[n].doctype, doclist[n].name, doclist[0].doctype); | |||||
if(doclist[n].docstatus+''!='2' && all_reqd_ok) // if not deleted | |||||
all_reqd_ok = reqd_ok; | |||||
} | |||||
} | |||||
// mandatory not filled | |||||
if(!all_reqd_ok) { | |||||
onerr() | |||||
return; | |||||
} | |||||
var _save = function() { | |||||
//console.log(compress_doclist(doclist)); | |||||
btn && $(btn).attr("disabled", true); | |||||
$c('webnotes.widgets.form.save.savedocs', {'docs':compress_doclist(doclist), 'docname':dn, 'action': save_action, 'user':user }, | |||||
function(r) { | |||||
btn && $(btn).attr("disabled", false); | |||||
if(r.saved) { | |||||
if(onsave)onsave(r); | |||||
} else { | |||||
if(onerr)onerr(r); | |||||
} | |||||
}, function() { | |||||
// | |||||
},0,(f ? 'Saving...' : '') | |||||
); | |||||
} | |||||
// ask for name | |||||
if(doc.__islocal && (doctype && doctype.autoname && doctype.autoname.toLowerCase()=='prompt')) { | |||||
var newname = prompt('Enter the name of the new '+ dt, ''); | |||||
if(newname) { | |||||
doc.__newname = strip(newname); _save(); | |||||
} else { | |||||
msgprint('Not Saved'); onerr(); | |||||
} | |||||
} else { | |||||
_save(); | |||||
} | |||||
} | |||||
function check_required(dt, dn, parent_dt) { | |||||
var doc = locals[dt][dn]; | |||||
if(doc.docstatus>1)return true; | |||||
var fl = wn.meta.docfield_list[dt]; | |||||
if(!fl)return true; // no doctype loaded | |||||
var all_clear = true; | |||||
var errfld = []; | |||||
for(var i=0;i<fl.length;i++) { | |||||
var key = fl[i].fieldname; | |||||
var df = wn.meta.get_docfield(dt, key, dn); | |||||
var has_value = wn.model.has_value(dt, dn, key); | |||||
if(df.reqd && !has_value) { | |||||
errfld[errfld.length] = df.label; | |||||
// Bring to front "Section" | |||||
if(cur_frm) { | |||||
// show as red | |||||
var f = cur_frm.fields_dict[df.fieldname]; | |||||
if(f) { | |||||
// in form | |||||
f.df.has_error = true; | |||||
f.refresh_label_icon && f.refresh_label_icon(); | |||||
if(all_clear && f.wrapper) { | |||||
$(document).scrollTop($(f.wrapper).offset().top - 100); | |||||
} | |||||
if(f.df.hidden) { | |||||
msgprint('Oops, field "'+ f.df.label+'" is both hidden and mandatory. \ | |||||
Please contact your admin for help.'); | |||||
} | |||||
} | |||||
} | |||||
if(all_clear)all_clear = false; | |||||
} | |||||
} | |||||
if(errfld.length)msgprint('<b>Mandatory fields required in '+ | |||||
(doc.parenttype ? (wn.meta.docfield_map[doc.parenttype][doc.parentfield].label + ' (Table)') : | |||||
doc.doctype) + ':</b>\n' + errfld.join('\n')); | |||||
return all_clear; | |||||
} |
@@ -1,288 +0,0 @@ | |||||
// Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com) | |||||
// | |||||
// MIT License (MIT) | |||||
// | |||||
// Permission is hereby granted, free of charge, to any person obtaining a | |||||
// copy of this software and associated documentation files (the "Software"), | |||||
// to deal in the Software without restriction, including without limitation | |||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
// and/or sell copies of the Software, and to permit persons to whom the | |||||
// Software is furnished to do so, subject to the following conditions: | |||||
// | |||||
// The above copyright notice and this permission notice shall be included in | |||||
// all copies or substantial portions of the Software. | |||||
// | |||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |||||
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |||||
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE | |||||
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||||
// | |||||
// Local DB | |||||
//----------- | |||||
var locals = {'DocType':{}}; | |||||
var LocalDB={}; | |||||
var READ = 0; var WRITE = 1; var CREATE = 2; var SUBMIT = 3; var CANCEL = 4; var AMEND = 5; | |||||
LocalDB.getchildren = function(child_dt, parent, parentfield, parenttype) { | |||||
var l = []; | |||||
for(var key in locals[child_dt]) { | |||||
var d = locals[child_dt][key]; | |||||
if((d.parent == parent)&&(d.parentfield == parentfield)) { | |||||
if(parenttype) { | |||||
if(d.parenttype==parenttype)l.push(d); | |||||
} else { // ignore for now | |||||
l.push(d); | |||||
} | |||||
} | |||||
} | |||||
l.sort(function(a,b){return (cint(a.idx)-cint(b.idx))}); return l; | |||||
} | |||||
// Add Doc | |||||
// ====================================================================================== | |||||
LocalDB.add=function(dt, dn) { | |||||
if(!locals[dt]) locals[dt] = {}; if(locals[dt][dn]) delete locals[dt][dn]; | |||||
locals[dt][dn] = {'name':dn, 'doctype':dt, 'docstatus':0}; | |||||
return locals[dt][dn]; | |||||
} | |||||
// Delete Doc | |||||
// ====================================================================================== | |||||
LocalDB.delete_doc=function(dt, dn) { | |||||
var doc = get_local(dt, dn); | |||||
if(!doc) return; | |||||
for(var ndt in locals) { // all doctypes | |||||
if(locals[ndt]) { | |||||
for(var ndn in locals[ndt]) { | |||||
var doc = locals[ndt][ndn]; | |||||
if(doc && doc.parenttype==dt && (doc.parent==dn||doc.__oldparent==dn)) { | |||||
delete locals[ndt][ndn]; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
delete locals[dt][dn]; | |||||
} | |||||
function get_local(dt, dn) { return locals[dt] ? locals[dt][dn] : null; } | |||||
// Sync Records from Server | |||||
// ====================================================================================== | |||||
LocalDB.sync = function(list) { | |||||
if(keys(list._kl)) | |||||
list = expand_doclist(list); | |||||
if(list.length) { | |||||
LocalDB.clear_locals(list[0].doctype, list[0].name); | |||||
} else { | |||||
return; | |||||
} | |||||
for(var i=0;i<list.length;i++) { | |||||
var d = list[i]; | |||||
if(!d.name) // get name (local if required) | |||||
d.name = LocalDB.get_localname(d.doctype); | |||||
LocalDB.add(d.doctype, d.name); | |||||
locals[d.doctype][d.name] = d; | |||||
// reset cur_frm.doc (as new doc is loaded from the server) | |||||
if(cur_frm && cur_frm.doctype==d.doctype && cur_frm.docname==d.name) { | |||||
cur_frm.doc = d; | |||||
} | |||||
if(d.doctype=='DocField') | |||||
wn.meta.add_field(d); | |||||
if(d.localname) { | |||||
wn.model.new_names[d.localname] = d.name; | |||||
$(document).trigger('rename', [d.doctype, d.localname, d.name]); | |||||
delete locals[d.doctype][d.localname]; | |||||
} | |||||
} | |||||
} | |||||
LocalDB.clear_locals = function(dt, dn) { | |||||
var doclist = make_doclist(dt, dn, 1); | |||||
// console.dir(['in clear', doclist]); | |||||
$.each(doclist, function(i, v) { | |||||
v && delete locals[v.doctype][v.name]; | |||||
}); | |||||
} | |||||
// Get Local Name | |||||
// ====================================================================================== | |||||
local_name_idx = {}; | |||||
LocalDB.get_localname=function(doctype) { | |||||
if(!local_name_idx[doctype]) local_name_idx[doctype] = 1; | |||||
var n = 'New '+ get_doctype_label(doctype) + ' ' + local_name_idx[doctype]; | |||||
local_name_idx[doctype]++; | |||||
return n; | |||||
} | |||||
// Create Local Doc | |||||
// ====================================================================================== | |||||
LocalDB.set_default_values = function(doc) { | |||||
var doctype = doc.doctype; | |||||
var docfields = wn.meta.docfield_list[doctype]; | |||||
if(!docfields) { | |||||
return; | |||||
} | |||||
var fields_to_refresh = []; | |||||
for(var fid=0;fid<docfields.length;fid++) { | |||||
var f = docfields[fid]; | |||||
if(!in_list(no_value_fields, f.fieldtype) && doc[f.fieldname]==null) { | |||||
var v = LocalDB.get_default_value(f.fieldname, f.fieldtype, f['default']); | |||||
if(v) { | |||||
doc[f.fieldname] = v; | |||||
fields_to_refresh.push(f.fieldname); | |||||
} | |||||
} | |||||
} | |||||
return fields_to_refresh; | |||||
} | |||||
// ====================================================================================== | |||||
LocalDB.create = function(doctype, n) { | |||||
if(!n) n = LocalDB.get_localname(doctype); | |||||
var doc = LocalDB.add(doctype, n) | |||||
doc.__islocal=1; doc.owner = user; | |||||
LocalDB.set_default_values(doc); | |||||
return n; | |||||
} | |||||
// ====================================================================================== | |||||
LocalDB.delete_record = function(dt, dn) { | |||||
delete locals[dt][dn]; | |||||
} | |||||
// ====================================================================================== | |||||
LocalDB.get_default_value = function(fn, ft, df) { | |||||
if(df=='_Login' || df=='__user') | |||||
return user; | |||||
else if(df=='_Full Name') | |||||
return user_fullname; | |||||
else if(ft=='Date'&& (df=='Today' || df=='__today')) { | |||||
return get_today(); } | |||||
else if(df) | |||||
return df; | |||||
else if(user_defaults[fn]) | |||||
return user_defaults[fn][0]; | |||||
else if(sys_defaults[fn]) | |||||
return sys_defaults[fn]; | |||||
} | |||||
// ====================================================================================== | |||||
LocalDB.add_child = function(doc, childtype, parentfield) { | |||||
// create row doc | |||||
var n = LocalDB.create(childtype); | |||||
var d = locals[childtype][n]; | |||||
d.parent = doc.name; | |||||
d.parentfield = parentfield; | |||||
d.parenttype = doc.doctype; | |||||
return d; | |||||
} | |||||
// ====================================================================================== | |||||
LocalDB.no_copy_list = ['amended_from','amendment_date','cancel_reason']; | |||||
LocalDB.copy=function(dt, dn, from_amend) { | |||||
var newdoc = LocalDB.create(dt); | |||||
for(var key in locals[dt][dn]) { | |||||
// dont copy name and blank fields | |||||
var df = wn.meta.get_docfield(dt, key); | |||||
if(key!=='name' && key.substr(0,2)!='__' && | |||||
!(df && ((!from_amend && cint(df.no_copy)==1) || in_list(LocalDB.no_copy_list, df.fieldname)))) { | |||||
locals[dt][newdoc][key] = locals[dt][dn][key]; | |||||
} | |||||
} | |||||
return locals[dt][newdoc]; | |||||
} | |||||
// ====================================================================================== | |||||
function make_doclist(dt, dn) { | |||||
if(!locals[dt]) { return []; } | |||||
var dl = []; | |||||
dl[0] = locals[dt][dn]; | |||||
// get children | |||||
for(var ndt in locals) { // all doctypes | |||||
if(locals[ndt]) { | |||||
for(var ndn in locals[ndt]) { | |||||
var doc = locals[ndt][ndn]; | |||||
if(doc && doc.parenttype==dt && doc.parent==dn) { | |||||
dl.push(doc) | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return dl; | |||||
} | |||||
// Meta Data | |||||
// ====================================================================================== | |||||
var Meta={}; | |||||
var local_dt = {}; | |||||
// Make Unique Copy of DocType for each record for client scripting | |||||
Meta.make_local_dt = function(dt, dn) { | |||||
var dl = make_doclist('DocType', dt); | |||||
if(!local_dt[dt]) local_dt[dt]={}; | |||||
if(!local_dt[dt][dn]) local_dt[dt][dn]={}; | |||||
for(var i=0;i<dl.length;i++) { | |||||
var d = dl[i]; | |||||
if(d.doctype=='DocField') { | |||||
var key = d.fieldname ? d.fieldname : d.label; | |||||
local_dt[dt][dn][key] = copy_dict(d); | |||||
local_dt[dt][dn][key].__copy = true; | |||||
} | |||||
} | |||||
} | |||||
Meta.set_field_property=function(fn, key, val, doc) { | |||||
if(!doc && (cur_frm.doc))doc = cur_frm.doc; | |||||
try{ | |||||
local_dt[doc.doctype][doc.name][fn][key] = val; | |||||
refresh_field(fn); | |||||
} catch(e) { | |||||
alert("Client Script Error: Unknown values for " + doc.name + ',' + fn +'.'+ key +'='+ val); | |||||
} | |||||
} | |||||
Meta.get_field = function(dt, fn, dn) { | |||||
try { | |||||
return local_dt[dt][dn][fn]; | |||||
} catch(e) { | |||||
return null; | |||||
} | |||||
} | |||||
// Get Dt label | |||||
// ====================================================================================== | |||||
function get_doctype_label(dt) { | |||||
return dt | |||||
} | |||||
function get_label_doctype(label) { | |||||
return label | |||||
} | |||||
// Global methods for API | |||||
// ====================================================================================== | |||||
var getchildren = LocalDB.getchildren; | |||||
var createLocal = LocalDB.create; |
@@ -44,7 +44,7 @@ function $c_obj(doclist, method, arg, callback, no_spinner, freeze_msg, btn) { | |||||
if(typeof doclist=='string') | if(typeof doclist=='string') | ||||
args.doctype = doclist; | args.doctype = doclist; | ||||
else | else | ||||
args.docs = compress_doclist(doclist) | |||||
args.docs = wn.model.compress(doclist) | |||||
wn.request.call({ | wn.request.call({ | ||||
args: args, | args: args, | ||||
@@ -84,7 +84,7 @@ function $c_obj_csv(doclist, method, arg) { | |||||
if(doclist.substr) | if(doclist.substr) | ||||
args.doctype = doclist; | args.doctype = doclist; | ||||
else | else | ||||
args.docs = compress_doclist(doclist); | |||||
args.docs = wn.model.compress(doclist); | |||||
// open | // open | ||||
open_url_post(wn.request.url, args); | open_url_post(wn.request.url, args); | ||||
@@ -28,7 +28,6 @@ function loadreport(dt, rep_name, onload) { | |||||
} | } | ||||
function loaddoc(doctype, name, onload) { | function loaddoc(doctype, name, onload) { | ||||
//doctype = get_label_doctype(doctype); | |||||
wn.model.with_doctype(doctype, function() { | wn.model.with_doctype(doctype, function() { | ||||
if(locals.DocType[doctype].in_dialog) { | if(locals.DocType[doctype].in_dialog) { | ||||
_f.edit_record(doctype, name); | _f.edit_record(doctype, name); | ||||
@@ -40,10 +39,9 @@ function loaddoc(doctype, name, onload) { | |||||
var load_doc = loaddoc; | var load_doc = loaddoc; | ||||
function new_doc(doctype, in_form) { | function new_doc(doctype, in_form) { | ||||
doctype = get_label_doctype(doctype); | |||||
wn.model.with_doctype(doctype, function() { | wn.model.with_doctype(doctype, function() { | ||||
if(!in_form && locals.DocType[doctype].in_dialog) { | if(!in_form && locals.DocType[doctype].in_dialog) { | ||||
var new_name = LocalDB.create(doctype); | |||||
var new_name = wn.model.make_new_doc_and_get_name(doctype); | |||||
_f.edit_record(doctype, new_name); | _f.edit_record(doctype, new_name); | ||||
} else { | } else { | ||||
wn.views.formview.create(doctype); | wn.views.formview.create(doctype); | ||||
@@ -74,7 +74,7 @@ function makeselector() { | |||||
} | } | ||||
d.style = 'Search'; | d.style = 'Search'; | ||||
if(d.input) { d.input = null; sel_type = null; } | if(d.input) { d.input = null; sel_type = null; } | ||||
d.sel_type = get_label_doctype(dt); | |||||
d.sel_type = dt; | |||||
d.set_title('Quick Search for ' + dt); | d.set_title('Quick Search for ' + dt); | ||||
} | } | ||||
@@ -44,7 +44,7 @@ get_server_fields = function(method, arg, table_field, doc, dt, dn, allow_edit, | |||||
if(!allow_edit) wn.dom.freeze(); | if(!allow_edit) wn.dom.freeze(); | ||||
$c('runserverobj', | $c('runserverobj', | ||||
args={'method':method, | args={'method':method, | ||||
'docs':compress_doclist(make_doclist(doc.doctype, doc.name)), | |||||
'docs':wn.model.compress(make_doclist(doc.doctype, doc.name)), | |||||
'arg':arg | 'arg':arg | ||||
}, | }, | ||||
function(r, rt) { | function(r, rt) { | ||||
@@ -127,7 +127,7 @@ set_field_permlevel = function(n, level) { | |||||
} | } | ||||
toggle_field = function(n, hidden) { | toggle_field = function(n, hidden) { | ||||
var df = Meta.get_field(cur_frm.doctype, n, cur_frm.docname); | |||||
var df = wn.meta.get_docfield(cur_frm.doctype, n, cur_frm.docname); | |||||
if(df) { | if(df) { | ||||
df.hidden = hidden; | df.hidden = hidden; | ||||
refresh_field(n); | refresh_field(n); | ||||
@@ -759,8 +759,8 @@ LinkField.prototype.validate_link = function(val, from_selector) { | |||||
me.run_trigger(); | me.run_trigger(); | ||||
} else { | } else { | ||||
var astr = ''; | var astr = ''; | ||||
if(in_list(profile.can_create, me.df.options)) astr = repl('<br><br><span class="link_type" onclick="newdoc(\'%(dt)s\')">Click here</span> to create a new %(dtl)s', {dt:me.df.options, dtl:get_doctype_label(me.df.options)}) | |||||
msgprint(repl('error:<b>%(val)s</b> is not a valid %(dt)s.<br><br>You must first create a new %(dt)s <b>%(val)s</b> and then select its value. To find an existing %(dt)s, click on the magnifying glass next to the field.%(add)s', {val:me.txt.value, dt:get_doctype_label(me.df.options), add:astr})); | |||||
if(in_list(profile.can_create, me.df.options)) astr = repl('<br><br><span class="link_type" onclick="newdoc(\'%(dt)s\')">Click here</span> to create a new %(dtl)s', {dt:me.df.options, dtl:wn._(me.df.options)}) | |||||
msgprint(repl('error:<b>%(val)s</b> is not a valid %(dt)s.<br><br>You must first create a new %(dt)s <b>%(val)s</b> and then select its value. To find an existing %(dt)s, click on the magnifying glass next to the field.%(add)s', {val:me.txt.value, dt:wn._(me.df.options), add:astr})); | |||||
me.txt.value = ''; | me.txt.value = ''; | ||||
me.set(''); | me.set(''); | ||||
} | } | ||||
@@ -46,6 +46,7 @@ _f.Frm = function(doctype, parent, in_form) { | |||||
this.docname = ''; | this.docname = ''; | ||||
this.doctype = doctype; | this.doctype = doctype; | ||||
this.display = 0; | this.display = 0; | ||||
this.refresh_if_stale_for = 600; | |||||
var me = this; | var me = this; | ||||
this.is_editable = {}; | this.is_editable = {}; | ||||
@@ -215,7 +216,7 @@ _f.Frm.prototype.print_doc = function() { | |||||
_f.Frm.prototype.email_doc = function(message) { | _f.Frm.prototype.email_doc = function(message) { | ||||
new wn.views.CommunicationComposer({ | new wn.views.CommunicationComposer({ | ||||
doc: this.doc, | doc: this.doc, | ||||
subject: get_doctype_label(this.meta.name) + ': ' + this.docname, | |||||
subject: wn._(this.meta.name) + ': ' + this.docname, | |||||
recipients: this.doc.email || this.doc.email_id || this.doc.contact_email, | recipients: this.doc.email || this.doc.email_id || this.doc.contact_email, | ||||
attach_document_print: true, | attach_document_print: true, | ||||
message: message, | message: message, | ||||
@@ -237,7 +238,7 @@ _f.Frm.prototype.rename_notify = function(dt, old, name) { | |||||
if(this.docname == old) | if(this.docname == old) | ||||
this.docname = name; | this.docname = name; | ||||
else | else | ||||
return; // thats it, not for children! | |||||
return; | |||||
// editable | // editable | ||||
this.is_editable[name] = this.is_editable[old]; | this.is_editable[name] = this.is_editable[old]; | ||||
@@ -245,9 +246,9 @@ _f.Frm.prototype.rename_notify = function(dt, old, name) { | |||||
// cleanup | // cleanup | ||||
if(this && this.opendocs[old]) { | if(this && this.opendocs[old]) { | ||||
// local doctype copy | |||||
local_dt[dt][name] = local_dt[dt][old]; | |||||
local_dt[dt][old] = null; | |||||
// delete docfield copy | |||||
wn.meta.docfield_copy[dt][name] = wn.meta.docfield_copy[dt][old]; | |||||
delete wn.meta.docfield_copy[dt][old]; | |||||
} | } | ||||
delete this.opendocs[old]; | delete this.opendocs[old]; | ||||
@@ -260,19 +261,16 @@ _f.Frm.prototype.rename_notify = function(dt, old, name) { | |||||
// SETUP | // SETUP | ||||
_f.Frm.prototype.setup_meta = function(doctype) { | _f.Frm.prototype.setup_meta = function(doctype) { | ||||
this.meta = get_local('DocType',this.doctype); | |||||
this.meta = wn.model.get_doc('DocType',this.doctype); | |||||
this.perm = wn.perm.get_perm(this.doctype); // for create | this.perm = wn.perm.get_perm(this.doctype); // for create | ||||
if(this.meta.istable) { this.meta.in_dialog = 1 } | if(this.meta.istable) { this.meta.in_dialog = 1 } | ||||
this.setup_print(); | this.setup_print(); | ||||
} | } | ||||
_f.Frm.prototype.setup_sidebar = function() { | _f.Frm.prototype.setup_sidebar = function() { | ||||
this.sidebar = new wn.widgets.form.sidebar.Sidebar(this); | this.sidebar = new wn.widgets.form.sidebar.Sidebar(this); | ||||
} | } | ||||
_f.Frm.prototype.setup_footer = function() { | _f.Frm.prototype.setup_footer = function() { | ||||
var me = this; | var me = this; | ||||
@@ -372,7 +370,6 @@ _f.Frm.prototype.setup_fields_std = function() { | |||||
} | } | ||||
} | } | ||||
// -------------------------------------------------------------------------------------- | |||||
_f.Frm.prototype.add_custom_button = function(label, fn, icon) { | _f.Frm.prototype.add_custom_button = function(label, fn, icon) { | ||||
this.frm_head.appframe.add_button(label, fn, icon); | this.frm_head.appframe.add_button(label, fn, icon); | ||||
} | } | ||||
@@ -380,8 +377,6 @@ _f.Frm.prototype.clear_custom_buttons = function() { | |||||
this.frm_head.refresh_toolbar() | this.frm_head.refresh_toolbar() | ||||
} | } | ||||
// -------------------------------------------------------------------------------------- | |||||
_f.Frm.prototype.add_fetch = function(link_field, src_field, tar_field) { | _f.Frm.prototype.add_fetch = function(link_field, src_field, tar_field) { | ||||
if(!this.fetch_dict[link_field]) { | if(!this.fetch_dict[link_field]) { | ||||
this.fetch_dict[link_field] = {'columns':[], 'fields':[]} | this.fetch_dict[link_field] = {'columns':[], 'fields':[]} | ||||
@@ -390,8 +385,6 @@ _f.Frm.prototype.add_fetch = function(link_field, src_field, tar_field) { | |||||
this.fetch_dict[link_field].fields.push(tar_field); | this.fetch_dict[link_field].fields.push(tar_field); | ||||
} | } | ||||
// -------------------------------------------------------------------------------------- | |||||
_f.Frm.prototype.setup_client_script = function() { | _f.Frm.prototype.setup_client_script = function() { | ||||
// setup client obj | // setup client obj | ||||
@@ -400,8 +393,6 @@ _f.Frm.prototype.setup_client_script = function() { | |||||
} | } | ||||
} | } | ||||
// -------------------------------------------------------------------------------------- | |||||
_f.Frm.prototype.refresh_print_layout = function() { | _f.Frm.prototype.refresh_print_layout = function() { | ||||
$ds(this.print_wrapper); | $ds(this.print_wrapper); | ||||
$dh(this.page_layout.wrapper); | $dh(this.page_layout.wrapper); | ||||
@@ -432,8 +423,6 @@ _f.Frm.prototype.refresh_print_layout = function() { | |||||
} | } | ||||
// -------------------------------------------------------------------------------------- | |||||
_f.Frm.prototype.show_the_frm = function() { | _f.Frm.prototype.show_the_frm = function() { | ||||
// show the dialog | // show the dialog | ||||
if(this.meta.in_dialog && !this.parent.dialog.display) { | if(this.meta.in_dialog && !this.parent.dialog.display) { | ||||
@@ -443,38 +432,15 @@ _f.Frm.prototype.show_the_frm = function() { | |||||
} | } | ||||
} | } | ||||
// -------------------------------------------------------------------------------------- | |||||
_f.Frm.prototype.set_print_heading = function(txt) { | _f.Frm.prototype.set_print_heading = function(txt) { | ||||
this.pformat[cur_frm.docname] = txt; | this.pformat[cur_frm.docname] = txt; | ||||
} | } | ||||
// -------------------------------------------------------------------------------------- | |||||
_f.Frm.prototype.defocus_rest = function() { | _f.Frm.prototype.defocus_rest = function() { | ||||
// deselect others | // deselect others | ||||
if(_f.cur_grid_cell) _f.cur_grid_cell.grid.cell_deselect(); | if(_f.cur_grid_cell) _f.cur_grid_cell.grid.cell_deselect(); | ||||
} | } | ||||
// -------- Permissions ------- | |||||
// Returns global permissions, at all levels | |||||
// ====================================================================================== | |||||
_f.Frm.prototype.get_doc_perms = function() { | |||||
var p = [0,0,0,0,0,0]; | |||||
for(var i=0; i<this.perm.length; i++) { | |||||
if(this.perm[i]) { | |||||
if(this.perm[i][READ]) p[READ] = 1; | |||||
if(this.perm[i][WRITE]) p[WRITE] = 1; | |||||
if(this.perm[i][SUBMIT]) p[SUBMIT] = 1; | |||||
if(this.perm[i][CANCEL]) p[CANCEL] = 1; | |||||
if(this.perm[i][AMEND]) p[AMEND] = 1; | |||||
} | |||||
} | |||||
return p; | |||||
} | |||||
// refresh | |||||
// ====================================================================================== | |||||
_f.Frm.prototype.refresh_header = function() { | _f.Frm.prototype.refresh_header = function() { | ||||
// set title | // set title | ||||
// main title | // main title | ||||
@@ -493,8 +459,6 @@ _f.Frm.prototype.refresh_header = function() { | |||||
wn.ui.toolbar.recent.add(this.doctype, this.docname, 1); | wn.ui.toolbar.recent.add(this.doctype, this.docname, 1); | ||||
} | } | ||||
// -------------------------------------------------------------------------------------- | |||||
_f.Frm.prototype.check_doc_perm = function() { | _f.Frm.prototype.check_doc_perm = function() { | ||||
// get perm | // get perm | ||||
var dt = this.parent_doctype?this.parent_doctype : this.doctype; | var dt = this.parent_doctype?this.parent_doctype : this.doctype; | ||||
@@ -516,8 +480,6 @@ _f.Frm.prototype.check_doc_perm = function() { | |||||
return 1 | return 1 | ||||
} | } | ||||
// -------------------------------------------------------------------------------------- | |||||
_f.Frm.prototype.refresh = function(docname) { | _f.Frm.prototype.refresh = function(docname) { | ||||
// record switch | // record switch | ||||
if(docname) { | if(docname) { | ||||
@@ -535,15 +497,20 @@ _f.Frm.prototype.refresh = function(docname) { | |||||
// check permissions | // check permissions | ||||
if(!this.check_doc_perm()) return; | if(!this.check_doc_perm()) return; | ||||
// set the doc | |||||
this.doc = wn.model.get_doc(this.doctype, this.docname); | |||||
// check if doctype is already open | // check if doctype is already open | ||||
if (!this.opendocs[this.docname]) { | if (!this.opendocs[this.docname]) { | ||||
this.check_doctype_conflict(this.docname); | this.check_doctype_conflict(this.docname); | ||||
} else { | |||||
if((new Date() - this.doc.__last_sync_on) / 1000 > this.refresh_if_stale_for) { | |||||
this.reload_doc(); | |||||
return; | |||||
} | |||||
} | } | ||||
// set the doc | |||||
this.doc = get_local(this.doctype, this.docname); | |||||
// do setup | // do setup | ||||
if(!this.setup_done) this.setup(); | if(!this.setup_done) this.setup(); | ||||
@@ -621,13 +588,11 @@ _f.Frm.prototype.refresh = function(docname) { | |||||
} | } | ||||
} | } | ||||
// -------------------------------------------------------------------------------------- | |||||
_f.Frm.prototype.refresh_footer = function() { | _f.Frm.prototype.refresh_footer = function() { | ||||
var f = this.page_layout.footer; | var f = this.page_layout.footer; | ||||
if(f.save_area) { | if(f.save_area) { | ||||
if(this.editable && (!this.meta.in_dialog || this.in_form) | if(this.editable && (!this.meta.in_dialog || this.in_form) | ||||
&& this.doc.docstatus==0 && !this.meta.istable && this.get_doc_perms()[WRITE] | |||||
&& this.doc.docstatus==0 && !this.meta.istable && this.perm[0][WRITE] | |||||
&& (this.fields && this.fields.length > 7)) { | && (this.fields && this.fields.length > 7)) { | ||||
f.show_save(); | f.show_save(); | ||||
} else { | } else { | ||||
@@ -755,18 +720,14 @@ _f.Frm.prototype.setnewdoc = function(docname) { | |||||
return; | return; | ||||
} | } | ||||
//if(!this.meta) | |||||
// this.setup_meta(); | |||||
// make a copy of the doctype for client script settings | // make a copy of the doctype for client script settings | ||||
// each record will have its own client script | // each record will have its own client script | ||||
Meta.make_local_dt(this.doctype,docname); | |||||
wn.meta.make_docfield_copy_for(this.doctype,docname); | |||||
this.docname = docname; | this.docname = docname; | ||||
var me = this; | var me = this; | ||||
var viewname = docname; | |||||
if(this.meta.issingle) viewname = this.doctype; | |||||
var viewname = this.meta.issingle ? this.doctype : docname; | |||||
// Client Script | // Client Script | ||||
this.runclientscript('onload', this.doctype, this.docname); | this.runclientscript('onload', this.doctype, this.docname); | ||||
@@ -788,82 +749,12 @@ _f.Frm.prototype.show_doc = function(dn) { | |||||
this.refresh(dn); | this.refresh(dn); | ||||
} | } | ||||
// ====================================================================================== | |||||
var validated; // bad design :( | |||||
_f.Frm.prototype.save = function(save_action, callback, btn) { | |||||
// removes focus from a field before save, | |||||
// so that its change event gets triggered before saving | |||||
$(document.activeElement).blur(); | |||||
//alert(save_action); | |||||
if(!save_action) { | |||||
if(cint(this.doc.docstatus) > 0) return; | |||||
save_action = 'Save'; | |||||
} | |||||
if(save_action=='Submit') { | |||||
locals[this.doctype][this.docname].submitted_on = dateutil.full_str(); | |||||
locals[this.doctype][this.docname].submitted_by = user; | |||||
} | |||||
if(save_action=='Trash') { | |||||
var reason = prompt('Reason for trash (mandatory)', ''); | |||||
if(!strip(reason)) { | |||||
msgprint('Reason is mandatory, not trashed'); | |||||
return; | |||||
} | |||||
locals[this.doctype][this.docname].trash_reason = reason; | |||||
} | |||||
// run validations | |||||
if(save_action=='Cancel') { | |||||
var reason = prompt('Reason for cancellation (mandatory)', ''); | |||||
if(!strip(reason)) { | |||||
msgprint('Reason is mandatory, not cancelled'); | |||||
return; | |||||
} | |||||
locals[this.doctype][this.docname].cancel_reason = reason; | |||||
locals[this.doctype][this.docname].cancelled_on = dateutil.full_str(); | |||||
locals[this.doctype][this.docname].cancelled_by = user; | |||||
} else if(save_action=='Update') { | |||||
// no validation for update | |||||
} else { // no validation for cancellation | |||||
validated = true; | |||||
if(this.cscript.validate) | |||||
this.runclientscript('validate'); | |||||
if(!validated) { | |||||
return 'Error'; | |||||
} | |||||
} | |||||
var onsave = function(r) { | |||||
if(!me.meta.istable && r) { | |||||
me.refresh(r.docname); | |||||
} | |||||
callback && callback(r) | |||||
} | |||||
var me = this; | |||||
var onerr = function(r) { | |||||
var doc = locals[me.doctype][me.docname]; | |||||
onsave(r); | |||||
} | |||||
if(this.docname && validated) { | |||||
// scroll to top | |||||
scroll(0, 0); | |||||
return save_doclist(this.doctype, this.docname, save_action, onsave, onerr, btn); | |||||
} | |||||
} | |||||
_f.Frm.prototype.runscript = function(scriptname, callingfield, onrefresh) { | _f.Frm.prototype.runscript = function(scriptname, callingfield, onrefresh) { | ||||
var me = this; | var me = this; | ||||
if(this.docname) { | if(this.docname) { | ||||
// make doc list | // make doc list | ||||
var doclist = compress_doclist(make_doclist(this.doctype, this.docname)); | |||||
var doclist = wn.model.compress(make_doclist(this.doctype, this.docname)); | |||||
// send to run | // send to run | ||||
if(callingfield) | if(callingfield) | ||||
$(callingfield.input).set_working(); | $(callingfield.input).set_working(); | ||||
@@ -906,7 +797,7 @@ _f.Frm.prototype.runclientscript = function(caller, cdt, cdn) { | |||||
if(caller && caller.toLowerCase()=='setup') { | if(caller && caller.toLowerCase()=='setup') { | ||||
var doctype = get_local('DocType', this.doctype); | |||||
var doctype = wn.model.get_doc('DocType', this.doctype); | |||||
// js | // js | ||||
var cs = doctype.__js || (doctype.client_script_core + doctype.client_script); | var cs = doctype.__js || (doctype.client_script_core + doctype.client_script); | ||||
@@ -941,7 +832,7 @@ _f.Frm.prototype.copy_doc = function(onload, from_amend) { | |||||
var dn = this.docname; | var dn = this.docname; | ||||
// copy parent | // copy parent | ||||
var newdoc = LocalDB.copy(this.doctype, dn, from_amend); | |||||
var newdoc = wn.model.copy_doc(this.doctype, dn, from_amend); | |||||
// do not copy attachments | // do not copy attachments | ||||
if(this.meta.allow_attach && newdoc.file_list && !from_amend) | if(this.meta.allow_attach && newdoc.file_list && !from_amend) | ||||
@@ -962,7 +853,7 @@ _f.Frm.prototype.copy_doc = function(onload, from_amend) { | |||||
} | } | ||||
if(d1.parent==dn && cint(tf_dict[d1.parentfield].no_copy)!=1) { | if(d1.parent==dn && cint(tf_dict[d1.parentfield].no_copy)!=1) { | ||||
var ch = LocalDB.copy(d1.doctype, d1.name, from_amend); | |||||
var ch = wn.model.copy_doc(d1.doctype, d1.name, from_amend); | |||||
ch.parent = newdoc.name; | ch.parent = newdoc.name; | ||||
ch.docstatus = 0; | ch.docstatus = 0; | ||||
ch.owner = user; | ch.owner = user; | ||||
@@ -1003,6 +894,31 @@ _f.Frm.prototype.reload_doc = function() { | |||||
} | } | ||||
} | } | ||||
var validated; | |||||
_f.Frm.prototype.save = function(save_action, callback, btn) { | |||||
$(document.activeElement).blur(); | |||||
var me = this; | |||||
var doclist = new wn.model.DocList(this.doctype, this.docname); | |||||
// validate | |||||
if(save_action!="Cancel") { | |||||
validated = true; | |||||
if(this.cscript.validate) | |||||
this.runclientscript('validate'); | |||||
if(!validated) { | |||||
return; | |||||
} | |||||
} | |||||
doclist.save(save_action || "Save", function(r) { | |||||
if(!r.exc) { | |||||
me.refresh(); | |||||
} | |||||
callback && callback(r); | |||||
}, btn); | |||||
} | |||||
_f.Frm.prototype.savesubmit = function(btn) { | _f.Frm.prototype.savesubmit = function(btn) { | ||||
var me = this; | var me = this; | ||||
wn.confirm("Permanently Submit "+this.docname+"?", function() { | wn.confirm("Permanently Submit "+this.docname+"?", function() { | ||||
@@ -1017,7 +933,10 @@ _f.Frm.prototype.savesubmit = function(btn) { | |||||
_f.Frm.prototype.savecancel = function(btn) { | _f.Frm.prototype.savecancel = function(btn) { | ||||
var me = this; | var me = this; | ||||
wn.confirm("Permanently Cancel "+this.docname+"?", function() { | wn.confirm("Permanently Cancel "+this.docname+"?", function() { | ||||
me.save('Cancel', null, btn); | |||||
var doclist = new wn.model.DocList(me.doctype, me.docname); | |||||
doclist.cancel(function(r) { | |||||
if(!r.exc) me.refresh(); | |||||
}, btn); | |||||
}); | }); | ||||
} | } | ||||
@@ -158,7 +158,7 @@ _f.FormGrid.prototype.insert_row = function() { | |||||
_f.FormGrid.prototype.new_row_doc = function() { | _f.FormGrid.prototype.new_row_doc = function() { | ||||
// create row doc | // create row doc | ||||
var n = LocalDB.create(this.doctype); | |||||
var n = wn.model.make_new_doc_and_get_name(this.doctype); | |||||
var d = locals[this.doctype][n]; | var d = locals[this.doctype][n]; | ||||
d.parent = this.field.frm.docname; | d.parent = this.field.frm.docname; | ||||
d.parentfield = this.field.df.fieldname; | d.parentfield = this.field.df.fieldname; | ||||
@@ -220,7 +220,7 @@ _f.FormGrid.prototype.check_selected = function() { | |||||
_f.FormGrid.prototype.delete_row = function(dt, dn) { | _f.FormGrid.prototype.delete_row = function(dt, dn) { | ||||
if(dt && dn) { | if(dt && dn) { | ||||
LocalDB.delete_record(dt, dn); | |||||
wn.model.clear_doc(dt, dn); | |||||
this.refresh(); | this.refresh(); | ||||
} else { | } else { | ||||
if(!this.check_selected()) return; | if(!this.check_selected()) return; | ||||
@@ -230,7 +230,7 @@ _f.FormGrid.prototype.delete_row = function(dt, dn) { | |||||
var ci = _f.cur_grid_cell.cellIndex; | var ci = _f.cur_grid_cell.cellIndex; | ||||
var ri = _f.cur_grid_cell.row.rowIndex; | var ri = _f.cur_grid_cell.row.rowIndex; | ||||
LocalDB.delete_record(this.doctype, r.docname); | |||||
wn.model.clear_doc(this.doctype, r.docname); | |||||
this.refresh(); | this.refresh(); | ||||
if(ri < (this.tab.rows.length-1)) | if(ri < (this.tab.rows.length-1)) | ||||
@@ -80,7 +80,7 @@ _f.FrmHeader = Class.extend({ | |||||
this.$w.find('.avatar img').centerImage(); | this.$w.find('.avatar img').centerImage(); | ||||
}, | }, | ||||
refresh_labels: function() { | refresh_labels: function() { | ||||
cur_frm.doc = get_local(cur_frm.doc.doctype, cur_frm.doc.name); | |||||
cur_frm.doc = wn.model.get_doc(cur_frm.doc.doctype, cur_frm.doc.name); | |||||
var labinfo = { | var labinfo = { | ||||
0: ['Saved', 'label-success'], | 0: ['Saved', 'label-success'], | ||||
1: ['Submitted', 'label-info'], | 1: ['Submitted', 'label-info'], | ||||
@@ -121,7 +121,7 @@ _f.FrmHeader = Class.extend({ | |||||
} | } | ||||
this.appframe.clear_buttons(); | this.appframe.clear_buttons(); | ||||
var p = cur_frm.get_doc_perms(); | |||||
var p = cur_frm.perm[0]; | |||||
// Edit | // Edit | ||||
if(cur_frm.meta.read_only_onload && !cur_frm.doc.__islocal) { | if(cur_frm.meta.read_only_onload && !cur_frm.doc.__islocal) { | ||||
@@ -452,7 +452,7 @@ $.extend(_p, { | |||||
} | } | ||||
} | } | ||||
// if not, just have doctype has heading | // if not, just have doctype has heading | ||||
h1.innerHTML = val ? val : get_doctype_label(doctype); | |||||
h1.innerHTML = val ? val : wn._(doctype); | |||||
} | } | ||||
var h2_style = { | var h2_style = { | ||||
@@ -132,7 +132,7 @@ _r.ReportBuilder = function(parent, doctype, onload) { | |||||
$ds(me.wrapper); | $ds(me.wrapper); | ||||
// reset main title | // reset main title | ||||
this.set_main_title('Report: ' + get_doctype_label(me.doctype)); | |||||
this.set_main_title('Report: ' + wn._(me.doctype)); | |||||
if(my_onload)my_onload(me); | if(my_onload)my_onload(me); | ||||
} | } | ||||
@@ -156,7 +156,7 @@ _r.ReportBuilder.prototype.make_tabs = function() { | |||||
_r.ReportBuilder.prototype.make_body = function() { | _r.ReportBuilder.prototype.make_body = function() { | ||||
this.set_main_title('Report: ' + get_doctype_label(this.doctype)); | |||||
this.set_main_title('Report: ' + wn._(this.doctype)); | |||||
var me = this; | var me = this; | ||||
this.make_save_criteria(); | this.make_save_criteria(); | ||||
@@ -204,7 +204,7 @@ _r.ReportBuilder.prototype.save_criteria = function(save_as) { | |||||
if(!criteria_name) | if(!criteria_name) | ||||
return; | return; | ||||
var dn = createLocal('Search Criteria'); | |||||
var dn = wn.model.make_new_doc_and_get_name('Search Criteria'); | |||||
var doc = locals['Search Criteria'][dn]; | var doc = locals['Search Criteria'][dn]; | ||||
doc.criteria_name = criteria_name; | doc.criteria_name = criteria_name; | ||||
@@ -243,12 +243,7 @@ _r.ReportBuilder.prototype.save_criteria = function(save_as) { | |||||
me.sc_dict[criteria_name] = r.main_doc_name; | me.sc_dict[criteria_name] = r.main_doc_name; | ||||
me.set_criteria_sel(criteria_name); | me.set_criteria_sel(criteria_name); | ||||
} | } | ||||
//if(this.current_loaded && overwrite) { | |||||
// msgprint('Filters and Columns Synchronized. You must also "Save" the Search Criteria to update'); | |||||
// loaddoc('Search Criteria', this.sc_dict[this.current_loaded]); | |||||
//} else { | |||||
save_doclist(doc.doctype, doc.name, 'Save', fn); // server-side save | |||||
//} | |||||
new wn.model.DocList(doc.doctype, doc.name).save("Save", fn); | |||||
} | } | ||||
// ------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------- | ||||
@@ -292,7 +287,7 @@ _r.ReportBuilder.prototype.clear_criteria = function() { | |||||
this.set_sort_options(); | this.set_sort_options(); | ||||
this.set_main_title('Report: ' + get_doctype_label(this.doctype)); | |||||
this.set_main_title('Report: ' + wn._(this.doctype)); | |||||
this.current_loaded = null; | this.current_loaded = null; | ||||
this.customized_filters = null; | this.customized_filters = null; | ||||
@@ -503,10 +498,10 @@ _r.ReportBuilder.prototype.setup_dt_filters_and_cols = function(fl, dt) { | |||||
// set section headings | // set section headings | ||||
var lab = $a(me.filter_area,'div','filter_dt_head'); | var lab = $a(me.filter_area,'div','filter_dt_head'); | ||||
lab.innerHTML = 'Filters for ' + get_doctype_label(dt); | |||||
lab.innerHTML = 'Filters for ' + wn._(dt); | |||||
var lab = $a(me.picker_area,'div','builder_dt_head'); | var lab = $a(me.picker_area,'div','builder_dt_head'); | ||||
lab.innerHTML = 'Select columns for ' + get_doctype_label(dt); | |||||
lab.innerHTML = 'Select columns for ' + wn._(dt); | |||||
// get fields | // get fields | ||||
var dt_fields = wn.meta.docfield_list[dt]; | var dt_fields = wn.meta.docfield_list[dt]; | ||||
@@ -678,7 +673,7 @@ _r.ReportBuilder.prototype.make_datatable = function() { | |||||
// get search criteria | // get search criteria | ||||
if(me.current_loaded && me.sc_dict[me.current_loaded]) { | if(me.current_loaded && me.sc_dict[me.current_loaded]) { | ||||
var sc = get_local('Search Criteria', me.sc_dict[me.current_loaded]); | |||||
var sc = wn.model.get_doc('Search Criteria', me.sc_dict[me.current_loaded]); | |||||
} | } | ||||
if(sc) me.dt.search_criteria = sc; | if(sc) me.dt.search_criteria = sc; | ||||
@@ -1221,7 +1216,7 @@ _r.ReportColumnPicker.prototype.set_options = function(s, l) { | |||||
for(var i=0; i<l.length; i++) { | for(var i=0; i<l.length; i++) { | ||||
var v = l[i].df.parent + '.' + l[i].df.label; | var v = l[i].df.parent + '.' + l[i].df.label; | ||||
var v_label = get_doctype_label(l[i].df.parent) + '.' + l[i].df.label; | |||||
var v_label = wn._(l[i].df.parent) + '.' + l[i].df.label; | |||||
var o = new Option (v_label, v, false, false); | var o = new Option (v_label, v, false, false); | ||||
o.field = l[i]; | o.field = l[i]; | ||||
if(o.field.is_selected) o.selected = 1; | if(o.field.is_selected) o.selected = 1; | ||||
@@ -36,7 +36,8 @@ wn.widgets.form.sidebar.Comments = function(parent, sidebar, doctype, docname) { | |||||
this.refresh_latest_comment = function() { | this.refresh_latest_comment = function() { | ||||
var wrapper = cur_frm.page_layout.body; | var wrapper = cur_frm.page_layout.body; | ||||
if(!$(wrapper).find(".latest-comment").length) { | if(!$(wrapper).find(".latest-comment").length) { | ||||
$('<div class="latest-comment alert alert-info" style="margin-top:20px;">').prependTo(wrapper); | |||||
$('<div class="latest-comment alert alert-info" style="margin-top:20px; display: none;">') | |||||
.prependTo(wrapper); | |||||
} | } | ||||
var comment_list = wn.widgets.form.comments.comment_list[me.docname]; | var comment_list = wn.widgets.form.comments.comment_list[me.docname]; | ||||
if(comment_list) { | if(comment_list) { | ||||
@@ -21,6 +21,7 @@ | |||||
// | // | ||||
wn.provide('wn.meta.docfield_map'); | wn.provide('wn.meta.docfield_map'); | ||||
wn.provide('wn.meta.docfield_copy'); | |||||
wn.provide('wn.meta.docfield_list'); | wn.provide('wn.meta.docfield_list'); | ||||
wn.provide('wn.meta.doctypes'); | wn.provide('wn.meta.doctypes'); | ||||
wn.provide("wn.meta.precision_map"); | wn.provide("wn.meta.precision_map"); | ||||
@@ -43,9 +44,21 @@ $.extend(wn.meta, { | |||||
wn.meta.docfield_list[df.parent].push(df); | wn.meta.docfield_list[df.parent].push(df); | ||||
}, | }, | ||||
make_docfield_copy_for: function(doctype, docname) { | |||||
var c = wn.meta.docfield_copy; | |||||
if(!c[doctype]) | |||||
c[doctype] = {}; | |||||
if(!c[doctype][docname]) | |||||
c[doctype][docname] = {}; | |||||
$.each(wn.meta.docfield_list[doctype], function(i, df) { | |||||
c[doctype][docname][df.fieldname || df.label] = copy_dict(df); | |||||
}) | |||||
}, | |||||
get_docfield: function(dt, fn, dn) { | get_docfield: function(dt, fn, dn) { | ||||
if(dn && local_dt[dt] && local_dt[dt][dn]){ | |||||
return local_dt[dt][dn][fn]; | |||||
if(dn && wn.meta.docfield_copy[dt] && wn.meta.docfield_copy[dt][dn]){ | |||||
return wn.meta.docfield_copy[dt][dn][fn]; | |||||
} else { | } else { | ||||
return wn.meta.docfield_map[dt][fn]; | return wn.meta.docfield_map[dt][fn]; | ||||
} | } | ||||
@@ -85,4 +98,11 @@ $.extend(wn.meta, { | |||||
return wn.meta.precision_map[doctype]; | return wn.meta.precision_map[doctype]; | ||||
}, | }, | ||||
sync_messages: function(doc) { | |||||
if(doc.__messages) { | |||||
$.extend(wn._messages, doc.__messages); | |||||
} | |||||
}, | |||||
}); | }); |
@@ -0,0 +1,99 @@ | |||||
wn.provide("wn.model"); | |||||
$.extend(wn.model, { | |||||
new_names: {}, | |||||
new_name_count: {}, | |||||
get_new_doc: function(doctype) { | |||||
wn.provide("locals." + doctype); | |||||
var doc = { | |||||
docstatus: 0, | |||||
doctype: doctype, | |||||
name: wn.model.get_new_name(doctype), | |||||
__islocal: 1, | |||||
owner: user | |||||
}; | |||||
wn.model.set_default_values(doc); | |||||
locals[doctype][doc.name] = doc; | |||||
return doc; | |||||
}, | |||||
make_new_doc_and_get_name: function(doctype) { | |||||
return wn.model.get_new_doc(doctype).name; | |||||
}, | |||||
get_new_name: function(doctype) { | |||||
var cnt = wn.model.new_name_count | |||||
if(!cnt[doctype]) | |||||
cnt[doctype] = 0; | |||||
cnt[doctype]++; | |||||
return 'New '+ doctype + ' ' + cnt[doctype]; | |||||
}, | |||||
set_default_values: function(doc) { | |||||
var doctype = doc.doctype; | |||||
var docfields = wn.meta.docfield_list[doctype] || []; | |||||
var updated = []; | |||||
for(var fid=0;fid<docfields.length;fid++) { | |||||
var f = docfields[fid]; | |||||
if(!in_list(no_value_fields, f.fieldtype) && doc[f.fieldname]==null) { | |||||
var v = wn.model.get_default_value(f); | |||||
if(v) { | |||||
doc[f.fieldname] = v; | |||||
updated.push(f.fieldname); | |||||
} | |||||
} | |||||
} | |||||
return updated; | |||||
}, | |||||
get_default_value: function(df) { | |||||
var def_vals = { | |||||
"_Login": user, | |||||
"__user": user, | |||||
"Today": dateutil.get_today(), | |||||
"__today": dateutil.get_today(), | |||||
"Now": dateutil.get_cur_time() | |||||
} | |||||
if(def_vals[df["default"]]) | |||||
return def_vals[df["default"]]; | |||||
else if(df["default"]) | |||||
return df["default"]; | |||||
else if(user_defaults[df.fieldname]) | |||||
return user_defaults[df.fieldname][0]; | |||||
else if(sys_defaults[df.fieldname]) | |||||
return sys_defaults[df.fieldname]; | |||||
}, | |||||
add_child: function(doc, childtype, parentfield) { | |||||
// create row doc | |||||
var d = wn.model.get_new_doc(childtype); | |||||
$.extend(d, { | |||||
parent: doc.name, | |||||
parentfield: parentfield, | |||||
parenttype: doc.doctype, | |||||
idx: getchildren(childtype, d.parent, d.parentfield, d.parenttype).length | |||||
}); | |||||
return d; | |||||
}, | |||||
copy_doc: function(dt, dn, from_amend) { | |||||
var no_copy_list = ['name','amended_from','amendment_date','cancel_reason']; | |||||
var newdoc = wn.model.get_new_doc(dt); | |||||
for(var key in locals[dt][dn]) { | |||||
// dont copy name and blank fields | |||||
var df = wn.meta.get_docfield(dt, key); | |||||
if(key.substr(0,2)!='__' | |||||
&& !in_list(no_copy_list, key) | |||||
&& !(df && (!from_amend && cint(df.no_copy)==1))) { | |||||
newdoc[key] = locals[dt][dn][key]; | |||||
} | |||||
} | |||||
return newdoc; | |||||
}, | |||||
}) |
@@ -0,0 +1,129 @@ | |||||
// Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com) | |||||
// | |||||
// MIT License (MIT) | |||||
// | |||||
// Permission is hereby granted, free of charge, to any person obtaining a | |||||
// copy of this software and associated documentation files (the "Software"), | |||||
// to deal in the Software without restriction, including without limitation | |||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
// and/or sell copies of the Software, and to permit persons to whom the | |||||
// Software is furnished to do so, subject to the following conditions: | |||||
// | |||||
// The above copyright notice and this permission notice shall be included in | |||||
// all copies or substantial portions of the Software. | |||||
// | |||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |||||
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |||||
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE | |||||
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||||
// | |||||
wn.provide("wn.model"); | |||||
wn.model.DocList = Class.extend({ | |||||
init: function(doctype, name) { | |||||
this.doctype = doctype; this.name = name; | |||||
this.doclist = wn.model.get_doclist(this.doctype, this.name); | |||||
this.doc = this.doclist[0]; | |||||
}, | |||||
save: function(action, callback, btn) { | |||||
this.check_name(); | |||||
if(this.check_mandatory()) { | |||||
this._call({ | |||||
method: "webnotes.widgets.form.save.savedocs", | |||||
args: { docs: wn.model.compress(this.doclist), action:action}, | |||||
callback: callback, | |||||
btn: btn | |||||
}); | |||||
} | |||||
}, | |||||
cancel: function(callback, btn) { | |||||
this._call({ | |||||
method: "webnotes.widgets.form.save.cancel", | |||||
args: { doctype: this.doctype, name: this.name }, | |||||
callback: callback, | |||||
btn: btn | |||||
}); | |||||
}, | |||||
check_name: function() { | |||||
var doc = this.doclist[0]; | |||||
var doctype = doc.doctype; | |||||
if(doc.__islocal && (doctype && doctype.autoname | |||||
&& doctype.autoname.toLowerCase()=='prompt')) { | |||||
var newname = prompt('Enter the name of the new '+ dt, ''); | |||||
if(newname) { | |||||
doc.__newname = strip(newname); | |||||
} else { | |||||
msgprint("Name is required."); | |||||
throw "name required"; | |||||
} | |||||
} | |||||
}, | |||||
check_mandatory: function() { | |||||
var me = this; | |||||
var has_errors = false; | |||||
this.scroll_set = false; | |||||
if(this.doc.docstatus==2) return true; // don't check for cancel | |||||
$.each(this.doclist, function(i, doc) { | |||||
var error_fields = []; | |||||
$.each(wn.meta.docfield_list[doc.doctype], function(i, docfield) { | |||||
if(!docfield.fieldname.std_field) { | |||||
var df = wn.meta.get_docfield(doc.doctype, | |||||
docfield.fieldname, me.doclist[0].name); | |||||
if(df.reqd && !wn.model.has_value(doc.doctype, doc.name, df.fieldname)) { | |||||
has_errors = true; | |||||
error_fields[error_fields.length] = df.label; | |||||
// scroll to field | |||||
if(!me.scroll_set) | |||||
me.scroll_to(doc.parentfield || df.fieldname); | |||||
} | |||||
} | |||||
}); | |||||
if(error_fields.length) | |||||
msgprint('<b>Mandatory fields required in '+ (doc.parenttype | |||||
? (wn.meta.docfield_map[doc.parenttype][doc.parentfield].label + ' (Table)') | |||||
: doc.doctype) + ':</b>\n' + error_fields.join('\n')); | |||||
}); | |||||
return !has_errors; | |||||
}, | |||||
scroll_to: function(fieldname) { | |||||
var f = cur_frm.fields_dict[fieldname]; | |||||
if(f) { | |||||
$(document).scrollTop($(f.wrapper).offset().top - 100); | |||||
} | |||||
this.scroll_set = true; | |||||
}, | |||||
_call: function(opts) { | |||||
// opts = { | |||||
// method: "some server method", | |||||
// args: {args to be passed}, | |||||
// callback: callback, | |||||
// btn: btn | |||||
// } | |||||
$(opts.btn).attr("disabled", true); | |||||
wn.call({ | |||||
freeze: true, | |||||
method: opts.method, | |||||
args: opts.args, | |||||
callback: function(r) { | |||||
$(opts.btn).attr("disabled", false); | |||||
opts.callback && opts.callback(r); | |||||
} | |||||
}) | |||||
}, | |||||
}); |
@@ -22,7 +22,7 @@ | |||||
wn.provide('wn.model'); | wn.provide('wn.model'); | ||||
wn.model = { | |||||
$.extend(wn.model, { | |||||
no_value_type: ['Section Break', 'Column Break', 'HTML', 'Table', | no_value_type: ['Section Break', 'Column Break', 'HTML', 'Table', | ||||
'Button', 'Image'], | 'Button', 'Image'], | ||||
@@ -85,7 +85,7 @@ wn.model = { | |||||
}); | }); | ||||
} | } | ||||
}, | }, | ||||
get_server_module_name: function(doctype) { | get_server_module_name: function(doctype) { | ||||
var dt = wn.model.scrub(doctype) | var dt = wn.model.scrub(doctype) | ||||
return wn.model.scrub(locals.DocType[doctype].module) | return wn.model.scrub(locals.DocType[doctype].module) | ||||
@@ -136,6 +136,10 @@ wn.model = { | |||||
return wn.utils.filter_dict(locals[doctype], filters); | return wn.utils.filter_dict(locals[doctype], filters); | ||||
}, | }, | ||||
get_doc: function(doctype, name) { | |||||
return locals[doctype] ? locals[doctype][name] : null; | |||||
}, | |||||
get_doclist: function(doctype, name, filters) { | get_doclist: function(doctype, name, filters) { | ||||
var doclist = []; | var doclist = []; | ||||
if(!locals[doctype]) | if(!locals[doctype]) | ||||
@@ -159,6 +163,47 @@ wn.model = { | |||||
return doclist; | return doclist; | ||||
}, | }, | ||||
get_children: function(child_dt, parent, parentfield, parenttype) { | |||||
if(parenttype) { | |||||
var l = wn.model.get(child_dt, {parent:parent, | |||||
parentfield:parentfield, parenttype:parenttype}); | |||||
} else { | |||||
var l = wn.model.get(child_dt, {parent:parent, | |||||
parentfield:parentfield}); | |||||
} | |||||
l.sort(function(a,b) { return cint(a.idx) - cint(b.idx) }); | |||||
$.each(l, function(i, v) { v.idx = i+1; }); // for chrome bugs ??? | |||||
return l; | |||||
}, | |||||
clear_doclist: function(doctype, name) { | |||||
$.each(wn.model.get_doclist(doctype, name), function(i, d) { | |||||
if(d) wn.model.clear_doc(d.doctype, d.name); | |||||
}); | |||||
}, | |||||
clear_doc: function(doctype, name) { | |||||
delete locals[doctype][name]; | |||||
}, | |||||
copy_doc: function(dt, dn, from_amend) { | |||||
var no_copy_list = ['name','amended_from','amendment_date','cancel_reason']; | |||||
var newdoc = wn.model.get_new_doc(dt); | |||||
for(var key in locals[dt][dn]) { | |||||
// dont copy name and blank fields | |||||
var df = wn.meta.get_docfield(dt, key); | |||||
if(key.substr(0,2)!='__' | |||||
&& !in_list(no_copy_list, key) | |||||
&& !(df && (!from_amend && cint(df.no_copy)==1))) { | |||||
newdoc[key] = locals[dt][dn][key]; | |||||
} | |||||
} | |||||
return newdoc; | |||||
}, | |||||
delete_doc: function(doctype, docname, callback) { | delete_doc: function(doctype, docname, callback) { | ||||
wn.confirm("Permanently delete "+ docname + "?", function() { | wn.confirm("Permanently delete "+ docname + "?", function() { | ||||
@@ -170,7 +215,7 @@ wn.model = { | |||||
}, | }, | ||||
callback: function(r, rt) { | callback: function(r, rt) { | ||||
if(!r.exc) { | if(!r.exc) { | ||||
LocalDB.delete_doc(doctype, docname); | |||||
wn.model.clear_doclist(doctype, docname); | |||||
if(wn.ui.toolbar.recent) | if(wn.ui.toolbar.recent) | ||||
wn.ui.toolbar.recent.remove(doctype, docname); | wn.ui.toolbar.recent.remove(doctype, docname); | ||||
if(callback) callback(r,rt); | if(callback) callback(r,rt); | ||||
@@ -215,4 +260,8 @@ wn.model = { | |||||
}); | }); | ||||
d.show(); | d.show(); | ||||
} | } | ||||
} | |||||
}); | |||||
// legacy | |||||
getchildren = wn.model.get_children | |||||
make_doclist = wn.model.get_doclist |
@@ -0,0 +1,117 @@ | |||||
// Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com) | |||||
// | |||||
// MIT License (MIT) | |||||
// | |||||
// Permission is hereby granted, free of charge, to any person obtaining a | |||||
// copy of this software and associated documentation files (the "Software"), | |||||
// to deal in the Software without restriction, including without limitation | |||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
// and/or sell copies of the Software, and to permit persons to whom the | |||||
// Software is furnished to do so, subject to the following conditions: | |||||
// | |||||
// The above copyright notice and this permission notice shall be included in | |||||
// all copies or substantial portions of the Software. | |||||
// | |||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, | |||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |||||
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |||||
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE | |||||
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||||
// | |||||
$.extend(wn.model, { | |||||
sync: function(doclist, sync_in) { | |||||
if(!sync_in) | |||||
sync_in = locals; | |||||
if(doclist._kl) | |||||
doclist = wn.model.expand(doclist); | |||||
if(doclist && sync_in==locals) | |||||
wn.model.clear_doclist(doclist[0].doctype, doclist[0].name) | |||||
$.each(doclist, function(i, d) { | |||||
if(!d.name) // get name (local if required) | |||||
d.name = wn.model.get_new_name(d.doctype); | |||||
if(!sync_in[d.doctype]) | |||||
sync_in[d.doctype] = {}; | |||||
sync_in[d.doctype][d.name] = d; | |||||
d.__last_sync_on = new Date(); | |||||
if(cur_frm && cur_frm.doctype==d.doctype && cur_frm.docname==d.name) { | |||||
cur_frm.doc = d; | |||||
} | |||||
if(d.doctype=='DocField') wn.meta.add_field(d); | |||||
if(d.doctype=='DocType') wn.meta.sync_messages(d); | |||||
if(d.localname) { | |||||
wn.model.new_names[d.localname] = d.name; | |||||
$(document).trigger('rename', [d.doctype, d.localname, d.name]); | |||||
delete sync_in[d.doctype][d.localname]; | |||||
} | |||||
}); | |||||
}, | |||||
expand: function(data) { | |||||
function zip(k,v) { | |||||
var obj = {}; | |||||
for(var i=0;i<k.length;i++) { | |||||
obj[k[i]] = v[i]; | |||||
} | |||||
return obj; | |||||
} | |||||
var l = []; | |||||
for(var i=0;i<data._vl.length;i++) { | |||||
l.push(zip(data._kl[data._vl[i][0]], data._vl[i])); | |||||
} | |||||
return l; | |||||
}, | |||||
compress: function(doclist) { | |||||
var keys = {}; var values = []; | |||||
function get_key_list(doctype) { | |||||
// valid standard keys | |||||
var key_list = ['doctype', 'name', 'docstatus', 'owner', 'parent', | |||||
'parentfield', 'parenttype', 'idx', 'creation', 'modified', | |||||
'modified_by', '__islocal', '__newname', '__modified', | |||||
'_user_tags', '__temp']; | |||||
for(key in wn.meta.docfield_map[doctype]) { // all other values | |||||
if(!in_list(key_list, key) | |||||
&& !in_list(no_value_fields, wn.meta.docfield_map[doctype][key].fieldtype) | |||||
&& !wn.meta.docfield_map[doctype][key].no_column) { | |||||
key_list[key_list.length] = key | |||||
} | |||||
} | |||||
return key_list; | |||||
} | |||||
for(var i=0; i<doclist.length;i++) { | |||||
var doc = doclist[i]; | |||||
// make keys | |||||
if(!keys[doc.doctype]) { | |||||
keys[doc.doctype] = get_key_list(doc.doctype); | |||||
// doctype must be first | |||||
} | |||||
var row = [] | |||||
var key_list = keys[doc.doctype]; | |||||
// make data rows | |||||
for(var j=0;j<key_list.length;j++) { | |||||
row.push(doc[key_list[j]]); | |||||
} | |||||
values.push(row); | |||||
} | |||||
return JSON.stringify({'_vl':values, '_kl':keys}); | |||||
} | |||||
}); |
@@ -40,5 +40,6 @@ wn._ = function(txt) { | |||||
return txt; | return txt; | ||||
} | } | ||||
wn.provide('wn.settings'); | |||||
wn.provide('wn.ui'); | |||||
wn.provide("locals"); | |||||
wn.provide("wn.settings"); | |||||
wn.provide("wn.ui"); |
@@ -87,7 +87,7 @@ wn.request.cleanup = function(opts, r) { | |||||
// sync docs | // sync docs | ||||
if(r.docs) { | if(r.docs) { | ||||
LocalDB.sync(r.docs); | |||||
wn.model.sync(r.docs); | |||||
} | } | ||||
wn.last_response = r; | wn.last_response = r; | ||||
@@ -148,7 +148,7 @@ wn.call = function(opts) { | |||||
} else if(opts.doc) { | } else if(opts.doc) { | ||||
$.extend(args, { | $.extend(args, { | ||||
cmd: "runserverobj", | cmd: "runserverobj", | ||||
docs: compress_doclist(wn.model.get_doclist(opts.doc.doctype, | |||||
docs: wn.model.compress(wn.model.get_doclist(opts.doc.doctype, | |||||
opts.doc.name)), | opts.doc.name)), | ||||
method: opts.method, | method: opts.method, | ||||
args: opts.args, | args: opts.args, | ||||
@@ -65,7 +65,7 @@ wn.ui.Listing = Class.extend({ | |||||
if(wn.boot.profile.can_create.indexOf(this.opts.new_doctype)==-1) { | if(wn.boot.profile.can_create.indexOf(this.opts.new_doctype)==-1) { | ||||
this.opts.new_doctype = null; | this.opts.new_doctype = null; | ||||
} else { | } else { | ||||
this.opts.new_doctype = get_doctype_label(this.opts.new_doctype); | |||||
this.opts.new_doctype = wn._(this.opts.new_doctype); | |||||
} | } | ||||
} | } | ||||
if(!this.opts.no_result_message) { | if(!this.opts.no_result_message) { | ||||
@@ -10,7 +10,7 @@ wn.ui.set_user_background = function(src) { | |||||
wn.ui.themes = { | wn.ui.themes = { | ||||
"Default": { | "Default": { | ||||
sidebar: "#f2f2f2", | sidebar: "#f2f2f2", | ||||
titlebar: "#dfdfdf", | |||||
titlebar: "#d2d2d2", | |||||
toolbar: "#e9e9e9" | toolbar: "#e9e9e9" | ||||
}, | }, | ||||
Desert: { | Desert: { | ||||
@@ -82,7 +82,7 @@ wn.ui.toolbar.SelectorDialog = Class.extend({ | |||||
set_values: function(lst) { | set_values: function(lst) { | ||||
// convert to labels | // convert to labels | ||||
for(var i=0;i<lst.length;i++) | for(var i=0;i<lst.length;i++) | ||||
lst[i]=get_doctype_label(lst[i]); | |||||
lst[i]=wn._(lst[i]); | |||||
// set values | // set values | ||||
var sel = this.dialog.fields_dict.doctype.input; | var sel = this.dialog.fields_dict.doctype.input; | ||||
@@ -45,7 +45,7 @@ wn.views.doclistview.show = function(doctype) { | |||||
wn.views.DocListView = wn.ui.Listing.extend({ | wn.views.DocListView = wn.ui.Listing.extend({ | ||||
init: function(doctype) { | init: function(doctype) { | ||||
this.doctype = doctype; | this.doctype = doctype; | ||||
this.label = get_doctype_label(doctype); | |||||
this.label = wn._(doctype); | |||||
this.label = (this.label.toLowerCase().substr(-4) == 'list') ? | this.label = (this.label.toLowerCase().substr(-4) == 'list') ? | ||||
this.label : (this.label + ' List'); | this.label : (this.label + ' List'); | ||||
this.make_page(); | this.make_page(); | ||||
@@ -15,7 +15,7 @@ wn.views.formview = { | |||||
if(!(locals[dt] && locals[dt][dn])) { | if(!(locals[dt] && locals[dt][dn])) { | ||||
if(dn && dn.substr(0,4)=="New ") { | if(dn && dn.substr(0,4)=="New ") { | ||||
var new_name = LocalDB.create(dt); | |||||
var new_name = wn.model.make_new_doc_and_get_name(dt); | |||||
wn.views.formview.show(dt, new_name); | wn.views.formview.show(dt, new_name); | ||||
return; | return; | ||||
} else { | } else { | ||||
@@ -33,7 +33,7 @@ wn.views.formview = { | |||||
}) | }) | ||||
}, | }, | ||||
create: function(dt) { | create: function(dt) { | ||||
var new_name = LocalDB.create(dt); | |||||
var new_name = wn.model.make_new_doc_and_get_name(dt); | |||||
wn.set_route('Form', dt, new_name); | wn.set_route('Form', dt, new_name); | ||||
} | } | ||||
} | } |
@@ -23,7 +23,6 @@ | |||||
wn.views.reportview = { | wn.views.reportview = { | ||||
show: function(dt, rep_name) { | show: function(dt, rep_name) { | ||||
wn.require('js/report-legacy.js'); | wn.require('js/report-legacy.js'); | ||||
dt = get_label_doctype(dt); | |||||
if(!_r.rb_con) { | if(!_r.rb_con) { | ||||
// first load | // first load | ||||
@@ -286,7 +286,7 @@ def doclist(lst=None): | |||||
from webnotes.model.doclist import DocList | from webnotes.model.doclist import DocList | ||||
return DocList(lst) | return DocList(lst) | ||||
def model_wrapper(doctype, name=None): | |||||
def model_wrapper(doctype=None, name=None): | |||||
from webnotes.model.wrapper import ModelWrapper | from webnotes.model.wrapper import ModelWrapper | ||||
return ModelWrapper(doctype, name) | return ModelWrapper(doctype, name) | ||||
@@ -80,6 +80,10 @@ def save_uploaded(): | |||||
return None, fname | return None, fname | ||||
def save_url(file_url): | def save_url(file_url): | ||||
if not (file_url.startswith("http://") or file_url.startswith("https://")): | |||||
webnotes.msgprint("URL must start with 'http://' or 'https://'") | |||||
return None, None | |||||
f = webnotes.doc("File Data") | f = webnotes.doc("File Data") | ||||
f.file_url = file_url | f.file_url = file_url | ||||
f.file_name = file_url.split('/')[-1] | f.file_name = file_url.split('/')[-1] | ||||
@@ -93,7 +97,7 @@ def get_uploaded_content(): | |||||
webnotes.uploaded_filename, webnotes.uploaded_content = i.filename, i.file.read() | webnotes.uploaded_filename, webnotes.uploaded_content = i.filename, i.file.read() | ||||
return webnotes.uploaded_filename, webnotes.uploaded_content | return webnotes.uploaded_filename, webnotes.uploaded_content | ||||
else: | else: | ||||
webnotes.msgprint('No File'); | |||||
webnotes.msgprint('No File') | |||||
return None, None | return None, None | ||||
def save_file(fname, content, module=None): | def save_file(fname, content, module=None): | ||||
@@ -23,6 +23,7 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import webnotes | import webnotes | ||||
import webnotes.model.doc | import webnotes.model.doc | ||||
import webnotes.utils | |||||
@webnotes.whitelist() | @webnotes.whitelist() | ||||
def getdoc(): | def getdoc(): | ||||
@@ -25,32 +25,40 @@ import webnotes | |||||
@webnotes.whitelist() | @webnotes.whitelist() | ||||
def savedocs(): | def savedocs(): | ||||
"""save / submit / cancel / update doclist""" | |||||
"""save / submit / update doclist""" | |||||
try: | try: | ||||
from webnotes.model.wrapper import ModelWrapper | |||||
form = webnotes.form_dict | |||||
doclist = ModelWrapper() | |||||
doclist.from_compressed(form.get('docs'), form.get('docname')) | |||||
doclist = webnotes.model_wrapper() | |||||
doclist.from_compressed(webnotes.form_dict.docs, webnotes.form_dict.docname) | |||||
# action | # action | ||||
action = form.get('action') | |||||
action = webnotes.form_dict.action | |||||
if action=='Update': action='update_after_submit' | if action=='Update': action='update_after_submit' | ||||
getattr(doclist, action.lower())() | getattr(doclist, action.lower())() | ||||
# update recent documents | # update recent documents | ||||
webnotes.user.update_recent(doclist.doc.doctype, doclist.doc.name) | webnotes.user.update_recent(doclist.doc.doctype, doclist.doc.name) | ||||
send_updated_docs(doclist) | |||||
# send updated docs | |||||
webnotes.response['saved'] = '1' | |||||
webnotes.response['main_doc_name'] = doclist.doc.name | |||||
webnotes.response['doctype'] = doclist.doc.doctype | |||||
webnotes.response['docname'] = doclist.doc.name | |||||
webnotes.response['docs'] = [doclist.doc] + doclist.children | |||||
except Exception, e: | |||||
webnotes.msgprint(webnotes._('Did not save')) | |||||
webnotes.errprint(webnotes.utils.getTraceback()) | |||||
raise e | |||||
@webnotes.whitelist() | |||||
def cancel(doctype=None, name=None): | |||||
"""cancel a doclist""" | |||||
try: | |||||
doclist = webnotes.model_wrapper(doctype, name) | |||||
doclist.cancel() | |||||
send_updated_docs(doclist) | |||||
except Exception, e: | except Exception, e: | ||||
webnotes.msgprint('Did not save') | |||||
webnotes.errprint(webnotes.utils.getTraceback()) | webnotes.errprint(webnotes.utils.getTraceback()) | ||||
webnotes.msgprint(webnotes._("Did not cancel")) | |||||
raise e | raise e | ||||
def send_updated_docs(doclist): | |||||
webnotes.response['main_doc_name'] = doclist.doc.name | |||||
webnotes.response['doctype'] = doclist.doc.doctype | |||||
webnotes.response['docname'] = doclist.doc.name | |||||
webnotes.response['docs'] = [doclist.doc] + doclist.children |