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.
 
 
 
 
 
 

218 lines
5.2 KiB

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