Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 
 

379 řádky
10 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. wn.call({
  58. method:'webnotes.widgets.form.load.getdoctype',
  59. type: "GET",
  60. args: {
  61. doctype: doctype,
  62. with_parent: 1
  63. },
  64. callback: function(r) {
  65. var meta = locals.DocType[doctype];
  66. if(meta.__list_js) {
  67. eval(meta.__list_js);
  68. }
  69. if(meta.__calendar_js) {
  70. eval(meta.__calendar_js);
  71. }
  72. if(meta.__map_js) {
  73. eval(meta.__map_js);
  74. }
  75. callback(r);
  76. }
  77. });
  78. }
  79. },
  80. with_doc: function(doctype, name, callback) {
  81. if(!name) name = doctype; // single type
  82. if(locals[doctype] && locals[doctype][name]) {
  83. callback(name);
  84. } else {
  85. wn.call({
  86. method: 'webnotes.widgets.form.load.getdoc',
  87. type: "GET",
  88. args: {
  89. doctype: doctype,
  90. name: name
  91. },
  92. callback: function(r) { callback(name, r); }
  93. });
  94. }
  95. },
  96. get_server_module_name: function(doctype) {
  97. var dt = wn.model.scrub(doctype)
  98. return wn.model.scrub(locals.DocType[doctype].module)
  99. + '.doctype.' + dt + '.' + dt;
  100. },
  101. scrub: function(txt) {
  102. return txt.replace(/ /g, "_").toLowerCase();
  103. },
  104. can_create: function(doctype) {
  105. return wn.boot.profile.can_create.indexOf(doctype)!=-1;
  106. },
  107. can_read: function(doctype) {
  108. return wn.boot.profile.can_read.indexOf(doctype)!=-1;
  109. },
  110. can_write: function(doctype) {
  111. return wn.boot.profile.can_write.indexOf(doctype)!=-1;
  112. },
  113. can_get_report: function(doctype) {
  114. return wn.boot.profile.can_get_report.indexOf(doctype)!=-1;
  115. },
  116. can_delete: function(doctype) {
  117. if(!doctype) return false;
  118. return wn.boot.profile.can_cancel.indexOf(doctype)!=-1;
  119. },
  120. is_submittable: function(doctype) {
  121. if(!doctype) return false;
  122. return locals.DocType[doctype] && locals.DocType[doctype].is_submittable;
  123. },
  124. has_value: function(dt, dn, fn) {
  125. // return true if property has value
  126. var val = locals[dt] && locals[dt][dn] && locals[dt][dn][fn];
  127. var df = wn.meta.get_docfield(dt, fn, dn);
  128. if(df.fieldtype=='Table') {
  129. var ret = false;
  130. $.each(locals[df.options] || {}, function(k,d) {
  131. if(d.parent==dn && d.parenttype==dt && d.parentfield==df.fieldname) {
  132. ret = true;
  133. }
  134. });
  135. } else {
  136. var ret = !is_null(val);
  137. }
  138. return ret ? true : false;
  139. },
  140. get: function(doctype, filters) {
  141. var src = locals[doctype] || locals[":" + doctype] || [];
  142. if($.isEmptyObject(src))
  143. return src;
  144. return wn.utils.filter_dict(src, filters);
  145. },
  146. get_value: function(doctype, filters, fieldname) {
  147. var l = wn.model.get(doctype, filters);
  148. return (l.length && l[0]) ? l[0][fieldname] : null;
  149. },
  150. get_doc: function(doctype, name) {
  151. return locals[doctype] ? locals[doctype][name] : null;
  152. },
  153. get_doclist: function(doctype, name, filters) {
  154. var doclist = [];
  155. if(!locals[doctype])
  156. return doclist;
  157. doclist[0] = locals[doctype][name];
  158. $.each(wn.model.get("DocField", {parent:doctype, fieldtype:"Table"}),
  159. function(i, table_field) {
  160. var child_doclist = wn.model.get(table_field.options, {
  161. parent:name, parenttype: doctype,
  162. parentfield: table_field.fieldname});
  163. if($.isArray(child_doclist)) {
  164. child_doclist.sort(function(a, b) { return a.idx - b.idx; });
  165. doclist = doclist.concat(child_doclist);
  166. }
  167. }
  168. );
  169. if(filters) {
  170. doclist = wn.utils.filter_dict(doclist, filters);
  171. }
  172. return doclist;
  173. },
  174. get_children: function(child_dt, parent, parentfield, parenttype) {
  175. if(parenttype) {
  176. var l = wn.model.get(child_dt, {parent:parent,
  177. parentfield:parentfield, parenttype:parenttype});
  178. } else {
  179. var l = wn.model.get(child_dt, {parent:parent,
  180. parentfield:parentfield});
  181. }
  182. if(l.length) {
  183. l.sort(function(a,b) { return cint(a.idx) - cint(b.idx) });
  184. $.each(l, function(i, v) { v.idx = i+1; }); // for chrome bugs ???
  185. }
  186. return l;
  187. },
  188. clear_doclist: function(doctype, name) {
  189. $.each(wn.model.get_doclist(doctype, name), function(i, d) {
  190. if(d) wn.model.clear_doc(d.doctype, d.name);
  191. });
  192. },
  193. remove_from_locals: function(doctype, name) {
  194. this.clear_doclist(doctype, name);
  195. if(wn.views.formview[doctype]) {
  196. delete wn.views.formview[doctype].frm.opendocs[name];
  197. }
  198. },
  199. clear_doc: function(doctype, name) {
  200. delete locals[doctype][name];
  201. },
  202. get_no_copy_list: function(doctype) {
  203. var no_copy_list = ['name','amended_from','amendment_date','cancel_reason'];
  204. $.each(wn.model.get("DocField", {parent:doctype}), function(i, df) {
  205. if(cint(df.no_copy)) no_copy_list.push(df.fieldname);
  206. })
  207. return no_copy_list;
  208. },
  209. copy_doc: function(dt, dn, from_amend) {
  210. var no_copy_list = wn.model.get_no_copy_list(dt);
  211. var newdoc = wn.model.get_new_doc(dt);
  212. for(var key in locals[dt][dn]) {
  213. // dont copy name and blank fields
  214. if(key.substr(0,2)!='__'
  215. && !in_list(no_copy_list, key)) {
  216. newdoc[key] = locals[dt][dn][key];
  217. }
  218. }
  219. return newdoc;
  220. },
  221. // args: source (doclist), target (doctype), table_map, field_map, callback
  222. map: function(args) {
  223. wn.model.with_doctype(args.target, function() {
  224. var map_info = wn.model.map_info[args.target]
  225. if(map_info)
  226. map_info = map_info[args.source[0].doctype];
  227. if(!map_info) {
  228. map_info = {
  229. table_map: {},
  230. field_map: {}
  231. }
  232. }
  233. // main
  234. var target = wn.model.map_doc(args.source[0], args.target, map_info.field_map[args.target]);
  235. // children
  236. $.each(map_info.table_map, function(child_target, child_source) {
  237. $.each($.map(args.source, function(d)
  238. { if(d.doctype==child_source) return d; else return null; }), function(i, d) {
  239. var child = wn.model.map_doc(d, child_target, map_info.field_map[child_target]);
  240. $.extend(child, {
  241. parent: target.name,
  242. parenttype: target.doctype,
  243. parentfield: wn.meta.get_parentfield(target.doctype, child.doctype),
  244. idx: i+1
  245. });
  246. });
  247. });
  248. if(args.callback) {
  249. args.callback(target);
  250. } else {
  251. wn.set_route("Form", target.doctype, target.name);
  252. }
  253. });
  254. },
  255. // map a single doc to a new doc of given DocType and field_map
  256. map_doc: function(source, doctype, field_map) {
  257. var new_doc = wn.model.get_new_doc(doctype);
  258. var no_copy_list = wn.model.get_no_copy_list(doctype);
  259. if(!field_map) field_map = {};
  260. delete no_copy_list[no_copy_list.indexOf("name")];
  261. for(fieldname in wn.meta.docfield_map[doctype]) {
  262. var df = wn.meta.docfield_map[doctype][fieldname];
  263. if(!df.no_copy) {
  264. var source_key = field_map[df.fieldname] || df.fieldname;
  265. if(source_key.substr(0,1)=="=") {
  266. var value = source_key.substr(1);
  267. } else {
  268. var value = source[source_key];
  269. }
  270. if(value!==undefined) {
  271. new_doc[df.fieldname] = value;
  272. }
  273. }
  274. }
  275. return new_doc;
  276. },
  277. delete_doc: function(doctype, docname, callback) {
  278. wn.confirm("Permanently delete "+ docname + "?", function() {
  279. wn.call({
  280. method: 'webnotes.model.delete_doc',
  281. args: {
  282. dt:doctype,
  283. dn:docname
  284. },
  285. callback: function(r, rt) {
  286. if(!r.exc) {
  287. wn.model.clear_doclist(doctype, docname);
  288. if(wn.ui.toolbar.recent)
  289. wn.ui.toolbar.recent.remove(doctype, docname);
  290. if(callback) callback(r,rt);
  291. }
  292. }
  293. })
  294. })
  295. },
  296. rename_doc: function(doctype, docname, callback) {
  297. var d = new wn.ui.Dialog({
  298. title: "Rename " + docname,
  299. fields: [
  300. {label:"New Name", fieldtype:"Data", reqd:1},
  301. {label:"Rename", fieldtype: "Button"}
  302. ]
  303. });
  304. d.get_input("rename").on("click", function() {
  305. var args = d.get_values();
  306. if(!args) return;
  307. d.get_input("rename").set_working();
  308. wn.call({
  309. method:"webnotes.model.rename_doc.rename_doc",
  310. args: {
  311. doctype: doctype,
  312. old: docname,
  313. "new": args.new_name
  314. },
  315. callback: function(r,rt) {
  316. d.get_input("rename").done_working();
  317. if(!r.exc) {
  318. $(document).trigger('rename', [doctype, docname,
  319. r.message || args.new_name]);
  320. if(locals[doctype] && locals[doctype][docname])
  321. delete locals[doctype][docname];
  322. d.hide();
  323. if(callback)
  324. callback(r.message);
  325. }
  326. }
  327. });
  328. });
  329. d.show();
  330. }
  331. });
  332. // legacy
  333. getchildren = wn.model.get_children
  334. make_doclist = wn.model.get_doclist