fix: print Total, Additional Discount, Net Total in that order

Default Standard Sales Invoice and Tax Invoice/Receipt printed the
Additional Discount Amount among the charges, after the Total line but
with no total after the discount. App copies of ERPNext's totals
includes are swapped in via doc.print_templates:

- taxes.html: a discount on Net Total is followed by the Net Total line
  ahead of the charges; a discount on Grand Total stays after them.
- total.html: with inclusive tax, "Total (Without Tax)" is the total
  before the discount (net_total + discount_amount); upstream printed
  net_total, which already has the discount taken off, so the same
  figure appeared before and after the discount line.
This commit is contained in:
kurogeek committed 2026-09-17 10:02:23 +00:00
1 parent 8cba58ba02
commit 71eda0bec9
3 files changed
+53 -2

No files matched your search

@@ -12,7 +12,7 @@
"font": null,
"font_size": 14,
"format_data": null,
"html": "{%- from \"templates/print_formats/standard_macros.html\" import add_header, render_field with context -%}\n{%- set bank_account = get_company_bank_account(doc.company) -%}\n{#- ERPNext hides taxes marked \"Is this Tax included in Basic Rate?\" unless Accounts Settings\n enables \"Show Inclusive Tax in Print\"; always show them here so the tax line and\n \"Total (Without Tax)\" appear on invoices with inclusive tax. -#}\n{%- if doc.get(\"taxes\", {\"included_in_print_rate\": 1}) -%}\n\t{%- set ignored = doc.flags.update({\"show_inclusive_tax_in_print\": 1}) -%}\n{%- endif -%}\n{#- Standard layout prints every non-empty field; drop the ones this invoice does not need.\n posting_date / due_date are printed in the heading, customer fields in the Customer section,\n in_words in the left column of the Totals section. -#}\n{%- set hidden_fields = [\n\t\"total_qty\", \"update_billed_amount_in_delivery_note\", \"amount_eligible_for_commission\", \"company_tax_id\",\n\t\"disable_rounded_total\",\n\t\"posting_date\", \"due_date\",\n\t\"customer_name\", \"address_display\", \"contact_display\", \"contact_mobile\", \"contact_email\", \"tax_id\",\n\t\"in_words\",\n] -%}\n{#- rounded_total keeps a value even when rounding is disabled, so the standard layout would print it. -#}\n{%- if doc.is_rounded_total_disabled() -%}{%- set ignored = hidden_fields.append(\"rounded_total\") -%}{%- endif -%}\n{#- add_header renders this string via frappe.render_template with {\"doc\": doc}, so it is kept\n unrendered with {% raw %}. Same markup as the stock heading plus a right-aligned date block. -#}\n{%- set heading_template -%}\n{% raw %}\n<div class=\"print-heading\">\n\t<style>\n\t\t.print-heading .heading-dates { float: right; text-align: right; margin-top: 4px; white-space: nowrap; }\n\t\t.print-heading .heading-dates label { display: inline; font-weight: 700; margin: 0 4px 0 0; }\n\t\t.print-heading .heading-clear { clear: both; }\n\t</style>\n\t<div class=\"heading-dates\">\n\t\t<div><label>{{ _(doc.meta.get_label(\"posting_date\")) }}:</label> {{ doc.get_formatted(\"posting_date\") }}</div>\n\t\t{%- if doc.due_date %}\n\t\t<div><label>{{ _(doc.meta.get_label(\"due_date\")) }}:</label> {{ doc.get_formatted(\"due_date\") }}</div>\n\t\t{%- endif %}\n\t</div>\n\t<h2>\n\t\t<div>{{ _(doc.select_print_heading) or (_(doc.print_heading) if doc.print_heading != None else _(doc.doctype)) }}</div>\n\t\t<small class=\"sub-heading\">{{ _(doc.sub_heading) if doc.sub_heading != None else _(doc.name) }}</small>\n\t</h2>\n\t<div class=\"heading-clear\"></div>\n</div>\n{% endraw %}\n{%- endset -%}\n{#- Standard layout prints every non-empty child column; keep the item table to the essentials -#}\n{%- set item_columns = [\n\t{\"fieldname\": \"item_code\"},\n\t{\"fieldname\": \"description\"},\n\t{\"fieldname\": \"qty\"},\n\t{\"fieldname\": \"rate\"},\n\t{\"fieldname\": \"amount\"},\n] -%}\n\n{%- macro render_fields(fields, no_of_cols) -%}\n\t{%- for df in fields -%}\n\t\t{%- if df.fieldname not in hidden_fields -%}\n\t\t\t{%- if df.fieldname == \"items\" -%}\n\t\t\t\t{%- set df = df.as_dict() -%}\n\t\t\t\t{%- set ignored = df.update({\"visible_columns\": item_columns}) -%}\n\t\t\t{%- endif -%}\n\t\t\t{{ render_field(df, doc, no_of_cols) }}\n\t\t{%- endif -%}\n\t{%- endfor -%}\n{%- endmacro -%}\n\n{% for page in layout %}\n<div class=\"page-break\">\n\t<div {% if print_settings.repeat_header_footer %} id=\"header-html\" class=\"hidden-pdf\" {% endif %}>\n\t\t{{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings, heading_template) }}\n\t</div>\n\n\t{% if loop.first %}\n\t<div class=\"row section-break\" data-label=\"{{ _(\"Customer\") }}\">\n\t\t<div class=\"col-xs-12 column-break\">\n\t\t\t<h4>{{ _(\"Customer\") }}</h4>\n\t\t\t<style>\n\t\t\t\t.customer-details { width: 100%; }\n\t\t\t\t.customer-details td { padding: 0 !important; border: 0; vertical-align: top; }\n\t\t\t\t.customer-details td.text-muted { width: 40%; padding-right: 1em !important; white-space: nowrap; }\n\t\t\t</style>\n\t\t</div>\n\t\t<div class=\"col-xs-6 column-break\">\n\t\t\t<table class=\"customer-details\">\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr><td class=\"text-muted\">{{ _(doc.meta.get_label(\"customer_name\")) }}</td><td>{{ doc.customer_name or doc.customer }}</td></tr>\n\t\t\t\t\t{% if doc.address_display %}\n\t\t\t\t\t<tr><td class=\"text-muted\">{{ _(doc.meta.get_label(\"address_display\")) }}</td><td>{{ doc.address_display }}</td></tr>\n\t\t\t\t\t{% endif %}\n\t\t\t\t\t{% if doc.tax_id %}\n\t\t\t\t\t<tr><td class=\"text-muted\">{{ _(doc.meta.get_label(\"tax_id\")) }}</td><td>{{ doc.tax_id }}</td></tr>\n\t\t\t\t\t{% endif %}\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t</div>\n\t\t<div class=\"col-xs-6 column-break\">\n\t\t\t{% if doc.contact_person %}\n\t\t\t{#- Sales Invoice carries the contact's mobile and email but not its phone; read that from the Contact. -#}\n\t\t\t{%- set contact_phone = frappe.db.get_valLine truncated
"html": "{%- from \"templates/print_formats/standard_macros.html\" import add_header, render_field with context -%}\n{%- set bank_account = get_company_bank_account(doc.company) -%}\n{#- ERPNext hides taxes marked \"Is this Tax included in Basic Rate?\" unless Accounts Settings\n enables \"Show Inclusive Tax in Print\"; always show them here so the tax line and\n \"Total (Without Tax)\" appear on invoices with inclusive tax. -#}\n{%- if doc.get(\"taxes\", {\"included_in_print_rate\": 1}) -%}\n\t{%- set ignored = doc.flags.update({\"show_inclusive_tax_in_print\": 1}) -%}\n{%- endif -%}\n{#- App copies of ERPNext's totals includes: \"total\" prints the total before an Additional Discount\n on Net Total with inclusive tax; \"taxes\" prints that discount and Net Total ahead of the charges. -#}\n{%- set ignored = doc.print_templates.update({\"total\": \"default_thai_company/templates/print_formats/includes/total.html\"}) -%}\n{%- if doc.print_templates.get(\"taxes\") -%}\n\t{%- set ignored = doc.print_templates.update({\"taxes\": \"default_thai_company/templates/print_formats/includes/taxes.html\"}) -%}\n{%- endif -%}\n{#- Standard layout prints every non-empty field; drop the ones this invoice does not need.\n posting_date / due_date are printed in the heading, customer fields in the Customer section,\n in_words in the left column of the Totals section. -#}\n{%- set hidden_fields = [\n\t\"total_qty\", \"update_billed_amount_in_delivery_note\", \"amount_eligible_for_commission\", \"company_tax_id\",\n\t\"disable_rounded_total\",\n\t\"posting_date\", \"due_date\",\n\t\"customer_name\", \"address_display\", \"contact_display\", \"contact_mobile\", \"contact_email\", \"tax_id\",\n\t\"in_words\",\n] -%}\n{#- rounded_total keeps a value even when rounding is disabled, so the standard layout would print it. -#}\n{%- if doc.is_rounded_total_disabled() -%}{%- set ignored = hidden_fields.append(\"rounded_total\") -%}{%- endif -%}\n{#- add_header renders this string via frappe.render_template with {\"doc\": doc}, so it is kept\n unrendered with {% raw %}. Same markup as the stock heading plus a right-aligned date block. -#}\n{%- set heading_template -%}\n{% raw %}\n<div class=\"print-heading\">\n\t<style>\n\t\t.print-heading .heading-dates { float: right; text-align: right; margin-top: 4px; white-space: nowrap; }\n\t\t.print-heading .heading-dates label { display: inline; font-weight: 700; margin: 0 4px 0 0; }\n\t\t.print-heading .heading-clear { clear: both; }\n\t</style>\n\t<div class=\"heading-dates\">\n\t\t<div><label>{{ _(doc.meta.get_label(\"posting_date\")) }}:</label> {{ doc.get_formatted(\"posting_date\") }}</div>\n\t\t{%- if doc.due_date %}\n\t\t<div><label>{{ _(doc.meta.get_label(\"due_date\")) }}:</label> {{ doc.get_formatted(\"due_date\") }}</div>\n\t\t{%- endif %}\n\t</div>\n\t<h2>\n\t\t<div>{{ _(doc.select_print_heading) or (_(doc.print_heading) if doc.print_heading != None else _(doc.doctype)) }}</div>\n\t\t<small class=\"sub-heading\">{{ _(doc.sub_heading) if doc.sub_heading != None else _(doc.name) }}</small>\n\t</h2>\n\t<div class=\"heading-clear\"></div>\n</div>\n{% endraw %}\n{%- endset -%}\n{#- Standard layout prints every non-empty child column; keep the item table to the essentials -#}\n{%- set item_columns = [\n\t{\"fieldname\": \"item_code\"},\n\t{\"fieldname\": \"description\"},\n\t{\"fieldname\": \"qty\"},\n\t{\"fieldname\": \"rate\"},\n\t{\"fieldname\": \"amount\"},\n] -%}\n\n{%- macro render_fields(fields, no_of_cols) -%}\n\t{%- for df in fields -%}\n\t\t{%- if df.fieldname not in hidden_fields -%}\n\t\t\t{%- if df.fieldname == \"items\" -%}\n\t\t\t\t{%- set df = df.as_dict() -%}\n\t\t\t\t{%- set ignored = df.update({\"visible_columns\": item_columns}) -%}\n\t\t\t{%- endif -%}\n\t\t\t{{ render_field(df, doc, no_of_cols) }}\n\t\t{%- endif -%}\n\t{%- endfor -%}\n{%- endmacro -%}\n\n{% for page in layout %}\n<div class=\"page-break\">\n\t<div {% if print_settings.repeat_header_footer %} id=\"header-html\" class=\"hidden-pdf\" {% endif %}>\n\t\t{{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings, heading_template) }}\n\t</div>\n\n\t{% if loop.first %}\n\t<div class=\"row section-break\" data-label=\"{{ _(\"Customer\") }}\">\n\t\t<div class=\"col-xs-12 column-break\">\n\t\t\t<h4>{{ _(\"Customer\") }}</h4>\n\t\t\t<style>\n\t\t\t\t.customer-details { width: 100%; }\n\t\t\t\t.customer-details td { padding: 0 !important; border: 0; vertical-align: top; }\n\t\t\t\t.customer-details td.text-muted { width: 40%; padding-right: 1em !important; white-space: nowrap; }\n\t\t\t</style>\n\t\t</div>\n\t\t<div class=\"col-xs-6 column-break\">\n\t\t\t<table class=\"customer-details\">\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr><td class=\"text-muted\">{{ _(doc.meta.get_label(\"customer_name\")) }}</td><td>{{ doc.customer_name or doc.customer }}</td></tr>\n\t\t\t\t\t{% if doc.address_display %}\n\t\t\t\t\t<tr><td class=\"text-muted\">{{ _(doc.meta.get_label(\"addrLine truncated
"line_breaks": 0,
"margin_bottom": 15.0,
"margin_left": 15.0,
@@ -46,7 +46,7 @@
"font": null,
"font_size": 14,
"format_data": null,
"html": "{%- from \"templates/print_formats/standard_macros.html\" import add_header, render_field with context -%}\n{#- ERPNext hides taxes marked \"Is this Tax included in Basic Rate?\" unless Accounts Settings\n enables \"Show Inclusive Tax in Print\"; always show them here so the tax line and\n \"Total (Without Tax)\" appear on invoices with inclusive tax. -#}\n{%- if doc.get(\"taxes\", {\"included_in_print_rate\": 1}) -%}\n\t{%- set ignored = doc.flags.update({\"show_inclusive_tax_in_print\": 1}) -%}\n{%- endif -%}\n{#- Standard layout prints every non-empty field; drop the ones this invoice does not need.\n posting_date / due_date are printed in the heading, customer fields in the Customer section,\n in_words in the left column of the Totals section. -#}\n{%- set hidden_fields = [\n\t\"total_qty\", \"update_billed_amount_in_delivery_note\", \"amount_eligible_for_commission\", \"company_tax_id\",\n\t\"disable_rounded_total\",\n\t\"posting_date\", \"due_date\",\n\t\"customer_name\", \"address_display\", \"contact_display\", \"contact_mobile\", \"contact_email\", \"tax_id\",\n\t\"in_words\",\n] -%}\n{#- rounded_total keeps a value even when rounding is disabled, so the standard layout would print it. -#}\n{%- if doc.is_rounded_total_disabled() -%}{%- set ignored = hidden_fields.append(\"rounded_total\") -%}{%- endif -%}\n{#- add_header renders this string via frappe.render_template with {\"doc\": doc}, so it is kept\n unrendered with {% raw %}. Same markup as the stock heading plus a right-aligned date block. -#}\n{%- set heading_template -%}\n{% raw %}\n<div class=\"print-heading\">\n\t<style>\n\t\t.print-heading .heading-dates { float: right; text-align: right; margin-top: 4px; white-space: nowrap; }\n\t\t.print-heading .heading-dates label { display: inline; font-weight: 700; margin: 0 4px 0 0; }\n\t\t.print-heading .heading-clear { clear: both; }\n\t</style>\n\t<div class=\"heading-dates\">\n\t\t<div><label>{{ _(doc.meta.get_label(\"posting_date\")) }}:</label> {{ doc.get_formatted(\"posting_date\") }}</div>\n\t\t{%- if doc.due_date %}\n\t\t<div><label>{{ _(doc.meta.get_label(\"due_date\")) }}:</label> {{ doc.get_formatted(\"due_date\") }}</div>\n\t\t{%- endif %}\n\t</div>\n\t<h2>\n\t\t<div>{{ _(doc.select_print_heading) or (_(doc.print_heading) if doc.print_heading != None else _(\"Tax Invoice/Receipt\")) }}</div>\n\t\t<small class=\"sub-heading\">{{ _(doc.sub_heading) if doc.sub_heading != None else _(doc.name) }}</small>\n\t</h2>\n\t<div class=\"heading-clear\"></div>\n</div>\n{% endraw %}\n{%- endset -%}\n{#- Standard layout prints every non-empty child column; keep the item table to the essentials -#}\n{%- set item_columns = [\n\t{\"fieldname\": \"item_code\"},\n\t{\"fieldname\": \"description\"},\n\t{\"fieldname\": \"qty\"},\n\t{\"fieldname\": \"rate\"},\n\t{\"fieldname\": \"amount\"},\n] -%}\n\n{%- macro render_fields(fields, no_of_cols) -%}\n\t{%- for df in fields -%}\n\t\t{%- if df.fieldname not in hidden_fields -%}\n\t\t\t{%- if df.fieldname == \"items\" -%}\n\t\t\t\t{%- set df = df.as_dict() -%}\n\t\t\t\t{%- set ignored = df.update({\"visible_columns\": item_columns}) -%}\n\t\t\t{%- endif -%}\n\t\t\t{{ render_field(df, doc, no_of_cols) }}\n\t\t{%- endif -%}\n\t{%- endfor -%}\n{%- endmacro -%}\n\n{% for page in layout %}\n<div class=\"page-break\">\n\t<div {% if print_settings.repeat_header_footer %} id=\"header-html\" class=\"hidden-pdf\" {% endif %}>\n\t\t{{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings, heading_template) }}\n\t</div>\n\n\t{% if loop.first %}\n\t<div class=\"row section-break\" data-label=\"{{ _(\"Customer\") }}\">\n\t\t<div class=\"col-xs-12 column-break\">\n\t\t\t<h4>{{ _(\"Customer\") }}</h4>\n\t\t\t<style>\n\t\t\t\t.customer-details { width: 100%; }\n\t\t\t\t.customer-details td { padding: 0 !important; border: 0; vertical-align: top; }\n\t\t\t\t.customer-details td.text-muted { width: 40%; padding-right: 1em !important; white-space: nowrap; }\n\t\t\t</style>\n\t\t</div>\n\t\t<div class=\"col-xs-6 column-break\">\n\t\t\t<table class=\"customer-details\">\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr><td class=\"text-muted\">{{ _(doc.meta.get_label(\"customer_name\")) }}</td><td>{{ doc.customer_name or doc.customer }}</td></tr>\n\t\t\t\t\t{% if doc.address_display %}\n\t\t\t\t\t<tr><td class=\"text-muted\">{{ _(doc.meta.get_label(\"address_display\")) }}</td><td>{{ doc.address_display }}</td></tr>\n\t\t\t\t\t{% endif %}\n\t\t\t\t\t{% if doc.tax_id %}\n\t\t\t\t\t<tr><td class=\"text-muted\">{{ _(doc.meta.get_label(\"tax_id\")) }}</td><td>{{ doc.tax_id }}</td></tr>\n\t\t\t\t\t{% endif %}\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t</div>\n\t\t<div class=\"col-xs-6 column-break\">\n\t\t\t{% if doc.contact_person %}\n\t\t\t{#- Sales Invoice carries the contact's mobile and email but not its phone; read that from the Contact. -#}\n\t\t\t{%- set contact_phone = frappe.db.get_value(\"Contact\", doc.contact_person, \"phone\") -%}\n\tLine truncated
"html": "{%- from \"templates/print_formats/standard_macros.html\" import add_header, render_field with context -%}\n{#- ERPNext hides taxes marked \"Is this Tax included in Basic Rate?\" unless Accounts Settings\n enables \"Show Inclusive Tax in Print\"; always show them here so the tax line and\n \"Total (Without Tax)\" appear on invoices with inclusive tax. -#}\n{%- if doc.get(\"taxes\", {\"included_in_print_rate\": 1}) -%}\n\t{%- set ignored = doc.flags.update({\"show_inclusive_tax_in_print\": 1}) -%}\n{%- endif -%}\n{#- App copies of ERPNext's totals includes: \"total\" prints the total before an Additional Discount\n on Net Total with inclusive tax; \"taxes\" prints that discount and Net Total ahead of the charges. -#}\n{%- set ignored = doc.print_templates.update({\"total\": \"default_thai_company/templates/print_formats/includes/total.html\"}) -%}\n{%- if doc.print_templates.get(\"taxes\") -%}\n\t{%- set ignored = doc.print_templates.update({\"taxes\": \"default_thai_company/templates/print_formats/includes/taxes.html\"}) -%}\n{%- endif -%}\n{#- Standard layout prints every non-empty field; drop the ones this invoice does not need.\n posting_date / due_date are printed in the heading, customer fields in the Customer section,\n in_words in the left column of the Totals section. -#}\n{%- set hidden_fields = [\n\t\"total_qty\", \"update_billed_amount_in_delivery_note\", \"amount_eligible_for_commission\", \"company_tax_id\",\n\t\"disable_rounded_total\",\n\t\"posting_date\", \"due_date\",\n\t\"customer_name\", \"address_display\", \"contact_display\", \"contact_mobile\", \"contact_email\", \"tax_id\",\n\t\"in_words\",\n] -%}\n{#- rounded_total keeps a value even when rounding is disabled, so the standard layout would print it. -#}\n{%- if doc.is_rounded_total_disabled() -%}{%- set ignored = hidden_fields.append(\"rounded_total\") -%}{%- endif -%}\n{#- add_header renders this string via frappe.render_template with {\"doc\": doc}, so it is kept\n unrendered with {% raw %}. Same markup as the stock heading plus a right-aligned date block. -#}\n{%- set heading_template -%}\n{% raw %}\n<div class=\"print-heading\">\n\t<style>\n\t\t.print-heading .heading-dates { float: right; text-align: right; margin-top: 4px; white-space: nowrap; }\n\t\t.print-heading .heading-dates label { display: inline; font-weight: 700; margin: 0 4px 0 0; }\n\t\t.print-heading .heading-clear { clear: both; }\n\t</style>\n\t<div class=\"heading-dates\">\n\t\t<div><label>{{ _(doc.meta.get_label(\"posting_date\")) }}:</label> {{ doc.get_formatted(\"posting_date\") }}</div>\n\t\t{%- if doc.due_date %}\n\t\t<div><label>{{ _(doc.meta.get_label(\"due_date\")) }}:</label> {{ doc.get_formatted(\"due_date\") }}</div>\n\t\t{%- endif %}\n\t</div>\n\t<h2>\n\t\t<div>{{ _(doc.select_print_heading) or (_(doc.print_heading) if doc.print_heading != None else _(\"Tax Invoice/Receipt\")) }}</div>\n\t\t<small class=\"sub-heading\">{{ _(doc.sub_heading) if doc.sub_heading != None else _(doc.name) }}</small>\n\t</h2>\n\t<div class=\"heading-clear\"></div>\n</div>\n{% endraw %}\n{%- endset -%}\n{#- Standard layout prints every non-empty child column; keep the item table to the essentials -#}\n{%- set item_columns = [\n\t{\"fieldname\": \"item_code\"},\n\t{\"fieldname\": \"description\"},\n\t{\"fieldname\": \"qty\"},\n\t{\"fieldname\": \"rate\"},\n\t{\"fieldname\": \"amount\"},\n] -%}\n\n{%- macro render_fields(fields, no_of_cols) -%}\n\t{%- for df in fields -%}\n\t\t{%- if df.fieldname not in hidden_fields -%}\n\t\t\t{%- if df.fieldname == \"items\" -%}\n\t\t\t\t{%- set df = df.as_dict() -%}\n\t\t\t\t{%- set ignored = df.update({\"visible_columns\": item_columns}) -%}\n\t\t\t{%- endif -%}\n\t\t\t{{ render_field(df, doc, no_of_cols) }}\n\t\t{%- endif -%}\n\t{%- endfor -%}\n{%- endmacro -%}\n\n{% for page in layout %}\n<div class=\"page-break\">\n\t<div {% if print_settings.repeat_header_footer %} id=\"header-html\" class=\"hidden-pdf\" {% endif %}>\n\t\t{{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings, heading_template) }}\n\t</div>\n\n\t{% if loop.first %}\n\t<div class=\"row section-break\" data-label=\"{{ _(\"Customer\") }}\">\n\t\t<div class=\"col-xs-12 column-break\">\n\t\t\t<h4>{{ _(\"Customer\") }}</h4>\n\t\t\t<style>\n\t\t\t\t.customer-details { width: 100%; }\n\t\t\t\t.customer-details td { padding: 0 !important; border: 0; vertical-align: top; }\n\t\t\t\t.customer-details td.text-muted { width: 40%; padding-right: 1em !important; white-space: nowrap; }\n\t\t\t</style>\n\t\t</div>\n\t\t<div class=\"col-xs-6 column-break\">\n\t\t\t<table class=\"customer-details\">\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr><td class=\"text-muted\">{{ _(doc.meta.get_label(\"customer_name\")) }}</td><td>{{ doc.customer_name or doc.customer }}</td></tr>\n\t\t\t\t\t{% if doc.address_display %}\n\t\t\t\t\t<tr><td class=\"text-muted\">{{ _(doc.meta.get_label(\"address_display\")) }}</td><td>{{ doc.address_display }}</Line truncated
"line_breaks": 0,
"margin_bottom": 15.0,
"margin_left": 15.0,
@@ -0,0 +1,31 @@
{#- ERPNext's templates/print_formats/includes/taxes.html, but a discount on Net Total is
followed by the Net Total line so the print reads Total, discount, Net Total, charges.
A discount on Grand Total stays after the charges, as upstream. -#}
{%- macro amount_row(label, value) -%}
<div class="row">
<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
<label>{{ label }}</label>
</div>
<div class="col-xs-7 text-right">
{{ value }}
</div>
</div>
{%- endmacro -%}
<div class="row">
<div class="col-xs-6"></div>
<div class="col-xs-6">
{%- if doc.discount_amount and doc.apply_discount_on == "Net Total" -%}
{{ amount_row(_(doc.meta.get_label("discount_amount")), "- " ~ doc.get_formatted("discount_amount", doc)) }}
{{ amount_row(_(doc.meta.get_label("net_total")), doc.get_formatted("net_total", doc)) }}
{%- endif -%}
{%- for charge in data -%}
{%- if (charge.tax_amount or print_settings.print_taxes_with_zero_amount) and (not charge.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) -%}
{{ amount_row(charge.get_formatted("description"), charge.get_formatted("tax_amount", doc)) }}
{%- endif -%}
{%- endfor -%}
{%- if doc.discount_amount and doc.apply_discount_on == "Grand Total" -%}
{{ amount_row(_(doc.meta.get_label("discount_amount")), "- " ~ doc.get_formatted("discount_amount", doc)) }}
{%- endif -%}
</div>
</div>
@@ -0,0 +1,20 @@
{#- ERPNext's templates/print_formats/includes/total.html, except that with inclusive tax the
"Total (Without Tax)" line is the total before an Additional Discount on Net Total:
net_total already has that discount taken off, so the print would show the same figure
before and after the discount line. -#}
<div class="row {% if df.bold %}important{% endif %} data-field">
{% if doc.flags.show_inclusive_tax_in_print %}
{%- set before_discount = doc.net_total + (doc.discount_amount if doc.apply_discount_on == "Net Total" else 0) -%}
<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
<label>{{ _("Total (Without Tax)") }}</label></div>
<div class="col-xs-7 text-right value">
{{ frappe.format_value(before_discount, {"fieldtype": "Currency", "options": "currency"}, doc) }}
</div>
{% else %}
<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
<label>{{ _(df.label) }}</label></div>
<div class="col-xs-7 text-right value">
{{ doc.get_formatted("total", doc) }}
</div>
{% endif %}
</div>