您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

374 行
10 KiB

  1. // Local DB
  2. //-----------
  3. var locals = {};
  4. var fields = {}; // fields[doctype][fieldname]
  5. var fields_list = {}; // fields_list[doctype]
  6. var LocalDB={};
  7. var READ = 0; var WRITE = 1; var CREATE = 2; var SUBMIT = 3; var CANCEL = 4; var AMEND = 5;
  8. LocalDB.getchildren = function(child_dt, parent, parentfield, parenttype) {
  9. var l = [];
  10. for(var key in locals[child_dt]) {
  11. var d = locals[child_dt][key];
  12. if((d.parent == parent)&&(d.parentfield == parentfield)) {
  13. if(parenttype) {
  14. if(d.parenttype==parenttype)l.push(d);
  15. } else { // ignore for now
  16. l.push(d);
  17. }
  18. }
  19. }
  20. l.sort(function(a,b){return (cint(a.idx)-cint(b.idx))}); return l;
  21. }
  22. // Add Doc
  23. // ======================================================================================
  24. LocalDB.add=function(dt, dn) {
  25. if(!locals[dt]) locals[dt] = {}; if(locals[dt][dn]) delete locals[dt][dn];
  26. locals[dt][dn] = {'name':dn, 'doctype':dt, 'docstatus':0};
  27. return locals[dt][dn];
  28. }
  29. // Delete Doc
  30. // ======================================================================================
  31. LocalDB.delete_doc=function(dt, dn) {
  32. var doc = get_local(dt, dn);
  33. for(var ndt in locals) { // all doctypes
  34. if(locals[ndt]) {
  35. for(var ndn in locals[ndt]) {
  36. var doc = locals[ndt][ndn];
  37. if(doc && doc.parenttype==dt && (doc.parent==dn||doc.__oldparent==dn)) {
  38. delete locals[ndt][ndn];
  39. }
  40. }
  41. }
  42. }
  43. delete locals[dt][dn];
  44. }
  45. function get_local(dt, dn) { return locals[dt] ? locals[dt][dn] : null; }
  46. // Sync Records from Server
  47. // ======================================================================================
  48. LocalDB.sync = function(list) {
  49. if(list._kl)list = expand_doclist(list);
  50. for(var i=0;i<list.length;i++) {
  51. var d = list[i];
  52. if(!d.name) // get name (local if required)
  53. d.name = LocalDB.get_localname(d.doctype);
  54. LocalDB.add(d.doctype, d.name);
  55. locals[d.doctype][d.name] = d;
  56. // cleanup for a second-loading
  57. if(d.doctype=='DocType') {
  58. fields_list[d.name] = [];
  59. } else if(d.doctype=='DocField') { // field dictionary / list
  60. if(!d.parent) {
  61. alert('Error: No parent specified for field "' + d.label + '"');
  62. }
  63. if(!fields_list[d.parent])fields_list[d.parent] = [];
  64. fields_list[d.parent][fields_list[d.parent].length] = d;
  65. if(!fields[d.parent])
  66. fields[d.parent] = {};
  67. if(d.fieldname) {
  68. fields[d.parent][d.fieldname] = d;
  69. } else if(d.label) {
  70. fields[d.parent][d.label] = d;
  71. }
  72. } else if(d.doctype=='Event') {
  73. if((!d.localname) && _c.calendar && (!_c.calendar.has_event[d.name]))
  74. _c.calendar.set_event(d);
  75. }
  76. if(d.localname)
  77. notify_rename_observers(d.doctype, d.localname, d.name);
  78. }
  79. }
  80. // Get Local Name
  81. // ======================================================================================
  82. local_name_idx = {};
  83. LocalDB.get_localname=function(doctype) {
  84. if(!local_name_idx[doctype]) local_name_idx[doctype] = 1;
  85. var n = 'New '+ get_doctype_label(doctype) + ' ' + local_name_idx[doctype];
  86. local_name_idx[doctype]++;
  87. return n;
  88. }
  89. // Create Local Doc
  90. // ======================================================================================
  91. LocalDB.set_default_values = function(doc) {
  92. var doctype = doc.doctype;
  93. var docfields = fields_list[doctype];
  94. if(!docfields) {
  95. return;
  96. }
  97. for(var fid=0;fid<docfields.length;fid++) {
  98. var f = docfields[fid];
  99. if(!in_list(no_value_fields, f.fieldtype) && doc[f.fieldname]==null) {
  100. var v = LocalDB.get_default_value(f.fieldname, f.fieldtype, f['default']);
  101. if(v) doc[f.fieldname] = v;
  102. }
  103. }
  104. }
  105. // ======================================================================================
  106. LocalDB.is_doc_loaded = function(dt, dn) {
  107. var exists = false;
  108. if(locals[dt] && locals[dt][dn]) exists = true;
  109. if(exists && dt=='DocType' // if it is a doctype
  110. && !locals[dt][dn].__islocal // and not copied
  111. && !frms[dt]) // and not loaded
  112. exists = false; // reload
  113. return exists;
  114. }
  115. // ======================================================================================
  116. function check_perm_match(p, dt, dn) {
  117. if(!dn) return true;
  118. var out =false;
  119. if(p.match) {
  120. if(user_defaults[p.match]) {
  121. for(var i=0;i<user_defaults[p.match].length;i++) {
  122. // user must have match field in defaults
  123. if(user_defaults[p.match][i]==locals[dt][dn][p.match]) {
  124. // must match document
  125. return true;
  126. }
  127. }
  128. return false;
  129. } else if(!locals[dt][dn][p.match]) { // blanks are true
  130. return true;
  131. } else {
  132. return false;
  133. }
  134. } else {
  135. return true;
  136. }
  137. }
  138. /* Note: Submitted docstatus overrides the permissions. To ignore submit condition
  139. pass ignore_submit=1 */
  140. function get_perm(doctype, dn, ignore_submit) {
  141. var perm = [[0,0],];
  142. if(in_list(user_roles, 'Administrator')) perm[0][READ] = 1;
  143. var plist = getchildren('DocPerm', doctype, 'permissions', 'DocType');
  144. for(var pidx in plist) {
  145. var p = plist[pidx];
  146. var pl = cint(p.permlevel?p.permlevel:0);
  147. // if user role
  148. if(in_list(user_roles, p.role)) {
  149. // if field match
  150. if(check_perm_match(p, doctype, dn)) { // new style
  151. if(!perm[pl])perm[pl] = [];
  152. if(!perm[pl][READ]) {
  153. if(cint(p.read)) perm[pl][READ]=1; else perm[pl][READ]=0;
  154. }
  155. if(!perm[pl][WRITE]) {
  156. if(cint(p.write)) { perm[pl][WRITE]=1; perm[pl][READ]=1; }else perm[pl][WRITE]=0;
  157. }
  158. if(!perm[pl][CREATE]) {
  159. if(cint(p.create))perm[pl][CREATE]=1; else perm[pl][CREATE]=0;
  160. }
  161. if(!perm[pl][SUBMIT]) {
  162. if(cint(p.submit))perm[pl][SUBMIT]=1; else perm[pl][SUBMIT]=0;
  163. }
  164. if(!perm[pl][CANCEL]) {
  165. if(cint(p.cancel))perm[pl][CANCEL]=1; else perm[pl][CANCEL]=0;
  166. }
  167. if(!perm[pl][AMEND]) {
  168. if(cint(p.amend)) perm[pl][AMEND]=1; else perm[pl][AMEND]=0;
  169. }
  170. }
  171. }
  172. }
  173. if((!ignore_submit) && dn && locals[doctype][dn].docstatus>0) {
  174. for(pl in perm)
  175. perm[pl][WRITE]=0; // read only
  176. }
  177. return perm;
  178. }
  179. // ======================================================================================
  180. LocalDB.create = function(doctype, n) {
  181. if(!n) n = LocalDB.get_localname(doctype);
  182. var doc = LocalDB.add(doctype, n)
  183. doc.__islocal=1; doc.owner = user;
  184. LocalDB.set_default_values(doc);
  185. return n;
  186. }
  187. // ======================================================================================
  188. LocalDB.delete_record = function(dt, dn) {
  189. var d = locals[dt][dn];
  190. if(!d.__islocal) // newly created (not required to tag)
  191. d.__oldparent = d.parent;
  192. d.parent = 'old_parent:' + d.parent; // should be ..
  193. d.docstatus = 2;
  194. d.__deleted = 1;
  195. }
  196. // ======================================================================================
  197. LocalDB.get_default_value = function(fn, ft, df) {
  198. if(df=='_Login' || df=='__user')
  199. return user;
  200. else if(df=='_Full Name')
  201. return user_fullname;
  202. else if(ft=='Date'&& (df=='Today' || df=='__today')) {
  203. return get_today(); }
  204. else if(df)
  205. return df;
  206. else if(user_defaults[fn])
  207. return user_defaults[fn][0];
  208. else if(sys_defaults[fn])
  209. return sys_defaults[fn];
  210. }
  211. // ======================================================================================
  212. LocalDB.add_child = function(doc, childtype, parentfield) {
  213. // create row doc
  214. var n = LocalDB.create(childtype);
  215. var d = locals[childtype][n];
  216. d.parent = doc.name;
  217. d.parentfield = parentfield;
  218. d.parenttype = doc.doctype;
  219. return d;
  220. }
  221. // ======================================================================================
  222. LocalDB.no_copy_list = ['amended_from','amendment_date','cancel_reason'];
  223. LocalDB.copy=function(dt, dn, from_amend) {
  224. var newdoc = LocalDB.create(dt);
  225. for(var key in locals[dt][dn]) {
  226. if(key!=='name' && key.substr(0,2)!='__') { // dont copy name and blank fields
  227. locals[dt][newdoc][key] = locals[dt][dn][key];
  228. }
  229. var df = get_field(dt, key);
  230. if(df && ((!from_amend && cint(df.no_copy)==1) || in_list(LocalDB.no_copy_list, df.fieldname))) { // blank out 'No Copy'
  231. locals[dt][newdoc][key]='';
  232. }
  233. }
  234. return locals[dt][newdoc];
  235. }
  236. // ======================================================================================
  237. function make_doclist(dt, dn, deleted) {
  238. var dl = [];
  239. dl[0] = locals[dt][dn];
  240. // get children
  241. for(var ndt in locals) { // all doctypes
  242. if(locals[ndt]) {
  243. for(var ndn in locals[ndt]) {
  244. var doc = locals[ndt][ndn];
  245. if(doc && doc.parenttype==dt && (doc.parent==dn||(deleted&&doc.__oldparent==dn))) {
  246. dl[dl.length]=doc;
  247. //if(deleted&&(doc.__oldparent==dn))alert(doc.name+','+doc.__oldparent);
  248. }
  249. }
  250. }
  251. }
  252. return dl;
  253. }
  254. // Renaming notification list
  255. // ======================================================================================
  256. var rename_observers = [];
  257. function notify_rename_observers(dt, old_name, new_name) {
  258. // delete from local
  259. try {
  260. var old = locals[dt][old_name];
  261. old.parent = null; old.__deleted = 1;
  262. } catch(e) {
  263. alert("[rename_from_local] No Document for: "+ old_name);
  264. }
  265. // everyone who observers
  266. for(var i=0; i<rename_observers.length;i++) {
  267. if(rename_observers[i])
  268. rename_observers[i].rename_notify(dt, old_name, new_name);
  269. }
  270. }
  271. // Meta Data
  272. // ======================================================================================
  273. var Meta={};
  274. var local_dt = {};
  275. // Make Unique Copy of DocType for each record for client scripting
  276. Meta.make_local_dt = function(dt, dn) {
  277. var dl = make_doclist('DocType', dt);
  278. if(!local_dt[dt]) local_dt[dt]={};
  279. if(!local_dt[dt][dn]) local_dt[dt][dn]={};
  280. for(var i=0;i<dl.length;i++) {
  281. var d = dl[i];
  282. if(d.doctype=='DocField') {
  283. var key = d.fieldname ? d.fieldname : d.label;
  284. local_dt[dt][dn][key] = copy_dict(d);
  285. }
  286. }
  287. }
  288. Meta.get_field=function(dt, fn, dn) {
  289. if(dn && local_dt[dt]&&local_dt[dt][dn]){
  290. return local_dt[dt][dn][fn];
  291. } else {
  292. if(fields[dt]) var d = fields[dt][fn];
  293. if(d) return d;
  294. }
  295. return {};
  296. }
  297. Meta.set_field_property=function(fn, key, val, doc) {
  298. if(!doc && (cur_frm.doc))doc = cur_frm.doc;
  299. try{
  300. local_dt[doc.doctype][doc.name][fn][key] = val;
  301. refresh_field(fn);
  302. } catch(e) {
  303. alert("Client Script Error: Unknown values for " + doc.name + ',' + fn +'.'+ key +'='+ val);
  304. }
  305. }
  306. // Get Dt label
  307. // ======================================================================================
  308. function get_doctype_label(dt) {
  309. if(session.dt_labels && session.dt_labels[dt])
  310. return session.dt_labels[dt]
  311. else
  312. return dt
  313. }
  314. function get_label_doctype(label) {
  315. if(session.rev_dt_labels && session.rev_dt_labels[label])
  316. return session.rev_dt_labels[label]
  317. else
  318. return label
  319. }
  320. // Global methods for API
  321. // ======================================================================================
  322. var getchildren = LocalDB.getchildren;
  323. var get_field = Meta.get_field;
  324. var createLocal = LocalDB.create;