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.
 
 
 
 
 
 

230 lines
6.1 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.print");
  23. // opts:
  24. // doctype (parent)
  25. // docname
  26. // tabletype
  27. // fieldname
  28. // show_all = false;
  29. wn.print.Table = Class.extend({
  30. init: function(opts) {
  31. $.extend(this, opts);
  32. if(!this.columns)
  33. this.columns = this.get_columns();
  34. this.data = this.get_data();
  35. this.remove_empty_cols();
  36. this.set_widths();
  37. this.make();
  38. },
  39. get_columns: function() {
  40. var perms = wn.perm.get_perm(this.doctype, this.docname);
  41. return ['Sr'].concat($.map(wn.meta.docfield_list[this.tabletype], function(df) {
  42. return (cint(df.print_hide) || !(perms[df.permlevel] &&
  43. perms[df.permlevel][READ])) ? null : df.fieldname;
  44. }));
  45. },
  46. get_data: function() {
  47. var children = wn.model.get(this.tabletype, {
  48. parent:this.docname, parenttype:this.doctype, parentfield: this.fieldname})
  49. var data = []
  50. for(var i=0; i<children.length; i++) {
  51. data.push(copy_dict(children[i]));
  52. }
  53. return data;
  54. },
  55. remove_empty_cols: function() {
  56. var cols_with_value = [];
  57. var widths = [];
  58. var head_labels = [];
  59. var me = this;
  60. $.each(this.data, function(i, row) {
  61. $.each(me.columns, function(ci, fieldname) {
  62. var value = row[fieldname];
  63. if(value || ci==0) {
  64. if(!in_list(cols_with_value, fieldname)) {
  65. cols_with_value.push(fieldname);
  66. // also prepare a new list of widths and head labels
  67. me.widths && widths.push(me.widths[ci]);
  68. me.head_labels && head_labels.push(me.head_labels[ci]);
  69. }
  70. }
  71. });
  72. });
  73. this.columns = cols_with_value;
  74. if(this.widths) this.widths = widths;
  75. if(this.head_labels) this.head_labels = head_labels;
  76. },
  77. make: function() {
  78. var me = this;
  79. this.tables = [];
  80. var table_data = [];
  81. $.each(this.data, function(i, d) {
  82. table_data.push(d);
  83. if(d.page_break) {
  84. me.add_table(table_data);
  85. table_data = [];
  86. }
  87. });
  88. if(table_data)
  89. me.add_table(table_data);
  90. },
  91. add_table: function(data) {
  92. var me = this;
  93. var wrapper = $("<div>")
  94. var table = $("<table>").css(this.table_style).appendTo(wrapper);
  95. var headrow = $("<tr>").appendTo(table);
  96. $.each(me.columns, function(ci, fieldname) {
  97. var df = wn.meta.docfield_map[me.tabletype][fieldname];
  98. if(me.head_labels) {
  99. var label = me.head_labels[ci];
  100. } else {
  101. var label = df ? df.label : fieldname;
  102. }
  103. var td = $("<td>").html(label)
  104. .css(me.head_cell_style)
  105. .css({"width": me.widths[ci]})
  106. .appendTo(headrow)
  107. if(df && in_list(['Float', 'Currency'], df.fieldtype)) {
  108. td.css({"text-align": "right"});
  109. }
  110. });
  111. $.each(data, function(ri, row) {
  112. var allow = true;
  113. if(me.condition) {
  114. allow = me.condition(row);
  115. }
  116. if(allow) {
  117. var tr = $("<tr>").appendTo(table);
  118. $.each(me.columns, function(ci, fieldname) {
  119. if(ci==0)
  120. var value = row.idx;
  121. else
  122. var value = row[fieldname];
  123. var df = wn.meta.docfield_map[me.tabletype][fieldname];
  124. value = wn.format(value, df, {for_print:true});
  125. // set formatted value back into data so that modifer can use it
  126. row[fieldname] = value;
  127. // modifier is called after formatting so that
  128. // modifier's changes do not get lost in formatting (eg. 3.45%)
  129. if(me.modifier && me.modifier[fieldname])
  130. value = me.modifier[fieldname](row);
  131. var td = $("<td>").html(value)
  132. .css(me.cell_style)
  133. .css({width: me.widths[ci]})
  134. .appendTo(tr);
  135. });
  136. }
  137. });
  138. this.tables.push(wrapper)
  139. },
  140. set_widths: function() {
  141. var me = this;
  142. // if widths not passed (like in standard),
  143. // get from doctype and redistribute to fit 100%
  144. if(!this.widths) {
  145. this.widths = $.map(this.columns, function(fieldname, ci) {
  146. df = wn.meta.docfield_map[me.tabletype][fieldname];
  147. return df && df.print_width || (fieldname=="Sr" ? 30 : 80);
  148. });
  149. var sum = 0;
  150. $.each(this.widths, function(i, w) {
  151. sum += cint(w);
  152. });
  153. this.widths = $.map(this.widths, function(w) {
  154. w = (flt(w) / sum * 100).toFixed(0);
  155. return (w < 5 ? 5 : w) + "%";
  156. });
  157. }
  158. },
  159. get_tables: function() {
  160. if(this.tables.length > 1) {
  161. return $.map(this.tables, function(t) {
  162. return t.get(0);
  163. });
  164. } else {
  165. return this.tables[0].get(0);
  166. }
  167. },
  168. cell_style: {
  169. border: '1px solid #999',
  170. padding: '3px',
  171. 'vertical-align': 'top',
  172. 'word-wrap': 'break-word',
  173. },
  174. head_cell_style: {
  175. border: '1px solid #999',
  176. padding: '3px',
  177. 'vertical-align': 'top',
  178. 'background-color': '#ddd',
  179. 'font-weight': 'bold',
  180. 'word-wrap': 'break-word',
  181. },
  182. table_style: {
  183. width: '100%',
  184. 'border-collapse': 'collapse',
  185. 'margin-bottom': '10px',
  186. 'margin-top': '10px',
  187. 'table-layout': 'fixed'
  188. },
  189. })
  190. function print_table(dt, dn, fieldname, tabletype, cols, head_labels, widths, condition, cssClass, modifier) {
  191. return new wn.print.Table({
  192. doctype: dt,
  193. docname: dn,
  194. fieldname: fieldname,
  195. tabletype: tabletype,
  196. columns: cols,
  197. head_labels: head_labels,
  198. widths: widths,
  199. condition: condition,
  200. cssClass: cssClass,
  201. modifier: modifier
  202. }).get_tables();
  203. }