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.
 
 
 
 
 
 

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