diff --git a/frappe/__init__.py b/frappe/__init__.py index a6f98ce184..b0b0631cd4 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -683,13 +683,13 @@ def format_value(value, df, doc=None): return frappe.utils.formatters.format_value(value, df, doc) def get_print_format(doctype, name, print_format=None, style=None, as_pdf=False): - from frappe.website.render import render_page + from frappe.website.render import build_page local.form_dict.doctype = doctype local.form_dict.name = name local.form_dict.format = print_format - local.form_dict.name = name + local.form_dict.style = style - html = render_page("print") + html = build_page("print") if as_pdf: print_settings = db.get_singles_dict("Print Settings") diff --git a/frappe/core/doctype/communication/communication.py b/frappe/core/doctype/communication/communication.py index 072e9faef9..47546c221b 100644 --- a/frappe/core/doctype/communication/communication.py +++ b/frappe/core/doctype/communication/communication.py @@ -34,7 +34,7 @@ class Communication(Document): @frappe.whitelist() def make(doctype=None, name=None, content=None, subject=None, sent_or_received = "Sent", sender=None, recipients=None, communication_medium="Email", send_email=False, - print_html=None, attachments='[]', send_me_a_copy=False, set_lead=True, date=None): + print_html=None, print_format=None, attachments='[]', send_me_a_copy=False, set_lead=True, date=None): if doctype and name and not frappe.has_permission(doctype, "email", name): raise frappe.PermissionError("You are not allowed to send emails related to: {doctype} {name}".format( @@ -42,12 +42,12 @@ def make(doctype=None, name=None, content=None, subject=None, sent_or_received = _make(doctype=doctype, name=name, content=content, subject=subject, sent_or_received=sent_or_received, sender=sender, recipients=recipients, communication_medium=communication_medium, send_email=send_email, - print_html=print_html, attachments=attachments, send_me_a_copy=send_me_a_copy, set_lead=set_lead, + print_html=print_html, print_format=print_format, attachments=attachments, send_me_a_copy=send_me_a_copy, set_lead=set_lead, date=date) def _make(doctype=None, name=None, content=None, subject=None, sent_or_received = "Sent", sender=None, recipients=None, communication_medium="Email", send_email=False, - print_html=None, attachments='[]', send_me_a_copy=False, set_lead=True, date=None): + print_html=None, print_format=None, attachments='[]', send_me_a_copy=False, set_lead=True, date=None): # add to Communication sent_via = None @@ -89,7 +89,7 @@ def _make(doctype=None, name=None, content=None, subject=None, sent_or_received if send_email: d = comm - send_comm_email(d, name, sent_via, print_html, attachments, send_me_a_copy) + send_comm_email(d, name, sent_via, print_html, print_format, attachments, send_me_a_copy) @frappe.whitelist() def get_customer_supplier(args=None): @@ -110,7 +110,7 @@ def get_customer_supplier(args=None): } return {} -def send_comm_email(d, name, sent_via=None, print_html=None, attachments='[]', send_me_a_copy=False): +def send_comm_email(d, name, sent_via=None, print_html=None, print_format=None, attachments='[]', send_me_a_copy=False): footer = None @@ -130,26 +130,8 @@ def send_comm_email(d, name, sent_via=None, print_html=None, attachments='[]', s if send_me_a_copy: mail.cc.append(frappe.db.get_value("User", frappe.session.user, "email")) - if print_html: - print_html = scrub_urls(print_html) - - print_settings = frappe.get_singles_dict("Print Settings") - send_print_as_pdf = cint(print_settings.send_print_as_pdf) - - if send_print_as_pdf: - try: - options = { - 'page-size': print_settings.pdf_page_size or 'A4' - } - mail.add_pdf_attachment(name.replace(' ','').replace('/','-') + '.pdf', print_html, - options=options) - except Exception: - frappe.msgprint(_("Error generating PDF, attachment sent as HTML")) - send_print_as_pdf = 0 - - if not send_print_as_pdf: - mail.add_attachment(name.replace(' ','').replace('/','-') + '.html', - print_html, 'text/html') + if print_html or print_format: + attach_print(mail, sent_via, print_html, print_format) for a in json.loads(attachments): try: @@ -159,6 +141,27 @@ def send_comm_email(d, name, sent_via=None, print_html=None, attachments='[]', s send(mail) +def attach_print(mail, sent_via, print_html, print_format): + name = sent_via.name + if not print_html and print_format: + print_html = frappe.get_print_format(sent_via.doctype, sent_via.name, print_format) + + print_settings = frappe.db.get_singles_dict("Print Settings") + send_print_as_pdf = cint(print_settings.send_print_as_pdf) + + if send_print_as_pdf: + try: + mail.add_pdf_attachment(name.replace(' ','').replace('/','-') + '.pdf', print_html) + except Exception: + frappe.msgprint(_("Error generating PDF, attachment sent as HTML")) + frappe.errprint(frappe.get_traceback()) + send_print_as_pdf = 0 + + if not send_print_as_pdf: + print_html = scrub_urls(print_html) + mail.add_attachment(name.replace(' ','').replace('/','-') + '.html', + print_html, 'text/html') + def set_portal_link(sent_via, comm): """set portal link in footer""" diff --git a/frappe/core/doctype/print_settings/print_settings.json b/frappe/core/doctype/print_settings/print_settings.json index f1e365cbee..576836cece 100644 --- a/frappe/core/doctype/print_settings/print_settings.json +++ b/frappe/core/doctype/print_settings/print_settings.json @@ -11,6 +11,7 @@ "permlevel": 0 }, { + "default": "1", "description": "Send Email Print Attachments as PDF (Recommended)", "fieldname": "send_print_as_pdf", "fieldtype": "Check", @@ -32,6 +33,7 @@ "permlevel": 0 }, { + "default": "", "fieldname": "print_style", "fieldtype": "Select", "in_list_view": 1, @@ -48,7 +50,7 @@ ], "icon": "icon-cog", "issingle": 1, - "modified": "2014-07-17 08:08:27.291811", + "modified": "2014-07-23 04:59:45.626239", "modified_by": "Administrator", "module": "Core", "name": "Print Settings", diff --git a/frappe/patches.txt b/frappe/patches.txt index abe17e867d..427676c64a 100644 --- a/frappe/patches.txt +++ b/frappe/patches.txt @@ -41,7 +41,7 @@ execute:frappe.reset_perms("User") #2014-06-13 execute:frappe.db.sql("""delete from `tabUserRole` where ifnull(parentfield, '')=''""") #2014-06-17 frappe.patches.v4_0.remove_user_owner_custom_field execute:frappe.delete_doc("DocType", "Website Template") -execute:frappe.reload_doc('website', 'doctype', 'website_route') #20114-06-17 +execute:frappe.reload_doc('website', 'doctype', 'website_route') #2014-06-17 execute:frappe.db.sql("""update `tabProperty Setter` set property_type='Text' where property in ('options', 'default')""") #2014-06-20 frappe.patches.v4_1.enable_outgoing_email_settings execute:frappe.db.sql("""update `tabSingles` set `value`=`doctype` where `field`='name'""") #2014-07-04 diff --git a/frappe/patches/v4_1/enable_print_as_pdf.py b/frappe/patches/v4_1/enable_print_as_pdf.py index 94cb96ff8b..877a2b61f7 100644 --- a/frappe/patches/v4_1/enable_print_as_pdf.py +++ b/frappe/patches/v4_1/enable_print_as_pdf.py @@ -6,10 +6,21 @@ import frappe def execute(): frappe.reload_doc("core", "doctype", "print_settings") - frappe.db.set_value("Print Settings", "Print Settings", "print_style", "Modern") + print_settings = frappe.get_doc("Print Settings") + print_settings.print_style = "Modern" + try: import pdfkit except ImportError: pass else: - frappe.db.set_value("Print Settings", "Print Settings", "send_print_as_pdf", 1) + # if someone has already configured in Outgoing Email Settings + outgoing_email_settings = frappe.db.get_singles_dict("Outgoing Email Settings") + if "send_print_as_pdf" in outgoing_email_settings: + print_settings.send_print_as_pdf = outgoing_email_settings.send_print_as_pdf + print_settings.pdf_page_size = outgoing_email_settings.pdf_page_size + + else: + print_settings.send_print_as_pdf = 1 + + print_settings.save() diff --git a/frappe/public/css/bootstrap.css b/frappe/public/css/bootstrap.css index 60babbec0b..c6e36fc3e6 100644 --- a/frappe/public/css/bootstrap.css +++ b/frappe/public/css/bootstrap.css @@ -189,9 +189,9 @@ th { } @media print { * { - color: #000 !important; +/* color: #000 !important;*/ text-shadow: none !important; - background: transparent !important; +/* background: transparent !important;*/ -webkit-box-shadow: none !important; box-shadow: none !important; } @@ -211,7 +211,7 @@ th { } pre, blockquote { - border: 1px solid #999; +/* border: 1px solid #999;*/ page-break-inside: avoid; } @@ -241,24 +241,24 @@ th { .navbar { display: none; } - .table td, +/* .table td, .table th { background-color: #fff !important; } - .btn > .caret, +*/ .btn > .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } - .label { +/* .label { border: 1px solid #000; } - .table { +*/ .table { border-collapse: collapse !important; } - .table-bordered th, + /*.table-bordered th, .table-bordered td { border: 1px solid #ddd !important; - } + }*/ } @font-face { font-family: 'Glyphicons Halflings'; diff --git a/frappe/public/js/frappe/form/print.js b/frappe/public/js/frappe/form/print.js index f23e072592..be569b3981 100644 --- a/frappe/public/js/frappe/form/print.js +++ b/frappe/public/js/frappe/form/print.js @@ -17,6 +17,7 @@ frappe.ui.form.PrintPreview = Class.extend({
\ \ @@ -42,11 +43,13 @@ frappe.ui.form.PrintPreview = Class.extend({ .find(".print-preview-select") .on("change", function() { if(me.is_old_style()) { + me.wrapper.find(".btn-download-pdf").toggle(false); me.preview_old_style(); } else { + me.wrapper.find(".btn-download-pdf").toggle(true); me.preview(); } - }) + }); this.wrapper.find(".btn-print-print").click(function() { if(me.is_old_style()) { @@ -63,6 +66,18 @@ frappe.ui.form.PrintPreview = Class.extend({ me.new_page_preview(); } }); + + this.wrapper.find(".btn-download-pdf").click(function() { + if(!me.is_old_style()) { + var w = window.open("/api/method/frappe.templates.pages.print.download_pdf?" + +"doctype="+encodeURIComponent(me.frm.doc.doctype) + +"&name="+encodeURIComponent(me.frm.doc.name) + +"&format="+me.selected_format()); + if(!w) { + msgprint(__("Please enable pop-ups")); return; + } + } + }); }, preview: function() { var me = this; @@ -102,14 +117,24 @@ frappe.ui.form.PrintPreview = Class.extend({ }); }, preview_old_style: function() { + var me = this; + this.with_old_style({ + format: me.print_sel.val(), + callback: function(html) { + me.wrapper.find(".print-format").html('No {ptype} permission
""".format(ptype=ptype) - } - meta = frappe.get_meta(doc.doctype) return { @@ -59,6 +53,8 @@ def get_html(doc, name=None, print_format=None, meta=None, if isinstance(doc, basestring): doc = frappe.get_doc(json.loads(doc)) + validate_print_permission(doc) + if hasattr(doc, "before_print"): doc.before_print() @@ -88,6 +84,18 @@ def get_html(doc, name=None, print_format=None, meta=None, return html +@frappe.whitelist() +def download_pdf(doctype, name, format=None): + html = frappe.get_print_format(doctype, name, format) + frappe.local.response.filename = "{name}.pdf".format(name=name.replace(" ", "-").replace("/", "-")) + frappe.local.response.filecontent = get_pdf(html) + frappe.local.response.type = "download" + +def validate_print_permission(doc): + for ptype in ("read", "print"): + if not frappe.has_permission(doc.doctype, ptype, doc): + raise frappe.PermissionError(_("No {0} permission").format(ptype)) + def get_letter_head(doc, no_letterhead): if no_letterhead: return "" @@ -168,12 +176,21 @@ def is_visible(df): def get_print_style(style=None): if not style: - style = frappe.db.get_default("print_style") or "Standard" + style = frappe.db.get_single_value("Print Settings", "print_style") or "Standard" css = frappe.get_template("templates/styles/standard.css").render() try: - css += frappe.get_template("templates/styles/" + style.lower() + ".css").render() + additional_css = frappe.get_template("templates/styles/" + style.lower() + ".css").render() + + # move @import to top + for at_import in list(set(re.findall("(@import url\([^\)]+\)[;]?)", additional_css))): + additional_css = additional_css.replace(at_import, "") + + # prepend css with at_import + css = at_import + css + + css += additional_css except TemplateNotFound: pass diff --git a/frappe/templates/print_formats/standard.html b/frappe/templates/print_formats/standard.html index 209ae9dad6..c3d9add59c 100644 --- a/frappe/templates/print_formats/standard.html +++ b/frappe/templates/print_formats/standard.html @@ -8,7 +8,7 @@ {% for section in page %}{error}
Did you log out?
".format(error=cstr(e)) frappe.local.message_title = "Not Permitted" return render_page(path), e.http_status_code