* Add auto_email_report.html * Add table styling for email * wip * commonify template * Right align numeric fields * Add text utility classes * fix testsversion-14
@@ -8,6 +8,7 @@ from frappe import _ | |||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
from datetime import timedelta | from datetime import timedelta | ||||
import frappe.utils | import frappe.utils | ||||
from frappe.utils import now, global_date_format, format_time | |||||
from frappe.utils.xlsxutils import make_xlsx | from frappe.utils.xlsxutils import make_xlsx | ||||
from frappe.utils.csvutils import to_csv | from frappe.utils.csvutils import to_csv | ||||
@@ -76,16 +77,28 @@ class AutoEmailReport(Document): | |||||
return xlsx_file.getvalue() | return xlsx_file.getvalue() | ||||
elif self.format == 'CSV': | elif self.format == 'CSV': | ||||
spreadsheet_data = self.get_spreadsheet_data(columns, data) | |||||
spreadsheet_data = self.get_spreadsheet_data(columns, data) | |||||
return to_csv(spreadsheet_data) | return to_csv(spreadsheet_data) | ||||
else: | else: | ||||
frappe.throw(_('Invalid Output Format')) | frappe.throw(_('Invalid Output Format')) | ||||
def get_html_table(self, columns, data): | |||||
return frappe.render_template('frappe/templates/includes/print_table.html', { | |||||
def get_html_table(self, columns=None, data=None): | |||||
date_time = global_date_format(now()) + ' ' + format_time(now()) | |||||
report_doctype = frappe.db.get_value('Report', self.report, 'ref_doctype') | |||||
return frappe.render_template('frappe/templates/emails/auto_email_report.html', { | |||||
'title': self.name, | |||||
'description': self.description, | |||||
'date_time': date_time, | |||||
'columns': columns, | 'columns': columns, | ||||
'data': data | |||||
'data': data, | |||||
'report_url': frappe.utils.get_url_to_report(self.report, | |||||
self.report_type, report_doctype), | |||||
'report_name': self.report, | |||||
'edit_report_settings': frappe.utils.get_link_to_form('Auto Email Report', | |||||
self.name) | |||||
}) | }) | ||||
@staticmethod | @staticmethod | ||||
@@ -111,29 +124,17 @@ class AutoEmailReport(Document): | |||||
return | return | ||||
attachments = None | attachments = None | ||||
message = '<p>{0}</p>'.format(_('{0} generated on {1}')\ | |||||
.format(frappe.bold(self.name), | |||||
frappe.utils.format_datetime(frappe.utils.now_datetime()))) | |||||
if self.description: | |||||
message += '<hr style="margin: 15px 0px;">' + self.description | |||||
if self.format=='HTML': | |||||
message += '<hr>' + data | |||||
if self.format == "HTML": | |||||
message = data | |||||
else: | else: | ||||
message = self.get_html_table() | |||||
if not self.format=='HTML': | |||||
attachments = [{ | attachments = [{ | ||||
'fname': self.get_file_name(), | 'fname': self.get_file_name(), | ||||
'fcontent': data | 'fcontent': data | ||||
}] | }] | ||||
report_doctype = frappe.db.get_value('Report', self.report, 'ref_doctype') | |||||
report_footer = frappe.render_template(self.get_report_footer(), | |||||
dict(report_url = frappe.utils.get_url_to_report(self.report, self.report_type, report_doctype), | |||||
report_name = self.report, | |||||
edit_report_settings = frappe.utils.get_link_to_form('Auto Email Report', self.name))) | |||||
message += report_footer | |||||
frappe.sendmail( | frappe.sendmail( | ||||
recipients = self.email_to.split(), | recipients = self.email_to.split(), | ||||
subject = self.name, | subject = self.name, | ||||
@@ -141,14 +142,6 @@ class AutoEmailReport(Document): | |||||
attachments = attachments | attachments = attachments | ||||
) | ) | ||||
def get_report_footer(self): | |||||
return """<hr style="margin: 30px 0px 15px 0px;"> | |||||
<p style="font-size: 9px;"> | |||||
View report in your browser: | |||||
<a href= {{report_url}} target="_blank">{{report_name}}</a><br><br> | |||||
Edit Auto Email Report Settings: {{edit_report_settings}} | |||||
</p>""" | |||||
@frappe.whitelist() | @frappe.whitelist() | ||||
def download(name): | def download(name): | ||||
'''Download report locally''' | '''Download report locally''' | ||||
@@ -6,9 +6,10 @@ body { | |||||
p { | p { | ||||
margin: 1em 0 !important; | margin: 1em 0 !important; | ||||
} | } | ||||
.body-table, | |||||
.email-body tr, | |||||
.email-footer tr { | |||||
hr { | |||||
border-top: 1px solid #d1d8dd; | |||||
} | |||||
.body-table { | |||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; | ||||
} | } | ||||
.email-header, | .email-header, | ||||
@@ -17,13 +18,11 @@ p { | |||||
width: 100% !important; | width: 100% !important; | ||||
min-width: 100% !important; | min-width: 100% !important; | ||||
} | } | ||||
.email-body tr { | |||||
.email-body { | |||||
font-size: 14px; | font-size: 14px; | ||||
} | } | ||||
.email-footer { | .email-footer { | ||||
border-top: 1px solid #d1d8dd; | border-top: 1px solid #d1d8dd; | ||||
} | |||||
.email-footer tr { | |||||
font-size: 12px; | font-size: 12px; | ||||
} | } | ||||
.email-header { | .email-header { | ||||
@@ -61,4 +60,64 @@ p { | |||||
background-color: #5E64FF; | background-color: #5E64FF; | ||||
border-color: #444bff; | border-color: #444bff; | ||||
} | } | ||||
.table { | |||||
width: 100%; | |||||
border-collapse: collapse; | |||||
} | |||||
.table td, | |||||
.table th { | |||||
padding: 8px; | |||||
line-height: 1.42857143; | |||||
vertical-align: top; | |||||
border-top: 1px solid #d1d8dd; | |||||
text-align: left; | |||||
} | |||||
.table th { | |||||
font-weight: bold; | |||||
} | |||||
.table > thead > tr > th { | |||||
vertical-align: bottom; | |||||
border-bottom: 2px solid #d1d8dd; | |||||
} | |||||
.table > thead:first-child > tr:first-child > th { | |||||
border-top: none; | |||||
} | |||||
.table.table-bordered { | |||||
border: 1px solid #d1d8dd; | |||||
} | |||||
.table.table-bordered td, | |||||
.table.table-bordered th { | |||||
border: 1px solid #d1d8dd; | |||||
} | |||||
.more-info { | |||||
font-size: 80% !important; | |||||
color: #8D99A6 !important; | |||||
border-top: 1px solid #EBEFF2; | |||||
padding-top: 10px; | |||||
} | |||||
.text-right { | |||||
text-align: right !important; | |||||
} | |||||
.text-center { | |||||
text-align: center !important; | |||||
} | |||||
.text-muted { | |||||
color: #8D99A6 !important; | |||||
} | |||||
.text-extra-muted { | |||||
color: #d1d8dd !important; | |||||
} | |||||
.text-regular { | |||||
font-size: 14px; | |||||
} | |||||
.text-medium { | |||||
font-size: 12px; | |||||
} | |||||
.text-small { | |||||
font-size: 10px; | |||||
} | |||||
/* auto email report */ | |||||
.report-title { | |||||
margin-bottom: 20px; | |||||
} | |||||
/* csslint ignore:end */ | /* csslint ignore:end */ |
@@ -10,7 +10,11 @@ p { | |||||
margin: 1em 0 !important; | margin: 1em 0 !important; | ||||
} | } | ||||
.body-table, .email-body tr, .email-footer tr { | |||||
hr { | |||||
border-top: 1px solid @border-color; | |||||
} | |||||
.body-table { | |||||
font-family: @font-stack; | font-family: @font-stack; | ||||
} | } | ||||
@@ -19,16 +23,13 @@ p { | |||||
min-width: 100% !important; | min-width: 100% !important; | ||||
} | } | ||||
.email-body tr { | |||||
.email-body { | |||||
font-size: @text-regular; | font-size: @text-regular; | ||||
} | } | ||||
.email-footer { | .email-footer { | ||||
border-top: 1px solid @border-color; | border-top: 1px solid @border-color; | ||||
tr { | |||||
font-size: @text-medium; | |||||
} | |||||
font-size: @text-medium; | |||||
} | } | ||||
.email-header { | .email-header { | ||||
@@ -75,4 +76,77 @@ p { | |||||
} | } | ||||
} | } | ||||
/* csslint ignore:end */ | |||||
.table { | |||||
width: 100%; | |||||
border-collapse: collapse; | |||||
td, th { | |||||
padding: 8px; | |||||
line-height: 1.42857143; | |||||
vertical-align: top; | |||||
border-top: 1px solid @border-color; | |||||
text-align: left; | |||||
} | |||||
th { | |||||
font-weight: bold; | |||||
} | |||||
& > thead > tr > th { | |||||
vertical-align: bottom; | |||||
border-bottom: 2px solid @border-color; | |||||
} | |||||
& > thead:first-child > tr:first-child > th { | |||||
border-top: none; | |||||
} | |||||
&.table-bordered { | |||||
border: 1px solid @border-color; | |||||
td, th { | |||||
border: 1px solid @border-color; | |||||
} | |||||
} | |||||
} | |||||
.more-info { | |||||
font-size: 80% !important; | |||||
color: @text-muted !important; | |||||
border-top: 1px solid @light-border-color; | |||||
padding-top: 10px; | |||||
} | |||||
.text-right { | |||||
text-align: right !important; | |||||
} | |||||
.text-center { | |||||
text-align: center !important; | |||||
} | |||||
.text-muted { | |||||
color: @text-muted !important; | |||||
} | |||||
.text-extra-muted { | |||||
color: @text-extra-muted !important; | |||||
} | |||||
.text-regular { | |||||
font-size: @text-regular; | |||||
} | |||||
.text-medium { | |||||
font-size: @text-medium; | |||||
} | |||||
.text-small { | |||||
font-size: @text-small; | |||||
} | |||||
/* auto email report */ | |||||
.report-title { | |||||
margin-bottom: 20px; | |||||
} | |||||
/* csslint ignore:end */ |
@@ -0,0 +1,51 @@ | |||||
{% macro get_alignment(col) %} | |||||
{%- if col.fieldtype in ('Int', 'Float', 'Currency', 'Check') %} class="text-right" {% endif -%} | |||||
{% endmacro %} | |||||
<table class="report-title" border="0" cellpadding="0" cellspacing="0" width="100%"> | |||||
<tr> | |||||
<td> | |||||
<b>{{ title }}</b> <span style="float: right">{{ date_time }}</span> | |||||
</td> | |||||
</tr> | |||||
{% if description %} | |||||
<tr> | |||||
<td>{{ description }}</td> | |||||
</tr> | |||||
{% endif %} | |||||
</table> | |||||
{% if data %} | |||||
<table class="table table-bordered" cellpadding="0" cellspacing="0" border="0" width="100%"> | |||||
<thead> | |||||
<tr> | |||||
{% for col in columns %} | |||||
<th {{- get_alignment(col) }}> | |||||
{{- col.label -}} | |||||
</th> | |||||
{% endfor %} | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
{% for row in data %} | |||||
<tr> | |||||
{% for col in columns %} | |||||
<td {{- get_alignment(col) }}> | |||||
{{- frappe.format(row[col.fieldname], col, row) -}} | |||||
</td> | |||||
{% endfor %} | |||||
</td> | |||||
{% endfor %} | |||||
</tbody> | |||||
</table> | |||||
{% endif %} | |||||
<table class="more-info" border="0" cellpadding="0" cellspacing="0" width="100%"> | |||||
<tr> | |||||
<td> | |||||
<p> | |||||
{{ _("View report in your browser") }}: | |||||
<a href= {{report_url}} target="_blank">{{report_name}}</a> | |||||
</p> | |||||
<p>{{ _("Edit Auto Email Report Settings") }}: {{edit_report_settings}}</p> | |||||
</td> | |||||
</tr> | |||||
</table> |