25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 
 

396 satır
11 KiB

  1. // Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
  2. //
  3. // MIT License (MIT)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a
  6. // copy of this software and associated documentation files (the "Software"),
  7. // to deal in the Software without restriction, including without limitation
  8. // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. // and/or sell copies of the Software, and to permit persons to whom the
  10. // Software is furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  16. // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  17. // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
  19. // CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  20. // OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. //
  22. wn.provide('wn.model');
  23. wn.provide("wn.model.map_info");
  24. $.extend(wn.model, {
  25. no_value_type: ['Section Break', 'Column Break', 'HTML', 'Table',
  26. 'Button', 'Image'],
  27. std_fields_list: ['name', 'owner', 'creation', 'modified', 'modified_by',
  28. '_user_tags', 'docstatus', 'parent', 'parenttype', 'parentfield', 'idx'],
  29. std_fields: [
  30. {fieldname:'name', fieldtype:'Link', label:'ID'},
  31. {fieldname:'owner', fieldtype:'Data', label:'Created By'},
  32. {fieldname:'creation', fieldtype:'Date', label:'Created On'},
  33. {fieldname:'modified', fieldtype:'Date', label:'Last Updated On'},
  34. {fieldname:'modified_by', fieldtype:'Data', label:'Last Updated By'},
  35. {fieldname:'_user_tags', fieldtype:'Data', label:'Tags'},
  36. {fieldname:'docstatus', fieldtype:'Int', label:'Document Status'},
  37. ],
  38. std_fields_table: [
  39. {fieldname:'parent', fieldtype:'Data', label:'Parent'},
  40. {fieldname:'idx', fieldtype:'Int', label:'Row No.'},
  41. ],
  42. new_names: {},
  43. get_std_field: function(fieldname) {
  44. var docfield = $.map([].concat(wn.model.std_fields).concat(wn.model.std_fields_table),
  45. function(d) {
  46. if(d.fieldname==fieldname) return d;
  47. });
  48. if(!docfield.length) {
  49. msgprint("Unknown Column: " + fieldname);
  50. }
  51. return docfield[0];
  52. },
  53. with_doctype: function(doctype, callback) {
  54. if(locals.DocType[doctype]) {
  55. callback();
  56. } else {
  57. var cached_timestamp = null;
  58. if(localStorage["_doctype:" + doctype]) {
  59. var cached_doclist = JSON.parse(localStorage["_doctype:" + doctype]);
  60. cached_timestamp = cached_doclist[0].modified;
  61. }
  62. wn.call({
  63. method:'webnotes.widgets.form.load.getdoctype',
  64. type: "GET",
  65. args: {
  66. doctype: doctype,
  67. with_parent: 1,
  68. cached_timestamp: cached_timestamp
  69. },
  70. callback: function(r) {
  71. if(r.message=="use_cache") {
  72. wn.model.sync(cached_doclist);
  73. } else {
  74. localStorage["_doctype:" + doctype] = JSON.stringify(r.docs);
  75. }
  76. wn.model.init_doctype(doctype);
  77. callback(r);
  78. }
  79. });
  80. }
  81. },
  82. init_doctype: function(doctype) {
  83. var meta = locals.DocType[doctype];
  84. if(meta.__list_js) {
  85. eval(meta.__list_js);
  86. }
  87. if(meta.__calendar_js) {
  88. eval(meta.__calendar_js);
  89. }
  90. if(meta.__map_js) {
  91. eval(meta.__map_js);
  92. }
  93. },
  94. with_doc: function(doctype, name, callback) {
  95. if(!name) name = doctype; // single type
  96. if(locals[doctype] && locals[doctype][name]) {
  97. callback(name);
  98. } else {
  99. wn.call({
  100. method: 'webnotes.widgets.form.load.getdoc',
  101. type: "GET",
  102. args: {
  103. doctype: doctype,
  104. name: name
  105. },
  106. callback: function(r) { callback(name, r); }
  107. });
  108. }
  109. },
  110. get_server_module_name: function(doctype) {
  111. var dt = wn.model.scrub(doctype)
  112. return wn.model.scrub(locals.DocType[doctype].module)
  113. + '.doctype.' + dt + '.' + dt;
  114. },
  115. scrub: function(txt) {
  116. return txt.replace(/ /g, "_").toLowerCase();
  117. },
  118. can_create: function(doctype) {
  119. return wn.boot.profile.can_create.indexOf(doctype)!=-1;
  120. },
  121. can_read: function(doctype) {
  122. return wn.boot.profile.can_read.indexOf(doctype)!=-1;
  123. },
  124. can_write: function(doctype) {
  125. return wn.boot.profile.can_write.indexOf(doctype)!=-1;
  126. },
  127. can_get_report: function(doctype) {
  128. return wn.boot.profile.can_get_report.indexOf(doctype)!=-1;
  129. },
  130. can_delete: function(doctype) {
  131. if(!doctype) return false;
  132. return wn.boot.profile.can_cancel.indexOf(doctype)!=-1;
  133. },
  134. is_submittable: function(doctype) {
  135. if(!doctype) return false;
  136. return locals.DocType[doctype] && locals.DocType[doctype].is_submittable;
  137. },
  138. has_value: function(dt, dn, fn) {
  139. // return true if property has value
  140. var val = locals[dt] && locals[dt][dn] && locals[dt][dn][fn];
  141. var df = wn.meta.get_docfield(dt, fn, dn);
  142. if(df.fieldtype=='Table') {
  143. var ret = false;
  144. $.each(locals[df.options] || {}, function(k,d) {
  145. if(d.parent==dn && d.parenttype==dt && d.parentfield==df.fieldname) {
  146. ret = true;
  147. }
  148. });
  149. } else {
  150. var ret = !is_null(val);
  151. }
  152. return ret ? true : false;
  153. },
  154. get: function(doctype, filters) {
  155. var src = locals[doctype] || locals[":" + doctype] || [];
  156. if($.isEmptyObject(src))
  157. return [];
  158. return wn.utils.filter_dict(src, filters);
  159. },
  160. get_value: function(doctype, filters, fieldname) {
  161. var l = wn.model.get(doctype, filters);
  162. return (l.length && l[0]) ? l[0][fieldname] : null;
  163. },
  164. get_doc: function(doctype, name) {
  165. return locals[doctype] ? locals[doctype][name] : null;
  166. },
  167. get_doclist: function(doctype, name, filters) {
  168. var doclist = [];
  169. if(!locals[doctype])
  170. return doclist;
  171. doclist[0] = locals[doctype][name];
  172. $.each(wn.model.get("DocField", {parent:doctype, fieldtype:"Table"}),
  173. function(i, table_field) {
  174. var child_doclist = wn.model.get(table_field.options, {
  175. parent:name, parenttype: doctype,
  176. parentfield: table_field.fieldname});
  177. if($.isArray(child_doclist)) {
  178. child_doclist.sort(function(a, b) { return a.idx - b.idx; });
  179. doclist = doclist.concat(child_doclist);
  180. }
  181. }
  182. );
  183. if(filters) {
  184. doclist = wn.utils.filter_dict(doclist, filters);
  185. }
  186. return doclist;
  187. },
  188. get_children: function(child_dt, parent, parentfield, parenttype) {
  189. if(parenttype) {
  190. var l = wn.model.get(child_dt, {parent:parent,
  191. parentfield:parentfield, parenttype:parenttype});
  192. } else {
  193. var l = wn.model.get(child_dt, {parent:parent,
  194. parentfield:parentfield});
  195. }
  196. if(l.length) {
  197. l.sort(function(a,b) { return cint(a.idx) - cint(b.idx) });
  198. $.each(l, function(i, v) { v.idx = i+1; }); // for chrome bugs ???
  199. }
  200. return l;
  201. },
  202. clear_doclist: function(doctype, name) {
  203. $.each(wn.model.get_doclist(doctype, name), function(i, d) {
  204. if(d) wn.model.clear_doc(d.doctype, d.name);
  205. });
  206. },
  207. remove_from_locals: function(doctype, name) {
  208. this.clear_doclist(doctype, name);
  209. if(wn.views.formview[doctype]) {
  210. delete wn.views.formview[doctype].frm.opendocs[name];
  211. }
  212. },
  213. clear_doc: function(doctype, name) {
  214. delete locals[doctype][name];
  215. },
  216. get_no_copy_list: function(doctype) {
  217. var no_copy_list = ['name','amended_from','amendment_date','cancel_reason'];
  218. $.each(wn.model.get("DocField", {parent:doctype}), function(i, df) {
  219. if(cint(df.no_copy)) no_copy_list.push(df.fieldname);
  220. })
  221. return no_copy_list;
  222. },
  223. copy_doc: function(dt, dn, from_amend) {
  224. var no_copy_list = wn.model.get_no_copy_list(dt);
  225. var newdoc = wn.model.get_new_doc(dt);
  226. for(var key in locals[dt][dn]) {
  227. // dont copy name and blank fields
  228. if(key.substr(0,2)!='__'
  229. && !in_list(no_copy_list, key)) {
  230. newdoc[key] = locals[dt][dn][key];
  231. }
  232. }
  233. return newdoc;
  234. },
  235. // args: source (doclist), target (doctype), table_map, field_map, callback
  236. map: function(args) {
  237. wn.model.with_doctype(args.target, function() {
  238. var map_info = wn.model.map_info[args.target]
  239. if(map_info)
  240. map_info = map_info[args.source[0].doctype];
  241. if(!map_info) {
  242. map_info = {
  243. table_map: {},
  244. field_map: {}
  245. }
  246. }
  247. // main
  248. var target = wn.model.map_doc(args.source[0], args.target, map_info.field_map[args.target]);
  249. // children
  250. $.each(map_info.table_map, function(child_target, child_source) {
  251. $.each($.map(args.source, function(d)
  252. { if(d.doctype==child_source) return d; else return null; }), function(i, d) {
  253. var child = wn.model.map_doc(d, child_target, map_info.field_map[child_target]);
  254. $.extend(child, {
  255. parent: target.name,
  256. parenttype: target.doctype,
  257. parentfield: wn.meta.get_parentfield(target.doctype, child.doctype),
  258. idx: i+1
  259. });
  260. });
  261. });
  262. if(args.callback) {
  263. args.callback(target);
  264. } else {
  265. wn.set_route("Form", target.doctype, target.name);
  266. }
  267. });
  268. },
  269. // map a single doc to a new doc of given DocType and field_map
  270. map_doc: function(source, doctype, field_map) {
  271. var new_doc = wn.model.get_new_doc(doctype);
  272. var no_copy_list = wn.model.get_no_copy_list(doctype);
  273. if(!field_map) field_map = {};
  274. delete no_copy_list[no_copy_list.indexOf("name")];
  275. for(fieldname in wn.meta.docfield_map[doctype]) {
  276. var df = wn.meta.docfield_map[doctype][fieldname];
  277. if(!df.no_copy) {
  278. var source_key = field_map[df.fieldname] || df.fieldname;
  279. if(source_key.substr(0,1)=="=") {
  280. var value = source_key.substr(1);
  281. } else {
  282. var value = source[source_key];
  283. }
  284. if(value!==undefined) {
  285. new_doc[df.fieldname] = value;
  286. }
  287. }
  288. }
  289. return new_doc;
  290. },
  291. delete_doc: function(doctype, docname, callback) {
  292. wn.confirm("Permanently delete "+ docname + "?", function() {
  293. wn.call({
  294. method: 'webnotes.model.delete_doc',
  295. args: {
  296. dt:doctype,
  297. dn:docname
  298. },
  299. callback: function(r, rt) {
  300. if(!r.exc) {
  301. wn.model.clear_doclist(doctype, docname);
  302. if(wn.ui.toolbar.recent)
  303. wn.ui.toolbar.recent.remove(doctype, docname);
  304. if(callback) callback(r,rt);
  305. }
  306. }
  307. })
  308. })
  309. },
  310. rename_doc: function(doctype, docname, callback) {
  311. var d = new wn.ui.Dialog({
  312. title: "Rename " + docname,
  313. fields: [
  314. {label:"New Name", fieldtype:"Data", reqd:1},
  315. {label:"Merge with existing", fieldtype:"Check", fieldname:"merge"},
  316. {label:"Rename", fieldtype: "Button"}
  317. ]
  318. });
  319. d.get_input("rename").on("click", function() {
  320. var args = d.get_values();
  321. if(!args) return;
  322. d.get_input("rename").set_working();
  323. wn.call({
  324. method:"webnotes.model.rename_doc.rename_doc",
  325. args: {
  326. doctype: doctype,
  327. old: docname,
  328. "new": args.new_name,
  329. "merge": args.merge
  330. },
  331. callback: function(r,rt) {
  332. d.get_input("rename").done_working();
  333. if(!r.exc) {
  334. $(document).trigger('rename', [doctype, docname,
  335. r.message || args.new_name]);
  336. if(locals[doctype] && locals[doctype][docname])
  337. delete locals[doctype][docname];
  338. d.hide();
  339. if(callback)
  340. callback(r.message);
  341. }
  342. }
  343. });
  344. });
  345. d.show();
  346. }
  347. });
  348. // legacy
  349. getchildren = wn.model.get_children
  350. make_doclist = wn.model.get_doclist