function Layout(parent, width) { if (parent && parent.substr) { parent = $i(parent); } this.wrapper = $a(parent, 'div', '', { display: 'none' }); if (width) { this.width = this.wrapper.style.width; } this.myrows = []; } Layout.prototype.addrow = function () { this.cur_row = new LayoutRow(this, this.wrapper); this.myrows[this.myrows.length] = this.cur_row; return this.cur_row; }; Layout.prototype.addsubrow = function () { this.cur_row = new LayoutRow(this, this.cur_row.main_body); this.myrows[this.myrows.length] = this.cur_row; return this.cur_row; }; Layout.prototype.addcell = function (width) { return this.cur_row.addCell(width); }; Layout.prototype.setcolour = function (col) { $bg(cc, col); }; Layout.prototype.show = function () { $(this.wrapper).toggle(false); }; Layout.prototype.hide = function () { $(this.wrapper).toggle(false); }; Layout.prototype.close_borders = function () { if (this.with_border) { this.myrows[this.myrows.length - 1].wrapper.style.borderBottom = '1px solid #000'; } }; function LayoutRow(layout, parent) { this.layout = layout; this.wrapper = $a(parent, 'div', 'form-layout-row'); this.main_head = $a(this.wrapper, 'div'); this.main_body = $a(this.wrapper, 'div'); if (layout.with_border) { this.wrapper.style.border = '1px solid #000'; this.wrapper.style.borderBottom = '0px'; } this.header = $a(this.main_body, 'div', '', { padding: layout.with_border ? '0px 8px' : '0px' }); this.body = $a(this.main_body, 'div'); this.table = $a(this.body, 'table', '', { width: '100%', borderCollapse: 'collapse', tableLayout: 'fixed' }); this.row = this.table.insertRow(0); this.mycells = []; } LayoutRow.prototype.hide = function () { $(this.wrapper).toggle(false); }; LayoutRow.prototype.show = function () { $(this.wrapper).toggle(true); }; LayoutRow.prototype.addCell = function (wid) { var lc = new LayoutCell(this.layout, this, wid); this.mycells[this.mycells.length] = lc; return lc; }; function LayoutCell(layout, layoutRow, width) { if (width) { var w = width + ''; if (w.substr(w.length - 2, 2) != 'px') { if (w.substr(w.length - 1, 1) != "%") { width = width + '%'; } } } this.width = width; this.layout = layout; var cidx = layoutRow.row.cells.length; this.cell = layoutRow.row.insertCell(cidx); this.cell.style.verticalAlign = 'top'; this.set_width(layoutRow.row, width); var h = $a(this.cell, 'div', '', { padding: layout.with_border ? '0px 8px' : '0px' }); this.wrapper = $a(this.cell, 'div', '', { padding: layout.with_border ? '8px' : '0px' }); layout.cur_cell = this.wrapper; layout.cur_cell.header = h; } LayoutCell.prototype.set_width = function (row, width) { var w = 100; var n_cells = row.cells.length; var cells_with_no_width = n_cells; if (width) { $y(row.cells[n_cells - 1], { width: cint(width) + '%' }); } else { row.cells[n_cells - 1].estimated_width = 1; } for (var i = 0; i < n_cells; i++) { if (!row.cells[i].estimated_width) { w = w - cint(row.cells[i].style.width); cells_with_no_width--; } } for (var i = 0; i < n_cells; i++) { if (row.cells[i].estimated_width) $y(row.cells[i], { width: cint(w / cells_with_no_width) + '%' }); } }; LayoutCell.prototype.show = function () { $(this.wrapper).toggle(true); }; LayoutCell.prototype.hide = function () { $(this.wrapper).toggle(false); }; frappe.printTable = Class.extend({ init: function init(opts) { $.extend(this, opts); if (!this.columns) this.columns = this.get_columns(); this.data = this.get_data(); this.remove_empty_cols(); this.set_widths(); this.make(); }, get_columns: function get_columns() { var perms = frappe.perm.get_perm(this.doctype); return ['Sr'].concat($.map(frappe.meta.docfield_list[this.tabletype], function (df) { return cint(df.print_hide) || !(perms[df.permlevel] && perms[df.permlevel].read) ? null : df.fieldname; })); }, get_data: function get_data() { var children = frappe.get_doc(this.doctype, this.docname)[this.fieldname] || []; var data = []; for (var i = 0; i < children.length; i++) { data.push(copy_dict(children[i])); } return data; }, remove_empty_cols: function remove_empty_cols() { var me = this; var cols_with_value = []; $.each(this.data, function (i, row) { $.each(me.columns, function (ci, fieldname) { var value = row[fieldname]; if (value || ci == 0) { if (cols_with_value.indexOf(ci) === -1) { cols_with_value.push(ci); } } }); }); var columns = [], widths = [], head_labels = []; cols_with_value.sort(function (a, b) { return a - b; }); $.each(cols_with_value, function (i, col_idx) { columns.push(me.columns[col_idx]); me.widths && widths.push(me.widths[col_idx]); me.head_labels && head_labels.push(me.head_labels[col_idx]); }); this.columns = columns; if (this.widths) this.widths = widths; if (this.head_labels) this.head_labels = head_labels; }, make: function make() { var me = this; this.tables = []; var table_data = []; $.each(this.data, function (i, d) { table_data.push(d); if (d.page_break) { me.add_table(table_data); table_data = []; } }); if (table_data) me.add_table(table_data); }, add_table: function add_table(data) { var me = this; var wrapper = $("
"); var table = $("").css(this.table_style).appendTo(wrapper); var headrow = $("").appendTo(table); $.each(me.columns, function (ci, fieldname) { var df = frappe.meta.docfield_map[me.tabletype][fieldname]; if (me.head_labels) { var label = me.head_labels[ci]; } else { var label = df ? df.label : fieldname; } var td = $("").appendTo(table); $.each(me.columns, function (ci, fieldname) { if (fieldname.toLowerCase() === "sr") var value = row.idx;else var value = row[fieldname]; var df = frappe.meta.docfield_map[me.tabletype][fieldname]; value = frappe.format(value, df, { for_print: true }); row[fieldname] = value; if (me.modifier && me.modifier[fieldname]) value = me.modifier[fieldname](row); var td = $("
").html(__(label)).css(me.head_cell_style).css({ "width": me.widths[ci] }).appendTo(headrow); if (df && in_list(['Float', 'Currency'], df.fieldtype)) { td.css({ "text-align": "right" }); } }); $.each(data, function (ri, row) { var allow = true; if (me.condition) { allow = me.condition(row); } if (allow) { var tr = $("
").html(value).css(me.cell_style).css({ width: me.widths[ci] }).appendTo(tr); }); } }); this.tables.push(wrapper); }, set_widths: function set_widths() { var me = this; if (!this.widths) { this.widths = $.map(this.columns, function (fieldname, ci) { var df = frappe.meta.docfield_map[me.tabletype][fieldname]; return df && df.print_width || (fieldname == "Sr" ? 30 : 80); }); var sum = 0; $.each(this.widths, function (i, w) { sum += cint(w); }); this.widths = $.map(this.widths, function (w) { w = (flt(w) / sum * 100).toFixed(0); return (w < 5 ? 5 : w) + "%"; }); } }, get_tables: function get_tables() { if (this.tables.length > 1) { return $.map(this.tables, function (t) { return t.get(0); }); } else { return this.tables[0].get(0); } }, cell_style: { border: '1px solid #999', padding: '3px', 'vertical-align': 'top', 'word-wrap': 'break-word' }, head_cell_style: { border: '1px solid #999', padding: '3px', 'vertical-align': 'top', 'background-color': '#ddd', 'font-weight': 'bold', 'word-wrap': 'break-word' }, table_style: { width: '100%', 'border-collapse': 'collapse', 'margin-bottom': '10px', 'margin-top': '10px', 'table-layout': 'fixed' } }); window.print_table = function print_table(dt, dn, fieldname, tabletype, cols, head_labels, widths, condition, cssClass, modifier) { return new frappe.printTable({ doctype: dt, docname: dn, fieldname: fieldname, tabletype: tabletype, columns: cols, head_labels: head_labels, widths: widths, condition: condition, cssClass: cssClass, modifier: modifier }).get_tables(); }; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; _p.def_print_style_body = "html, body, div, span, td, p { \ font-family: inherit; \ font-size: inherit; \ }\ .page-settings {\ font-family: Helvetica, 'Open Sans', sans-serif;\ font-size: 9pt;\ }\ pre { margin:0; padding:0;}"; _p.def_print_style_other = "\n.simpletable, .noborder { \ border-collapse: collapse;\ margin-bottom: 10px;\ }\ .simpletable td {\ border: 1pt solid #777;\ vertical-align: top;\ padding: 4px;\ }\ .noborder td {\ vertical-align: top;\ }"; _p.go = function (html) { var w = _p.preview(html); w.print(); w.close(); }; _p.preview = function (html) { var w = window.open(); if (!w) { frappe.msgprint(__("Please enable pop-ups")); return; } w.document.write(html); w.document.close(); return w; }; _f.get_value = function (dt, dn, fn) { if (locals[dt] && locals[dt][dn]) return locals[dt][dn][fn]; }; $.extend(_p, { show_dialog: function show_dialog() { if (!_p.dialog) { _p.make_dialog(); } _p.dialog.show(); }, make_dialog: function make_dialog() { var dialog = new frappe.ui.Dialog({ title: "Print Formats", fields: [{ fieldtype: "Select", label: "Print Format", fieldname: "print_format", reqd: 1 }, { fieldtype: "Check", label: "No Letter Head", fieldname: "no_letterhead" }, { fieldtype: "HTML", options: '

\ \ \

' }] }); dialog.$wrapper.find(".btn-print").click(function () { var args = dialog.get_values(); _p.build(args.print_format, _p.go, args.no_letterhead); }); dialog.$wrapper.find(".btn-preview").click(function () { var args = dialog.get_values(); _p.build(args.print_format, _p.preview, args.no_letterhead); }); dialog.on_page_show = function () { var $print = dialog.fields_dict.print_format.$input; $print.empty().add_options(cur_frm.print_preview.print_formats); if (cur_frm.$print_view_select && cur_frm.$print_view_select.val()) $print.val(cur_frm.$print_view_select.val()); }; _p.dialog = dialog; }, formats: {}, build: function build(fmtname, onload, no_letterhead, only_body, no_heading) { if (!fmtname) { fmtname = "Standard"; } var args = { fmtname: fmtname, onload: onload, no_letterhead: no_letterhead, only_body: only_body }; if (!cur_frm) { frappe.msgprint(__("No document selected")); return; } if (!frappe.model.can_print(cur_frm.doctype, cur_frm)) { frappe.msgprint(__("You are not allowed to print this document")); return; } var doc = locals[cur_frm.doctype][cur_frm.docname]; if (args.fmtname == 'Standard') { args.onload(_p.render({ body: _p.print_std(args.no_letterhead, no_heading), style: _p.print_style, doc: doc, title: doc.name, no_letterhead: args.no_letterhead, no_heading: no_heading, only_body: args.only_body })); } else { var print_format_doc = locals["Print Format"][args.fmtname]; if (!print_format_doc) { frappe.msgprint(__("Unknown Print Format: {0}", [args.fmtname])); return; } args.onload(_p.render({ body: print_format_doc.html, style: '', doc: doc, title: doc.name, no_letterhead: args.no_letterhead, no_heading: no_heading, only_body: args.only_body })); } }, render: function render(args) { var container = document.createElement('div'); var stat = ''; if (!args.no_heading) { stat += _p.show_draft(args); stat += _p.show_archived(args); stat += _p.show_cancelled(args); } container.innerHTML = args.body; _p.show_letterhead(container, args); _p.run_embedded_js(container, args.doc); var style = _p.consolidate_css(container, args); _p.render_header_on_break(container, args); return _p.render_final(style, stat, container, args); }, head_banner_format: function head_banner_format() { return "\
\
\ {{HEAD}}\
\ {{DESCRIPTION}}\
"; }, show_draft: function show_draft(args) { var is_doctype_submittable = 0; var plist = locals['DocPerm']; for (var perm in plist) { var p = plist[perm]; if (p.parent == args.doc.doctype && p.submit == 1) { is_doctype_submittable = 1; break; } } if (args.doc && cint(args.doc.docstatus) == 0 && is_doctype_submittable) { var draft = _p.head_banner_format(); draft = draft.replace("{{HEAD}}", "DRAFT"); draft = draft.replace("{{DESCRIPTION}}", "This box will go away after the document is submitted."); return draft; } else { return ""; } }, show_archived: function show_archived(args) { if (args.doc && args.doc.__archived) { var archived = _p.head_banner_format(); archived = archived.replace("{{HEAD}}", "ARCHIVED"); archived = archived.replace("{{DESCRIPTION}}", "You must restore this document to make it editable."); return archived; } else { return ""; } }, show_cancelled: function show_cancelled(args) { if (args.doc && args.doc.docstatus == 2) { var cancelled = _p.head_banner_format(); cancelled = cancelled.replace("{{HEAD}}", "CANCELLED"); cancelled = cancelled.replace("{{DESCRIPTION}}", "You must amend this document to make it editable."); return cancelled; } else { return ""; } }, consolidate_css: function consolidate_css(container, args) { var body_style = ''; var style_list = container.getElementsByTagName('style'); while (style_list && style_list.length > 0) { for (var i in style_list) { if (style_list[i] && style_list[i].innerHTML) { body_style += style_list[i].innerHTML; var parent = style_list[i].parentNode; if (parent) { parent.removeChild(style_list[i]); } else { container.removeChild(style_list[i]); } } } style_list = container.getElementsByTagName('style'); } var style_concat = (args.only_body ? '' : _p.def_print_style_body) + _p.def_print_style_other + args.style + body_style; return style_concat; }, run_embedded_js: function run_embedded_js(container, doc) { var script_list = $(container).find("script"); for (var i = 0, j = script_list.length; i < j; i++) { var element = script_list[i]; var code = element.innerHTML; try { var new_html = code ? eval(code) || "" : ""; } catch (e) { console.log("Error in Custom Script:" + e + "\n" + code); console.trace(e); throw e; } if (in_list(["string", "number"], typeof new_html === "undefined" ? "undefined" : _typeof(new_html))) { $(element).replaceWith(this.add_span(new_html + "")); } } $(container).find("script").remove(); }, add_span: function add_span(html) { var tags = [""; } return html; }, show_letterhead: function show_letterhead(container, args) { if (!args.no_letterhead) { container.innerHTML = '
' + _p.get_letter_head() + '
' + container.innerHTML; } }, render_header_on_break: function render_header_on_break(container, args) { var page_set = container.getElementsByClassName('page-settings'); if (page_set.length) { for (var i = 0; i < page_set.length; i++) { var tmp = ''; tmp += _p.show_draft(args); tmp += _p.show_archived(args); _p.show_letterhead(page_set[i], args); page_set[i].innerHTML = tmp + page_set[i].innerHTML; } } }, render_final: function render_final(style, stat, container, args) { if (!args.only_body) { var header = '\ \ \ \ ' + args.title + '\ \ \ '; var footer = '\ \ '; } else { var header = ''; var footer = ''; } var finished = header + '
' + stat + container.innerHTML + '
' + footer; var prefix = window.location.href.split("desk")[0]; var matches = $.unique(finished.match(/src=['"]([^'"]*)['"]/g) || []); $.each(matches, function (i, v) { if (v.substr(0, 4) == "src=") { var v = v.substr(5, v.length - 6); if (v.substr(0, 4) != "http") { finished = finished.split(v).join(prefix + lstrip(v, "/")); } } }); return finished; }, get_letter_head: function get_letter_head() { var lh = ''; if (cur_frm.doc.letter_head) { lh = cstr(frappe.boot.letter_heads[cur_frm.doc.letter_head].header); } else if (frappe.boot.sysdefaults.default_letter_head_content) { lh = frappe.boot.sysdefaults.default_letter_head_content; } return lh; }, print_style: "\ .datalabelcell { \ padding: 2px 0px; \ width: 38%; \ vertical-align: top; \ } \ .datainputcell { \ padding: 2px 0px; \ width: 62%; \ text-align: left; \ }\ .sectionHeading { \ font-size: 16px; \ font-weight: bold; \ margin: 8px 0px; \ } \ .columnHeading { \ font-size: 14px; \ font-weight: bold; \ margin: 8px 0px; \ }", print_std: function print_std(no_letterhead, no_heading) { var docname = cur_frm.docname; var doctype = cur_frm.doctype; var data = frappe.get_children("DocType", doctype, "fields"); var layout = _p.add_layout(doctype); this.pf_list = [layout]; var me = this; me.layout = layout; $.extend(this, { build_head: function build_head(data, doctype, docname) { var h1_style = { fontSize: '22px', marginBottom: '8px' }; var h1 = $a(me.layout.cur_row.header, 'h1', '', h1_style); if (cur_frm.pformat[docname]) { h1.innerHTML = cur_frm.pformat[docname]; } else { var val = null; for (var i = 0; i < data.length; i++) { if (data[i].fieldname === 'select_print_heading') { val = _f.get_value(doctype, docname, data[i].fieldname); break; } } h1.innerHTML = val ? val : __(doctype); } var h2_style = { fontSize: '16px', color: '#888', marginBottom: '8px', paddingBottom: '8px', borderBottom: me.layout.with_border ? '0px' : '1px solid #000' }; var h2 = $a(me.layout.cur_row.header, 'div', '', h2_style); h2.innerHTML = docname; if (cur_frm.state_fieldname && !cur_frm.fields_dict[cur_frm.state_fieldname].df.print_hide) { $a(h2, 'br'); var span = $a(h2, 'span', '', { padding: "3px", color: "#fff", backgroundColor: "#777", display: "inline-block" }); span.innerHTML = cur_frm.doc[cur_frm.state_fieldname]; } }, build_data: function build_data(data, doctype, docname) { if (data[0] && data[0].fieldtype != "Section Break") { me.layout.addrow(); if (data[0].fieldtype != "Column Break") { me.layout.addcell(); } } $.extend(this, { generate_custom_html: function generate_custom_html(field, doctype, docname) { var container = $a(me.layout.cur_cell, 'div'); container.innerHTML = cur_frm.pformat[field.fieldname](locals[doctype][docname]); }, render_normal: function render_normal(field, data, i) { switch (field.fieldtype) { case 'Fold': break; case 'Section Break': me.layout.addrow(); if (data[i + 1] && data[i + 1].fieldtype != 'Column Break') { me.layout.addcell(); } break; case 'Column Break': me.layout.addcell(field.width, field.label); break; case 'Table': var table = print_table(doctype, docname, field.fieldname, field.options, null, null, null, null); me.layout = _p.print_std_add_table(table, me.layout, me.pf_list, doctype, no_letterhead); break; case 'HTML': var div = $a(me.layout.cur_cell, 'div'); div.innerHTML = cstr(field.options); break; case 'Code': var div = $a(me.layout.cur_cell, 'div'); var val = _f.get_value(doctype, docname, field.fieldname); div.innerHTML = '
' + __(field.label) + ':
' + (val ? val : '') + '
'; break; case 'Text Editor': var div = $a(me.layout.cur_cell, 'div'); var val = _f.get_value(doctype, docname, field.fieldname); div.innerHTML = val ? val : ''; break; default: _p.print_std_add_field(doctype, docname, field, me.layout); break; } } }); for (var i = 0; i < data.length; i++) { var fieldname = data[i].fieldname ? data[i].fieldname : data[i].label; var field = fieldname ? frappe.meta.get_docfield(doctype, fieldname, docname) : data[i]; if (!field.print_hide) { if (cur_frm.pformat[field.fieldname]) { this.generate_custom_html(field, doctype, docname); } else { this.render_normal(field, data, i); } } } me.layout.close_borders(); }, build_html: function build_html() { var html = ''; for (var i = 0; i < me.pf_list.length; i++) { if (me.pf_list[i].wrapper) { html += me.pf_list[i].wrapper.innerHTML; } else if (me.pf_list[i].innerHTML) { html += me.pf_list[i].innerHTML; } else { html += me.pf_list[i]; } } this.pf_list = []; return html; } }); if (!no_heading) { this.build_head(data, doctype, docname); } this.build_data(data, doctype, docname); var html = this.build_html(); return html; }, add_layout: function add_layout(doctype) { var layout = new Layout(); layout.addrow(); if (locals['DocType'][doctype].print_outline == 'Yes') { layout.with_border = 1; } return layout; }, print_std_add_table: function print_std_add_table(t, layout, pf_list, dt, no_letterhead) { if (t.appendChild) { layout.cur_cell.appendChild(t); } else { var page_break = '\n\
'; for (var i = 0; i < t.length - 1; i++) { layout.cur_cell.appendChild(t[i]); layout.close_borders(); pf_list.push(page_break); layout = _p.add_layout(dt, no_letterhead); pf_list.push(layout); layout.addrow(); layout.addcell(); var div = $a(layout.cur_cell, 'div'); div.innerHTML = 'Continued from previous page...'; div.style.padding = '4px'; } layout.cur_cell.appendChild(t[t.length - 1]); } return layout; }, print_std_add_field: function print_std_add_field(dt, dn, f, layout) { var val = _f.get_value(dt, dn, f.fieldname); if (f.fieldtype != 'Button') { if (val || in_list(['Float', 'Int', 'Currency'], f.fieldtype)) { var row = _p.field_tab(layout.cur_cell); row.cells[0].innerHTML = __(f.label ? f.label : f.fieldname); row.cells[1].innerHTML = frappe.format(val, f, { for_print: true }); if (f.fieldtype == 'Currency') { $y(row.cells[1], { textAlign: 'left' }); } } } }, field_tab: function field_tab(layout_cell) { var tab = $a(layout_cell, 'table', '', { width: '100%' }); var row = tab.insertRow(0); _p.row = row; row.insertCell(0); row.insertCell(1); row.cells[0].className = 'datalabelcell'; row.cells[0].style.width = "38%"; row.cells[1].className = 'datainputcell'; return row; } });