Przeglądaj źródła

Fixes to print

version-14
Anand Doshi 11 lat temu
rodzic
commit
7087be6559
20 zmienionych plików z 190 dodań i 84 usunięć
  1. +3
    -3
      frappe/__init__.py
  2. +28
    -25
      frappe/core/doctype/communication/communication.py
  3. +3
    -1
      frappe/core/doctype/print_settings/print_settings.json
  4. +1
    -1
      frappe/patches.txt
  5. +13
    -2
      frappe/patches/v4_1/enable_print_as_pdf.py
  6. +9
    -9
      frappe/public/css/bootstrap.css
  7. +39
    -11
      frappe/public/js/frappe/form/print.js
  8. +17
    -7
      frappe/public/js/frappe/views/communication.js
  9. +1
    -1
      frappe/public/js/legacy/print_format.js
  10. +27
    -10
      frappe/templates/pages/print.py
  11. +1
    -1
      frappe/templates/print_formats/standard.html
  12. +4
    -4
      frappe/templates/print_formats/standard_macros.html
  13. +3
    -1
      frappe/templates/styles/classic.css
  14. +10
    -1
      frappe/templates/styles/standard.css
  15. +10
    -2
      frappe/utils/__init__.py
  16. +1
    -1
      frappe/utils/email_lib/email_body.py
  17. +1
    -1
      frappe/utils/formatters.py
  18. +16
    -1
      frappe/utils/pdf.py
  19. +1
    -1
      frappe/utils/response.py
  20. +2
    -1
      frappe/website/render.py

+ 3
- 3
frappe/__init__.py Wyświetl plik

@@ -683,13 +683,13 @@ def format_value(value, df, doc=None):
return frappe.utils.formatters.format_value(value, df, doc) return frappe.utils.formatters.format_value(value, df, doc)


def get_print_format(doctype, name, print_format=None, style=None, as_pdf=False): 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.doctype = doctype
local.form_dict.name = name local.form_dict.name = name
local.form_dict.format = print_format 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: if as_pdf:
print_settings = db.get_singles_dict("Print Settings") print_settings = db.get_singles_dict("Print Settings")


+ 28
- 25
frappe/core/doctype/communication/communication.py Wyświetl plik

@@ -34,7 +34,7 @@ class Communication(Document):
@frappe.whitelist() @frappe.whitelist()
def make(doctype=None, name=None, content=None, subject=None, sent_or_received = "Sent", def make(doctype=None, name=None, content=None, subject=None, sent_or_received = "Sent",
sender=None, recipients=None, communication_medium="Email", send_email=False, 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): 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( 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, _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, 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) date=date)


def _make(doctype=None, name=None, content=None, subject=None, sent_or_received = "Sent", def _make(doctype=None, name=None, content=None, subject=None, sent_or_received = "Sent",
sender=None, recipients=None, communication_medium="Email", send_email=False, 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 # add to Communication
sent_via = None sent_via = None
@@ -89,7 +89,7 @@ def _make(doctype=None, name=None, content=None, subject=None, sent_or_received


if send_email: if send_email:
d = comm 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() @frappe.whitelist()
def get_customer_supplier(args=None): def get_customer_supplier(args=None):
@@ -110,7 +110,7 @@ def get_customer_supplier(args=None):
} }
return {} 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 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: if send_me_a_copy:
mail.cc.append(frappe.db.get_value("User", frappe.session.user, "email")) 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): for a in json.loads(attachments):
try: try:
@@ -159,6 +141,27 @@ def send_comm_email(d, name, sent_via=None, print_html=None, attachments='[]', s


send(mail) 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): def set_portal_link(sent_via, comm):
"""set portal link in footer""" """set portal link in footer"""




+ 3
- 1
frappe/core/doctype/print_settings/print_settings.json Wyświetl plik

@@ -11,6 +11,7 @@
"permlevel": 0 "permlevel": 0
}, },
{ {
"default": "1",
"description": "Send Email Print Attachments as PDF (Recommended)", "description": "Send Email Print Attachments as PDF (Recommended)",
"fieldname": "send_print_as_pdf", "fieldname": "send_print_as_pdf",
"fieldtype": "Check", "fieldtype": "Check",
@@ -32,6 +33,7 @@
"permlevel": 0 "permlevel": 0
}, },
{ {
"default": "",
"fieldname": "print_style", "fieldname": "print_style",
"fieldtype": "Select", "fieldtype": "Select",
"in_list_view": 1, "in_list_view": 1,
@@ -48,7 +50,7 @@
], ],
"icon": "icon-cog", "icon": "icon-cog",
"issingle": 1, "issingle": 1,
"modified": "2014-07-17 08:08:27.291811",
"modified": "2014-07-23 04:59:45.626239",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Core", "module": "Core",
"name": "Print Settings", "name": "Print Settings",


+ 1
- 1
frappe/patches.txt Wyświetl plik

@@ -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 execute:frappe.db.sql("""delete from `tabUserRole` where ifnull(parentfield, '')=''""") #2014-06-17
frappe.patches.v4_0.remove_user_owner_custom_field frappe.patches.v4_0.remove_user_owner_custom_field
execute:frappe.delete_doc("DocType", "Website Template") 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 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 frappe.patches.v4_1.enable_outgoing_email_settings
execute:frappe.db.sql("""update `tabSingles` set `value`=`doctype` where `field`='name'""") #2014-07-04 execute:frappe.db.sql("""update `tabSingles` set `value`=`doctype` where `field`='name'""") #2014-07-04


+ 13
- 2
frappe/patches/v4_1/enable_print_as_pdf.py Wyświetl plik

@@ -6,10 +6,21 @@ import frappe


def execute(): def execute():
frappe.reload_doc("core", "doctype", "print_settings") 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: try:
import pdfkit import pdfkit
except ImportError: except ImportError:
pass pass
else: 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()

+ 9
- 9
frappe/public/css/bootstrap.css Wyświetl plik

@@ -189,9 +189,9 @@ th {
} }
@media print { @media print {
* { * {
color: #000 !important;
/* color: #000 !important;*/
text-shadow: none !important; text-shadow: none !important;
background: transparent !important;
/* background: transparent !important;*/
-webkit-box-shadow: none !important; -webkit-box-shadow: none !important;
box-shadow: none !important; box-shadow: none !important;
} }
@@ -211,7 +211,7 @@ th {
} }
pre, pre,
blockquote { blockquote {
border: 1px solid #999;
/* border: 1px solid #999;*/


page-break-inside: avoid; page-break-inside: avoid;
} }
@@ -241,24 +241,24 @@ th {
.navbar { .navbar {
display: none; display: none;
} }
.table td,
/* .table td,
.table th { .table th {
background-color: #fff !important; background-color: #fff !important;
} }
.btn > .caret,
*/ .btn > .caret,
.dropup > .btn > .caret { .dropup > .btn > .caret {
border-top-color: #000 !important; border-top-color: #000 !important;
} }
.label {
/* .label {
border: 1px solid #000; border: 1px solid #000;
} }
.table {
*/ .table {
border-collapse: collapse !important; border-collapse: collapse !important;
} }
.table-bordered th,
/*.table-bordered th,
.table-bordered td { .table-bordered td {
border: 1px solid #ddd !important; border: 1px solid #ddd !important;
}
}*/
} }
@font-face { @font-face {
font-family: 'Glyphicons Halflings'; font-family: 'Glyphicons Halflings';


+ 39
- 11
frappe/public/js/frappe/form/print.js Wyświetl plik

@@ -17,6 +17,7 @@ frappe.ui.form.PrintPreview = Class.extend({
<div class="checkbox"><label><input type="checkbox" class="print-letterhead" checked/> Letterhead</label></div></div>\ <div class="checkbox"><label><input type="checkbox" class="print-letterhead" checked/> Letterhead</label></div></div>\
<div class="col-xs-6 text-right" style="padding-top: 7px;">\ <div class="col-xs-6 text-right" style="padding-top: 7px;">\
<a style="margin-right: 7px;" class="btn-print-preview text-muted small">Preview</a>\ <a style="margin-right: 7px;" class="btn-print-preview text-muted small">Preview</a>\
<a style="margin-right: 7px;" class="btn-download-pdf text-muted small">Download PDF</a>\
<strong><a style="margin-right: 7px;" class="btn-print-print">Print</a></strong>\ <strong><a style="margin-right: 7px;" class="btn-print-print">Print</a></strong>\
<a class="close">×</a>\ <a class="close">×</a>\
</div>\ </div>\
@@ -42,11 +43,13 @@ frappe.ui.form.PrintPreview = Class.extend({
.find(".print-preview-select") .find(".print-preview-select")
.on("change", function() { .on("change", function() {
if(me.is_old_style()) { if(me.is_old_style()) {
me.wrapper.find(".btn-download-pdf").toggle(false);
me.preview_old_style(); me.preview_old_style();
} else { } else {
me.wrapper.find(".btn-download-pdf").toggle(true);
me.preview(); me.preview();
} }
})
});


this.wrapper.find(".btn-print-print").click(function() { this.wrapper.find(".btn-print-print").click(function() {
if(me.is_old_style()) { if(me.is_old_style()) {
@@ -63,6 +66,18 @@ frappe.ui.form.PrintPreview = Class.extend({
me.new_page_preview(); 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() { preview: function() {
var me = this; var me = this;
@@ -102,14 +117,24 @@ frappe.ui.form.PrintPreview = Class.extend({
}); });
}, },
preview_old_style: function() { 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('<div class="alert alert-warning">'
+__("Warning: This Print Format is in old style and cannot be generated via the API.")
+'</div>'
+ html);
},
no_letterhead: !this.with_letterhead(),
only_body: true,
no_heading: true
});
},
with_old_style: function(opts) {
var me = this; var me = this;
frappe.require("/assets/js/print_format_v3.min.js"); frappe.require("/assets/js/print_format_v3.min.js");
_p.build(me.print_sel.val(), function(html) {
me.wrapper.find(".print-format").html('<div class="alert alert-warning">'
+__("Warning: This Print Format is in old style and cannot be generated via the API.")
+'</div>'
+ html);
}, !this.with_letterhead(), true, true);
_p.build(opts.format, opts.callback, opts.no_letterhead, opts.only_body, opts.no_heading);
}, },
print_old_style: function() { print_old_style: function() {
frappe.require("/assets/js/print_format_v3.min.js"); frappe.require("/assets/js/print_format_v3.min.js");
@@ -124,11 +149,14 @@ frappe.ui.form.PrintPreview = Class.extend({
selected_format: function() { selected_format: function() {
return this.print_sel.val(); return this.print_sel.val();
}, },
is_old_style: function() {
return this.get_print_format().print_format_type==="Client"
is_old_style: function(format) {
return this.get_print_format(format).print_format_type==="Client";
}, },
get_print_format: function() {
var format = this.selected_format();
get_print_format: function(format) {
if (!format) {
format = this.selected_format();
}

if(locals["Print Format"] && locals["Print Format"][format]) { if(locals["Print Format"] && locals["Print Format"][format]) {
return locals["Print Format"][format] return locals["Print Format"][format]
} else { } else {


+ 17
- 7
frappe/public/js/frappe/views/communication.js Wyświetl plik

@@ -264,8 +264,8 @@ frappe.views.CommunicationComposer = Class.extend({
if (cur_frm) { if (cur_frm) {
$(fields.select_print_format.input) $(fields.select_print_format.input)
.empty() .empty()
.add_options(cur_frm.print_formats)
.val(cur_frm.print_formats[0]);
.add_options(cur_frm.print_preview.print_formats)
.val(cur_frm.print_preview.print_formats[0]);
} else { } else {
$(fields.attach_document_print.wrapper).toggle(false); $(fields.attach_document_print.wrapper).toggle(false);
} }
@@ -324,20 +324,29 @@ frappe.views.CommunicationComposer = Class.extend({
}) })


if(form_values.attach_document_print) { if(form_values.attach_document_print) {
_p.build(form_values.select_print_format || "", function(print_format_html) {
me.send_email(btn, form_values, selected_attachments, print_format_html);
});
if (cur_frm.print_preview.is_old_style(form_values.select_print_format || "")) {
cur_frm.print_preview.with_old_style({
format: form_values.select_print_format,
callback: function(print_html) {
me.send_email(btn, form_values, selected_attachments, print_html);
}
});
} else {
me.send_email(btn, form_values, selected_attachments, null, form_values.select_print_format || "");
}

} else { } else {
me.send_email(btn, form_values, selected_attachments); me.send_email(btn, form_values, selected_attachments);
} }
}); });
}, },


send_email: function(btn, form_values, selected_attachments, print_html) {
send_email: function(btn, form_values, selected_attachments, print_html, print_format) {
var me = this; var me = this;


if(!form_values.attach_document_print) { if(!form_values.attach_document_print) {
print_html = "";
print_html = null;
print_format = null;
} }


if(form_values.send_email) { if(form_values.send_email) {
@@ -362,6 +371,7 @@ frappe.views.CommunicationComposer = Class.extend({
send_me_a_copy: form_values.send_me_a_copy, send_me_a_copy: form_values.send_me_a_copy,
send_email: form_values.send_email, send_email: form_values.send_email,
print_html: print_html, print_html: print_html,
print_format: print_format,
communication_medium: form_values.communication_medium, communication_medium: form_values.communication_medium,
sent_or_received: form_values.sent_or_received, sent_or_received: form_values.sent_or_received,
attachments: selected_attachments attachments: selected_attachments


+ 1
- 1
frappe/public/js/legacy/print_format.js Wyświetl plik

@@ -86,7 +86,7 @@ $.extend(_p, {


dialog.onshow = function() { dialog.onshow = function() {
var $print = dialog.fields_dict.print_format.$input; var $print = dialog.fields_dict.print_format.$input;
$print.empty().add_options(cur_frm.print_formats);
$print.empty().add_options(cur_frm.print_preview.print_formats);


if(cur_frm.$print_view_select && cur_frm.$print_view_select.val()) if(cur_frm.$print_view_select && cur_frm.$print_view_select.val())
$print.val(cur_frm.$print_view_select.val()); $print.val(cur_frm.$print_view_select.val());


+ 27
- 10
frappe/templates/pages/print.py Wyświetl plik

@@ -3,12 +3,13 @@


from __future__ import unicode_literals from __future__ import unicode_literals


import frappe, os, copy, json
import frappe, os, copy, json, re
from frappe import _ from frappe import _


from frappe.modules import get_doc_path from frappe.modules import get_doc_path
from jinja2 import TemplateNotFound from jinja2 import TemplateNotFound
from frappe.utils import cint from frappe.utils import cint
from frappe.utils.pdf import get_pdf


no_cache = 1 no_cache = 1
no_sitemap = 1 no_sitemap = 1
@@ -29,13 +30,6 @@ def get_context(context):


doc = frappe.get_doc(frappe.form_dict.doctype, frappe.form_dict.name) doc = frappe.get_doc(frappe.form_dict.doctype, frappe.form_dict.name)


for ptype in ("read", "print"):
if not frappe.has_permission(doc.doctype, ptype, doc):
return {
"body": """<h1>Error</h1>
<p>No {ptype} permission</p>""".format(ptype=ptype)
}

meta = frappe.get_meta(doc.doctype) meta = frappe.get_meta(doc.doctype)


return { return {
@@ -59,6 +53,8 @@ def get_html(doc, name=None, print_format=None, meta=None,
if isinstance(doc, basestring): if isinstance(doc, basestring):
doc = frappe.get_doc(json.loads(doc)) doc = frappe.get_doc(json.loads(doc))


validate_print_permission(doc)

if hasattr(doc, "before_print"): if hasattr(doc, "before_print"):
doc.before_print() doc.before_print()


@@ -88,6 +84,18 @@ def get_html(doc, name=None, print_format=None, meta=None,


return html 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): def get_letter_head(doc, no_letterhead):
if no_letterhead: if no_letterhead:
return "" return ""
@@ -168,12 +176,21 @@ def is_visible(df):


def get_print_style(style=None): def get_print_style(style=None):
if not style: 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() css = frappe.get_template("templates/styles/standard.css").render()


try: 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: except TemplateNotFound:
pass pass




+ 1
- 1
frappe/templates/print_formats/standard.html Wyświetl plik

@@ -8,7 +8,7 @@
{% for section in page %} {% for section in page %}
<div class="row"> <div class="row">
{% for column in section %} {% for column in section %}
<div class="col-sm-{{ (12 / section|len)|int }}">
<div class="col-xs-{{ (12 / section|len)|int }}">
{% for df in column %} {% for df in column %}
{{ render_field(df, doc) }} {{ render_field(df, doc) }}
{% endfor %} {% endfor %}


+ 4
- 4
frappe/templates/print_formats/standard_macros.html Wyświetl plik

@@ -49,13 +49,13 @@


{%- macro render_field_with_label(df, doc) -%} {%- macro render_field_with_label(df, doc) -%}
<div class="row"> <div class="row">
<div class="col-sm-5 text-right">
<div class="col-xs-5 text-right">
{% if df.fieldtype not in ("Image","HTML") and {% if df.fieldtype not in ("Image","HTML") and
doc.get(df.fieldname) != None %} doc.get(df.fieldname) != None %}
<label>{{ df.label }}</label> <label>{{ df.label }}</label>
{% endif %} {% endif %}
</div> </div>
<div class="col-sm-7 {%- if df.fieldtype
<div class="col-xs-7 {%- if df.fieldtype
in ('Int', 'Check', 'Float', 'Currency') %} text-right{% endif %}"> in ('Int', 'Check', 'Float', 'Currency') %} text-right{% endif %}">
{% if doc.get(df.fieldname) != None -%} {% if doc.get(df.fieldname) != None -%}
{{ print_value(df, doc) }}{% endif %} {{ print_value(df, doc) }}{% endif %}
@@ -75,9 +75,9 @@


{%- macro print_value(df, doc, parent_doc=None) -%} {%- macro print_value(df, doc, parent_doc=None) -%}
{% if df.fieldtype=="Check" %} {% if df.fieldtype=="Check" %}
<i class="{{ 'icon-check' if doc[df.fieldname] else 'icon-check-empty' }}"></i>
<i class="{{ 'icon-check' if doc[df.fieldname] else 'icon-check-empty' }}"></i>
{% elif df.fieldtype=="Image" %} {% elif df.fieldtype=="Image" %}
<img src="{{ doc[doc.meta.get_field(df.fieldname).options] }}" class="img-responsive">
<img src="{{ doc[doc.meta.get_field(df.fieldname).options] }}" class="img-responsive">
{% else %} {% else %}
{{ doc.get_formatted(df.fieldname, parent_doc or doc) }} {{ doc.get_formatted(df.fieldname, parent_doc or doc) }}
{% endif %} {% endif %}


+ 3
- 1
frappe/templates/styles/classic.css Wyświetl plik

@@ -1,3 +1,5 @@
@import url(http://fonts.googleapis.com/css?family=Noto+Serif:400,700);

/* /*
common style for whole page common style for whole page
This should include: This should include:
@@ -12,5 +14,5 @@
.print-format h2, .print-format h2,
.print-format h3, .print-format h3,
.print-format h4 { .print-format h4 {
font-family: serif;
font-family: 'Noto Serif', serif;
} }

+ 10
- 1
frappe/templates/styles/standard.css Wyświetl plik

@@ -1,3 +1,5 @@
@import url(http://fonts.googleapis.com/css?family=Noto+Sans:400,700);

@media screen { @media screen {
.print-format-gutter { .print-format-gutter {
background-color: #ddd; background-color: #ddd;
@@ -26,8 +28,16 @@
} }
} }


@media print {
.print-format p {
margin-left: 1px;
margin-right: 1px;
}
}

.print-format { .print-format {
font-size: 9pt; font-size: 9pt;
-webkit-print-color-adjust:exact;
} }


.page-break { .page-break {
@@ -49,4 +59,3 @@
table.no-border, table.no-border td { table.no-border, table.no-border td {
border: 0px; border: 0px;
} }


+ 10
- 2
frappe/utils/__init__.py Wyświetl plik

@@ -348,9 +348,17 @@ def fmt_money(amount, precision=None, currency=None):
""" """
Convert to string with commas for thousands, millions etc Convert to string with commas for thousands, millions etc
""" """
number_format = frappe.db.get_default("number_format") or "#,###.##"
decimal_str, comma_str, precision = get_number_format_info(number_format)
number_format = None
if currency:
number_format = frappe.db.get_value("Currency", currency, "number_format")

if not number_format:
number_format = frappe.db.get_default("number_format") or "#,###.##"

decimal_str, comma_str, number_format_precision = get_number_format_info(number_format)


if not precision:
precision = number_format_precision


amount = '%.*f' % (precision, flt(amount)) amount = '%.*f' % (precision, flt(amount))
if amount.find('.') == -1: if amount.find('.') == -1:


+ 1
- 1
frappe/utils/email_lib/email_body.py Wyświetl plik

@@ -17,7 +17,7 @@ def get_email(recipients, sender='', msg='', subject='[No Subject]',
msg = markdown(msg) msg = markdown(msg)
emailobj.set_html(msg, text_content, footer=footer, print_html=print_html, formatted=formatted) emailobj.set_html(msg, text_content, footer=footer, print_html=print_html, formatted=formatted)


for attach in attachments:
for attach in (attachments or []):
emailobj.add_attachment(**attach) emailobj.add_attachment(**attach)


return emailobj return emailobj


+ 1
- 1
frappe/utils/formatters.py Wyświetl plik

@@ -14,7 +14,7 @@ def format_value(value, df, doc=None):
currency=get_field_currency(df, doc) if doc else None) currency=get_field_currency(df, doc) if doc else None)


elif df.fieldtype == "Float": elif df.fieldtype == "Float":
return fmt_money(value)
return fmt_money(value, precision=get_field_precision(df, doc))


elif df.fieldtype == "Percent": elif df.fieldtype == "Percent":
return "{}%".format(flt(value, 2)) return "{}%".format(flt(value, 2))


+ 16
- 1
frappe/utils/pdf.py Wyświetl plik

@@ -2,13 +2,28 @@
# MIT License. See license.txt # MIT License. See license.txt


import pdfkit, os, frappe import pdfkit, os, frappe
from frappe.utils import scrub_urls


def get_pdf(html, options=None): def get_pdf(html, options=None):
if not options: if not options:
options = {} options = {}

options.update({
"print-media-type": None,
"background": None,
"images": None,
'margin-top': '15mm',
'margin-right': '15mm',
'margin-bottom': '15mm',
'margin-left': '15mm',
'encoding': "UTF-8",
'no-outline': None
})

if not options.get("page-size"): if not options.get("page-size"):
options['page-size'] = frappe.df.get_single_value("Print Settings", "pdf_page_size") or "A4"
options['page-size'] = frappe.db.get_single_value("Print Settings", "pdf_page_size") or "A4"


html = scrub_urls(html)
fname = os.path.join("/tmp", frappe.generate_hash() + ".pdf") fname = os.path.join("/tmp", frappe.generate_hash() + ".pdf")
pdfkit.from_string(html, fname, options=options or {}) pdfkit.from_string(html, fname, options=options or {})




+ 1
- 1
frappe/utils/response.py Wyświetl plik

@@ -49,7 +49,7 @@ def as_csv():


def as_raw(): def as_raw():
response = Response() response = Response()
response.headers[b"Content-Type"] = mimetypes.guess_type(frappe.response['filename'])[0] or b"application/unknown"
response.headers[b"Content-Type"] = frappe.response.get("content_type") or mimetypes.guess_type(frappe.response['filename'])[0] or b"application/unknown"
response.headers[b"Content-Disposition"] = ("filename=%s" % frappe.response['filename'].replace(' ', '_')).encode("utf-8") response.headers[b"Content-Disposition"] = ("filename=%s" % frappe.response['filename'].replace(' ', '_')).encode("utf-8")
response.data = frappe.response['filecontent'] response.data = frappe.response['filecontent']
return response return response


+ 2
- 1
frappe/website/render.py Wyświetl plik

@@ -3,6 +3,7 @@


from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
from frappe.utils import cstr
import mimetypes, json import mimetypes, json
from werkzeug.wrappers import Response from werkzeug.wrappers import Response


@@ -49,7 +50,7 @@ def render(path, http_status_code=None):


def render_403(e): def render_403(e):
path = "message" path = "message"
frappe.local.message = "Did you log out?"
frappe.local.message = "<p><strong>{error}</strong></p><p>Did you log out?</p>".format(error=cstr(e))
frappe.local.message_title = "Not Permitted" frappe.local.message_title = "Not Permitted"
return render_page(path), e.http_status_code return render_page(path), e.http_status_code




Ładowanie…
Anuluj
Zapisz