You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

269 lines
7.7 KiB

  1. // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
  2. // MIT License. See license.txt
  3. frappe.provide('frappe.meta.docfield_map');
  4. frappe.provide('frappe.meta.docfield_copy');
  5. frappe.provide('frappe.meta.docfield_list');
  6. frappe.provide('frappe.meta.doctypes');
  7. frappe.provide("frappe.meta.precision_map");
  8. frappe.get_meta = function(doctype) {
  9. return locals["DocType"][doctype];
  10. }
  11. $.extend(frappe.meta, {
  12. sync: function(doc) {
  13. $.each(doc.fields, function(i, df) {
  14. frappe.meta.add_field(df);
  15. })
  16. frappe.meta.sync_messages(doc);
  17. if(doc.__print_formats) frappe.model.sync(doc.__print_formats);
  18. if(doc.__workflow_docs) frappe.model.sync(doc.__workflow_docs);
  19. },
  20. // build docfield_map and docfield_list
  21. add_field: function(df) {
  22. frappe.provide('frappe.meta.docfield_map.' + df.parent);
  23. frappe.meta.docfield_map[df.parent][df.fieldname || df.label] = df;
  24. if(!frappe.meta.docfield_list[df.parent])
  25. frappe.meta.docfield_list[df.parent] = [];
  26. // check for repeat
  27. for(var i in frappe.meta.docfield_list[df.parent]) {
  28. var d = frappe.meta.docfield_list[df.parent][i];
  29. if(df.fieldname==d.fieldname)
  30. return; // no repeat
  31. }
  32. frappe.meta.docfield_list[df.parent].push(df);
  33. },
  34. make_docfield_copy_for: function(doctype, docname) {
  35. var c = frappe.meta.docfield_copy;
  36. if(!c[doctype])
  37. c[doctype] = {};
  38. if(!c[doctype][docname])
  39. c[doctype][docname] = {};
  40. var docfield_list = frappe.meta.docfield_list[doctype] || [];
  41. for(var i=0, j=docfield_list.length; i<j; i++) {
  42. var df = docfield_list[i];
  43. c[doctype][docname][df.fieldname || df.label] = copy_dict(df);
  44. }
  45. },
  46. get_field: function(doctype, fieldname, name) {
  47. var out = frappe.meta.get_docfield(doctype, fieldname, name);
  48. // search in standard fields
  49. if (!out) {
  50. frappe.model.std_fields.every(function(d) {
  51. if(d.fieldname===fieldname) {
  52. out = d;
  53. return false;
  54. } else {
  55. return true;
  56. }
  57. });
  58. }
  59. return out;
  60. },
  61. get_docfield: function(doctype, fieldname, name) {
  62. var fields_dict = frappe.meta.get_docfield_copy(doctype, name);
  63. return fields_dict ? fields_dict[fieldname] : null;
  64. },
  65. set_formatter: function(doctype, fieldname, name, formatter) {
  66. frappe.meta.get_docfield(doctype, fieldname, name).formatter = formatter;
  67. },
  68. set_indicator_formatter: function(doctype, fieldname, name, get_text, get_color) {
  69. frappe.meta.get_docfield(doctype, fieldname, name).formatter =
  70. function(value, df, options, doc) {
  71. return repl('<span class="indicator %(color)s">%(name)s</span>', {
  72. color: get_color(),
  73. name: get_text()
  74. });
  75. };
  76. },
  77. get_docfields: function(doctype, name, filters) {
  78. var docfield_map = frappe.meta.get_docfield_copy(doctype, name);
  79. var docfields = frappe.meta.sort_docfields(docfield_map);
  80. if(filters) {
  81. docfields = frappe.utils.filter_dict(docfields, filters);
  82. }
  83. return docfields;
  84. },
  85. get_linked_fields: function(doctype) {
  86. return $.map(frappe.get_meta(doctype).fields,
  87. function(d) { return d.fieldtype=="Link" ? d.options : null; });
  88. },
  89. get_fields_to_check_permissions: function(doctype, name, user_permission_doctypes) {
  90. var fields = $.map(frappe.meta.get_docfields(doctype, name), function(df) {
  91. return (df.fieldtype==="Link" && df.ignore_user_permissions!==1 &&
  92. user_permission_doctypes.indexOf(df.options)!==-1) ? df : null;
  93. });
  94. if (user_permission_doctypes.indexOf(doctype)!==-1) {
  95. fields = fields.concat({label: "Name", fieldname: name, options: doctype});
  96. }
  97. return fields;
  98. },
  99. sort_docfields: function(docs) {
  100. return $.map(docs, function(d) { return d; }).sort(function(a, b) { return a.idx - b.idx });
  101. },
  102. get_docfield_copy: function(doctype, name) {
  103. if(!name) return frappe.meta.docfield_map[doctype];
  104. if(!(frappe.meta.docfield_copy[doctype] && frappe.meta.docfield_copy[doctype][name])) {
  105. frappe.meta.make_docfield_copy_for(doctype, name);
  106. }
  107. return frappe.meta.docfield_copy[doctype][name];
  108. },
  109. get_fieldnames: function(doctype, name, filters) {
  110. return $.map(frappe.utils.filter_dict(frappe.meta.docfield_map[doctype], filters),
  111. function(df) { return df.fieldname; });
  112. },
  113. has_field: function(dt, fn) {
  114. return frappe.meta.docfield_map[dt][fn];
  115. },
  116. get_table_fields: function(dt) {
  117. return $.map(frappe.meta.docfield_list[dt], function(d) {
  118. return d.fieldtype==='Table' ? d : null});
  119. },
  120. get_doctype_for_field: function(doctype, key) {
  121. var out = null;
  122. if(in_list(frappe.model.std_fields_list, key)) {
  123. // standard
  124. out = doctype;
  125. } else if(frappe.meta.has_field(doctype, key)) {
  126. // found in parent
  127. out = doctype;
  128. } else {
  129. frappe.meta.get_table_fields(doctype).every(function(d) {
  130. if(frappe.meta.has_field(d.options, key)) {
  131. out = d.options;
  132. return false;
  133. }
  134. return true;
  135. });
  136. if(!out) {
  137. frappe.msgprint(__('Warning: Unable to find {0} in any table related to {1}', [
  138. key, __(doctype)]));
  139. }
  140. }
  141. return out;
  142. },
  143. get_parentfield: function(parent_dt, child_dt) {
  144. var df = (frappe.get_doc("DocType", parent_dt).fields || []).filter(function(d)
  145. { return d.fieldtype==="Table" && d.options===child_dt })
  146. if(!df.length)
  147. throw "parentfield not found for " + parent_dt + ", " + child_dt;
  148. return df[0].fieldname;
  149. },
  150. get_label: function(dt, fn, dn) {
  151. var standard = {
  152. 'owner': __('Owner'),
  153. 'creation': __('Created On'),
  154. 'modified': __('Last Modified On'),
  155. 'idx': __('Idx'),
  156. 'name': __('Name'),
  157. 'modified_by': __('Last Modified By')
  158. }
  159. if(standard[fn]) {
  160. return standard[fn];
  161. } else {
  162. var df = this.get_docfield(dt, fn, dn);
  163. return (df ? df.label : "") || fn;
  164. }
  165. },
  166. get_print_formats: function(doctype) {
  167. var print_format_list = ["Standard"];
  168. var default_print_format = locals.DocType[doctype].default_print_format;
  169. var print_formats = frappe.get_list("Print Format", {doc_type: doctype})
  170. .sort(function(a, b) { return (a > b) ? 1 : -1; });
  171. $.each(print_formats, function(i, d) {
  172. if(!in_list(print_format_list, d.name) && in_list(['Server', 'Client'], d.print_format_type))
  173. print_format_list.push(d.name);
  174. });
  175. if(default_print_format && default_print_format != "Standard") {
  176. var index = print_format_list.indexOf(default_print_format);
  177. print_format_list.splice(index, 1).sort();
  178. print_format_list.unshift(default_print_format);
  179. }
  180. return print_format_list;
  181. },
  182. sync_messages: function(doc) {
  183. if(doc.__messages) {
  184. $.extend(frappe._messages, doc.__messages);
  185. }
  186. },
  187. get_field_currency: function(df, doc) {
  188. var currency = frappe.boot.sysdefaults.currency;
  189. if(!doc && cur_frm)
  190. doc = cur_frm.doc;
  191. if(df && df.options) {
  192. if(doc && df.options.indexOf(":")!=-1) {
  193. var options = df.options.split(":");
  194. if(options.length==3) {
  195. // get reference record e.g. Company
  196. var docname = doc[options[1]];
  197. if(!docname && cur_frm) {
  198. docname = cur_frm.doc[options[1]];
  199. }
  200. currency = frappe.model.get_value(options[0], docname, options[2]) ||
  201. frappe.model.get_value(":" + options[0], docname, options[2]) ||
  202. currency;
  203. }
  204. } else if(doc && doc[df.options]) {
  205. currency = doc[df.options];
  206. } else if(cur_frm && cur_frm.doc[df.options]) {
  207. currency = cur_frm.doc[df.options];
  208. }
  209. }
  210. return currency;
  211. },
  212. get_field_precision: function(df, doc) {
  213. var precision = null;
  214. if (df && cint(df.precision)) {
  215. precision = cint(df.precision);
  216. } else if(df && df.fieldtype === "Currency") {
  217. precision = cint(frappe.defaults.get_default("currency_precision"));
  218. if(!precision) {
  219. var number_format = get_number_format();
  220. var number_format_info = get_number_format_info(number_format);
  221. precision = number_format_info.precision;
  222. }
  223. } else {
  224. precision = cint(frappe.defaults.get_default("float_precision")) || 3;
  225. }
  226. return precision;
  227. },
  228. });