From e85238383f714e0e5a75341b51768fbfce110258 Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Tue, 9 Sep 2025 12:55:55 +0530 Subject: [PATCH 01/45] feat: default print format for sales invoice --- .../sales_invoice_print_format/__init__.py | 0 .../sales_invoice_print_format.html | 148 ++++++++++++++++++ .../sales_invoice_print_format.json | 32 ++++ 3 files changed, 180 insertions(+) create mode 100644 erpnext/accounts/print_format/sales_invoice_print_format/__init__.py create mode 100644 erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html create mode 100644 erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.json diff --git a/erpnext/accounts/print_format/sales_invoice_print_format/__init__.py b/erpnext/accounts/print_format/sales_invoice_print_format/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html b/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html new file mode 100644 index 00000000000..c5800c0645f --- /dev/null +++ b/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html @@ -0,0 +1,148 @@ +{%- macro add_header(page_num, max_pages, doc, letter_head, no_letterhead, footer, print_settings=None, +print_heading_template=None) -%} {% if letter_head and not no_letterhead %} +
{{ letter_head }}
+{% endif %} {% if print_heading_template %} {{ frappe.render_template(print_heading_template, {"doc":doc}) }} +{% else %} {% endif %} {%- if doc.meta.is_submittable and doc.docstatus==2-%} +
+

{{ _("CANCELLED") }}

+
+{%- endif -%} {%- endmacro -%} {% for page in layout %} +
+
+ {{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings) }} +
+ + + + + + + + + + + + {% set address = (doc.address_display) %} {% if address.rstrip().endswith("
") %} {% set + address = address[:-5] %} {% endif %} {% set company_address_display = + (doc.company_address_display) %} {% if company_address_display.rstrip().endswith("
") %} {% + set company_address_display = company_address_display[:-5] %} {% endif %} + + + +
+ {{ _("Customer Name") }}: {{doc.customer_name }} + + {{ _("Payment Due Date") }}: {{ + frappe.utils.format_date(doc.due_date) }} +
{{ _("Invoice Number") }}: {{ doc.name }} + {{ _("Invoice Date") }}: {{ + frappe.utils.format_date(doc.posting_date) }} +
{{ _("Bill From") }}:
{{ address }}
{{ _("Bill To") }}:
{{ company_address_display }}
+ + + + + + + + + + + + + + + + + + + + + {% for item in doc.items %} + + + + + + + + {% endfor %} + +
{{ _("No") }}{{ _("Item") }}{{ _("Quantity") }}{{ _("Rate") }}{{ _("Amount") }}
{{ loop.index }}{{ item.item_name }}{{ item.get_formatted("qty", 0) }} {{ item.uom }}{{ item.get_formatted("net_rate", doc) }}{{ item.get_formatted("net_amount", doc) }}
+ + +
+
+
+

{{ _("Total in words") }}

+
{{ doc.in_words }}
+
+
+
+ + + + + + + + + + {% set tax_rate = doc.taxes | selectattr("tax_amount") | sum(attribute="rate") %} {% if + tax_rate > 0 %} + + + + + {% endif %} + + + + +
{{ _("Sub Total:") }}{{ doc.get_formatted("total", doc) }}
+ {{ _("Discount") }} ({{ doc.additional_discount_percentage }}%): + {{ doc.get_formatted("discount_amount", doc) }}
{{ _("Tax") }} ({{ tax_rate }}%):{{ doc.get_formatted("total_taxes_and_charges", doc) }}
{{ _("Grand Total:") }}{{ doc.get_formatted("grand_total", doc) }}
+
+
+ + + {% if doc.taxes_and_charges %} +
{{ _("Tax Breakup") }}
+
+ + + + + + {% for row in doc.taxes %} + + {% endfor %} + + + + {% for item in doc.items %} + + + + {% for row in doc.taxes %} {% set tax_amount = item.base_net_amount * (row.rate / 100) %} + + {% endfor %} + + {% endfor %} + +
{{ _("HSN/SAC") }}{{ _("Taxable Amount") }}{{ row.description }}
{{ item.gst_hsn_code }}{{ item.get_formatted("base_net_amount", doc) }} + ({{ (row.rate) }}%) {{ frappe.format_value(tax_amount, {"fieldtype": "Currency"}, doc) + }} +
+
+ {% endif %} + + + {% if doc.terms %} +
+
{{ _("Terms and Conditions") }}
+ {{ doc.terms}} +
+ {% endif %} +
+{% endfor %} diff --git a/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.json b/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.json new file mode 100644 index 00000000000..34198f03e9c --- /dev/null +++ b/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.json @@ -0,0 +1,32 @@ +{ + "absolute_value": 0, + "align_labels_right": 0, + "creation": "2025-08-28 04:03:36.284420", + "custom_format": 0, + "default_print_language": "en", + "disabled": 0, + "doc_type": "Sales Invoice", + "docstatus": 0, + "doctype": "Print Format", + "font_size": 14, + "idx": 0, + "line_breaks": 0, + "margin_bottom": 15.0, + "margin_left": 15.0, + "margin_right": 15.0, + "margin_top": 15.0, + "modified": "2025-09-01 17:47:14.710435", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Sales Invoice Print Format", + "owner": "Administrator", + "page_number": "Hide", + "pdf_generator": "wkhtmltopdf", + "print_format_builder": 0, + "print_format_builder_beta": 0, + "print_format_for": "DocType", + "print_format_type": "Jinja", + "raw_printing": 0, + "show_section_headings": 0, + "standard": "Yes" +} From af974fbccdf3ce8e473e59cbed924ada5e72107a Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Tue, 9 Sep 2025 12:56:51 +0530 Subject: [PATCH 02/45] feat: add css --- .../sales_invoice_print_format.html | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html b/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html index c5800c0645f..c9fbea3698b 100644 --- a/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html +++ b/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html @@ -12,6 +12,147 @@ print_heading_template=None) -%} {% if letter_head and not no_letterhead %} {{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings) }} + +
From 156dda8157dabf4b68dedd1fa29f0576863fd345 Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Tue, 9 Sep 2025 13:25:14 +0530 Subject: [PATCH 03/45] style: change padding --- .../sales_invoice_print_format/sales_invoice_print_format.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html b/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html index c9fbea3698b..65bfd93c2be 100644 --- a/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html +++ b/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html @@ -16,7 +16,7 @@ print_heading_template=None) -%} {% if letter_head and not no_letterhead %} .invoice-wrapper { font-family: "Inter", sans-serif; color: var(--black-overlay-700); - padding: 24px; + padding: 12px; } table.info-table, From 7386270fce5cb93e096c0a25ddac378c9c56236d Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Tue, 9 Sep 2025 14:45:37 +0530 Subject: [PATCH 04/45] feat: add letterhead fixture --- erpnext/fixtures/letter_head.json | 48 +++++++++++++++++++++++++++++++ erpnext/hooks.py | 2 ++ 2 files changed, 50 insertions(+) create mode 100644 erpnext/fixtures/letter_head.json diff --git a/erpnext/fixtures/letter_head.json b/erpnext/fixtures/letter_head.json new file mode 100644 index 00000000000..4b9e7d9cc46 --- /dev/null +++ b/erpnext/fixtures/letter_head.json @@ -0,0 +1,48 @@ +[ + { + "align": "Left", + "content": "\n\n
\n
\n
\n {% if frappe.db.get_value(\"Company\", doc.company, \"logo_for_printing\") %}\n \n {% endif %}\n
\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n {% set pan = frappe.db.get_value(\"Company\", doc.company, \"pan\") %}\n\n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n {% if pan %}\n
\n
{{ _(\"PAN:\") }}
\n
{{ pan }}

\n
\n {% endif %}\n
\n
\n", + "disabled": 0, + "docstatus": 0, + "doctype": "Letter Head", + "footer": null, + "footer_align": "Left", + "footer_image": null, + "footer_image_height": 0.0, + "footer_image_width": 0.0, + "footer_script": null, + "footer_source": "HTML", + "header_script": null, + "image": null, + "image_height": 0.0, + "image_width": 0.0, + "is_default": 0, + "letter_head_name": "Sales Invoice Letter Head", + "modified": "2025-09-09 14:31:07.209406", + "name": "Sales Invoice Letter Head", + "source": "HTML" + }, + { + "align": "Left", + "content": "\n\n
\n
\n
\n {% if frappe.db.get_value(\"Company\", doc.company, \"logo_for_printing\") %}\n \n {% endif %}\n
\n
\n
\n {{ _(\"Sales Invoice\") }}\n
\n
\n {{ doc.name }}\n
\n
\n
\n
\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n {% set pan = frappe.db.get_value(\"Company\", doc.company, \"pan\") %}\n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n {% if pan %}\n
\n
{{ _(\"PAN:\") }}
\n
{{ pan }}

\n
\n {% endif %}\n
\n
\n
\n", + "disabled": 0, + "docstatus": 0, + "doctype": "Letter Head", + "footer": null, + "footer_align": "Left", + "footer_image": null, + "footer_image_height": 0.0, + "footer_image_width": 0.0, + "footer_script": null, + "footer_source": "HTML", + "header_script": null, + "image": null, + "image_height": 0.0, + "image_width": 0.0, + "is_default": 1, + "letter_head_name": "Print Format Letter Head", + "modified": "2025-09-09 14:31:07.204974", + "name": "Print Format Letter Head", + "source": "HTML" + } +] \ No newline at end of file diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 22bff524dea..540fd6c36c4 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -600,6 +600,8 @@ user_privacy_documents = [ }, ] +fixtures = ["Letter Head"] + # ERPNext doctypes for Global Search global_search_doctypes = { "Default": [ From 1adbf90d8c51c44035b48d23f55ab8109eb43deb Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Tue, 9 Sep 2025 18:58:45 +0530 Subject: [PATCH 05/45] fix: css changes in letterhead --- .../sales_invoice_print_format.html | 4 ++-- erpnext/fixtures/letter_head.json | 8 ++++---- erpnext/hooks.py | 8 +++++++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html b/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html index 65bfd93c2be..6a9b5f24564 100644 --- a/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html +++ b/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html @@ -148,12 +148,12 @@ print_heading_template=None) -%} {% if letter_head and not no_letterhead %} font-style: normal; font-weight: 420; line-height: 21px; - padding: 12px; + padding: 5px; letter-spacing: 0.14px; } - +
- {% set address = (doc.address_display) %} {% if address.rstrip().endswith("
") %} {% set + {% set address = (doc.address_display) %} {% if address and address.rstrip().endswith("
") %} {% set address = address[:-5] %} {% endif %} {% set company_address_display = - (doc.company_address_display) %} {% if company_address_display.rstrip().endswith("
") %} {% + (doc.company_address_display) %} {% if company_address_display and company_address_display.rstrip().endswith("
") %} {% set company_address_display = company_address_display[:-5] %} {% endif %} From c78079628462ab9520e9e631c7e6ec1b9e653589 Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Mon, 15 Sep 2025 16:27:12 +0530 Subject: [PATCH 09/45] fix: remove border if company logo not available --- erpnext/fixtures/letter_head.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/erpnext/fixtures/letter_head.json b/erpnext/fixtures/letter_head.json index 36314aa4317..1b0eb0962c8 100644 --- a/erpnext/fixtures/letter_head.json +++ b/erpnext/fixtures/letter_head.json @@ -1,7 +1,7 @@ [ { "align": "Left", - "content": "\n\n
\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n \n {% endif %}\n
\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n \n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n
\n
\n
{{ _(\"Invoice:\") }}
\n
{{ doc.name }}

\n
\n
\n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n
\n
\n", + "content": "\n\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n
\n \n
\n {% endif %}\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n \n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n
\n
\n
{{ _(\"Invoice:\") }}
\n
{{ doc.name }}

\n
\n
\n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n
\n
\n", "disabled": 0, "docstatus": 0, "doctype": "Letter Head", @@ -16,15 +16,15 @@ "image": null, "image_height": 0.0, "image_width": 0.0, - "is_default": 1, + "is_default": 0, "letter_head_name": "Sales Invoice Letter Head", - "modified": "2025-09-10 14:21:04.051369", + "modified": "2025-09-15 16:23:58.583661", "name": "Sales Invoice Letter Head", "source": "HTML" }, { "align": "Left", - "content": "\n\n
\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n \n {% endif %}\n
\n
\n
\n {{ _(\"Sales Invoice\") }}\n
\n
\n {{ doc.name }}\n
\n
\n
\n
\n
\n
{{ doc.company }}
\n \n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n \n
\n
\n
\n", + "content": "\n\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n
\n \n
\n {% endif %}\n
\n
{{ doc.company }}
\n \n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n
\n
\n \n
\n
\n {{ _(\"Sales Invoice\") }}\n
\n
\n {{ doc.name }}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n \n
\n
\n
\n", "disabled": 0, "docstatus": 0, "doctype": "Letter Head", @@ -41,7 +41,7 @@ "image_width": 0.0, "is_default": 0, "letter_head_name": "Print Format Letter Head", - "modified": "2025-09-10 14:21:04.063016", + "modified": "2025-09-15 16:14:24.080812", "name": "Print Format Letter Head", "source": "HTML" } From 4cc2afbd832aab3dfc3ac5dc668934411d79daad Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Mon, 15 Sep 2025 16:34:14 +0530 Subject: [PATCH 10/45] feat: print format design two --- .../print_format_sales_invoice/__init__.py | 0 .../print_format_sales_invoice.html | 310 ++++++++++++++++++ .../print_format_sales_invoice.json | 32 ++ 3 files changed, 342 insertions(+) create mode 100644 erpnext/accounts/print_format/print_format_sales_invoice/__init__.py create mode 100644 erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.html create mode 100644 erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.json diff --git a/erpnext/accounts/print_format/print_format_sales_invoice/__init__.py b/erpnext/accounts/print_format/print_format_sales_invoice/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.html b/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.html new file mode 100644 index 00000000000..aa1f9923326 --- /dev/null +++ b/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.html @@ -0,0 +1,310 @@ +{%- macro add_header(page_num, max_pages, doc, letter_head, no_letterhead, footer, print_settings=None, +print_heading_template=None) -%} {% if letter_head and not no_letterhead %} +
{{ letter_head }}
+{% endif %} {% if print_heading_template %} {{ frappe.render_template(print_heading_template, {"doc":doc}) }} +{% endif %} {%- if doc.meta.is_submittable and doc.docstatus==2 -%} +
+

{{ _("CANCELLED") }}

+
+{%- endif -%} {%- endmacro -%} {% for page in layout %} +
+
+ {{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings) }} +
+ + + +
{{ _("Customer Name") }}: {{doc.customer_name }} diff --git a/erpnext/fixtures/letter_head.json b/erpnext/fixtures/letter_head.json index 4b9e7d9cc46..b956a8c64e3 100644 --- a/erpnext/fixtures/letter_head.json +++ b/erpnext/fixtures/letter_head.json @@ -1,7 +1,7 @@ [ { "align": "Left", - "content": "\n\n
\n
\n
\n {% if frappe.db.get_value(\"Company\", doc.company, \"logo_for_printing\") %}\n \n {% endif %}\n
\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n {% set pan = frappe.db.get_value(\"Company\", doc.company, \"pan\") %}\n\n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n {% if pan %}\n
\n
{{ _(\"PAN:\") }}
\n
{{ pan }}

\n
\n {% endif %}\n
\n
\n", + "content": "\n\n
\n
\n
\n {% if frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n \n {% endif %}\n
\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n {% set pan = frappe.db.get_value(\"Company\", doc.company, \"pan\") %}\n\n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n {% if pan %}\n
\n
{{ _(\"PAN:\") }}
\n
{{ pan }}

\n
\n {% endif %}\n
\n
\n", "disabled": 0, "docstatus": 0, "doctype": "Letter Head", @@ -18,13 +18,13 @@ "image_width": 0.0, "is_default": 0, "letter_head_name": "Sales Invoice Letter Head", - "modified": "2025-09-09 14:31:07.209406", + "modified": "2025-09-09 18:25:09.704061", "name": "Sales Invoice Letter Head", "source": "HTML" }, { "align": "Left", - "content": "\n\n
\n
\n
\n {% if frappe.db.get_value(\"Company\", doc.company, \"logo_for_printing\") %}\n \n {% endif %}\n
\n
\n
\n {{ _(\"Sales Invoice\") }}\n
\n
\n {{ doc.name }}\n
\n
\n
\n
\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n {% set pan = frappe.db.get_value(\"Company\", doc.company, \"pan\") %}\n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n {% if pan %}\n
\n
{{ _(\"PAN:\") }}
\n
{{ pan }}

\n
\n {% endif %}\n
\n
\n
\n", + "content": "\n\n
\n
\n
\n {% if frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n \n {% endif %}\n
\n
\n
\n {{ _(\"Sales Invoice\") }}\n
\n
\n {{ doc.name }}\n
\n
\n
\n
\n
\n
{{ doc.company }}
\n \n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n {% set pan = frappe.db.get_value(\"Company\", doc.company, \"pan\") %}\n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n {% if pan %}\n
\n
{{ _(\"PAN:\") }}
\n
{{ pan }}

\n
\n {% endif %}\n
\n
\n
\n", "disabled": 0, "docstatus": 0, "doctype": "Letter Head", @@ -41,7 +41,7 @@ "image_width": 0.0, "is_default": 1, "letter_head_name": "Print Format Letter Head", - "modified": "2025-09-09 14:31:07.204974", + "modified": "2025-09-09 18:11:28.309162", "name": "Print Format Letter Head", "source": "HTML" } diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 540fd6c36c4..213efd9a0f6 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -600,7 +600,13 @@ user_privacy_documents = [ }, ] -fixtures = ["Letter Head"] +fixtures = [ + { + "dt": "Letter Head", + "filters": [["name", "in", ["Sales Invoice Letter Head", "Print Format Letter Head"]]], + } +] + # ERPNext doctypes for Global Search global_search_doctypes = { From 2bc19783cb61abb2e56c9ad134667b5d77fe36e2 Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Wed, 10 Sep 2025 13:24:30 +0530 Subject: [PATCH 06/45] fix: letterhead styling --- erpnext/fixtures/letter_head.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/fixtures/letter_head.json b/erpnext/fixtures/letter_head.json index b956a8c64e3..32d56e77475 100644 --- a/erpnext/fixtures/letter_head.json +++ b/erpnext/fixtures/letter_head.json @@ -1,7 +1,7 @@ [ { "align": "Left", - "content": "\n\n
\n
\n
\n {% if frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n \n {% endif %}\n
\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n {% set pan = frappe.db.get_value(\"Company\", doc.company, \"pan\") %}\n\n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n {% if pan %}\n
\n
{{ _(\"PAN:\") }}
\n
{{ pan }}

\n
\n {% endif %}\n
\n
\n", + "content": "\n\n
\n
\n
\n {% if frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n \n {% endif %}\n
\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n \n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n
\n
\n
{{ _(\"Invoice:\") }}
\n
{{ doc.name }}

\n
\n
\n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n
\n
\n", "disabled": 0, "docstatus": 0, "doctype": "Letter Head", @@ -18,13 +18,13 @@ "image_width": 0.0, "is_default": 0, "letter_head_name": "Sales Invoice Letter Head", - "modified": "2025-09-09 18:25:09.704061", + "modified": "2025-09-10 00:56:32.108422", "name": "Sales Invoice Letter Head", "source": "HTML" }, { "align": "Left", - "content": "\n\n
\n
\n
\n {% if frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n \n {% endif %}\n
\n
\n
\n {{ _(\"Sales Invoice\") }}\n
\n
\n {{ doc.name }}\n
\n
\n
\n
\n
\n
{{ doc.company }}
\n \n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n {% set pan = frappe.db.get_value(\"Company\", doc.company, \"pan\") %}\n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n {% if pan %}\n
\n
{{ _(\"PAN:\") }}
\n
{{ pan }}

\n
\n {% endif %}\n
\n
\n
\n", + "content": "\n\n
\n
\n
\n {% if frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n \n {% endif %}\n
\n
\n
\n {{ _(\"Sales Invoice\") }}\n
\n
\n {{ doc.name }}\n
\n
\n
\n
\n
\n
{{ doc.company }}
\n \n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n \n
\n
\n
\n", "disabled": 0, "docstatus": 0, "doctype": "Letter Head", @@ -41,7 +41,7 @@ "image_width": 0.0, "is_default": 1, "letter_head_name": "Print Format Letter Head", - "modified": "2025-09-09 18:11:28.309162", + "modified": "2025-09-10 00:56:32.101771", "name": "Print Format Letter Head", "source": "HTML" } From b5c739d1cc0d58fa654df19dede4fe7d3b18fc89 Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Wed, 10 Sep 2025 14:21:50 +0530 Subject: [PATCH 07/45] fix: broken img tag in letterhead --- erpnext/fixtures/letter_head.json | 50 +++++++++++++++---------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/erpnext/fixtures/letter_head.json b/erpnext/fixtures/letter_head.json index 32d56e77475..36314aa4317 100644 --- a/erpnext/fixtures/letter_head.json +++ b/erpnext/fixtures/letter_head.json @@ -1,30 +1,7 @@ [ { "align": "Left", - "content": "\n\n
\n
\n
\n {% if frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n \n {% endif %}\n
\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n \n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n
\n
\n
{{ _(\"Invoice:\") }}
\n
{{ doc.name }}

\n
\n
\n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n
\n
\n", - "disabled": 0, - "docstatus": 0, - "doctype": "Letter Head", - "footer": null, - "footer_align": "Left", - "footer_image": null, - "footer_image_height": 0.0, - "footer_image_width": 0.0, - "footer_script": null, - "footer_source": "HTML", - "header_script": null, - "image": null, - "image_height": 0.0, - "image_width": 0.0, - "is_default": 0, - "letter_head_name": "Sales Invoice Letter Head", - "modified": "2025-09-10 00:56:32.108422", - "name": "Sales Invoice Letter Head", - "source": "HTML" - }, - { - "align": "Left", - "content": "\n\n
\n
\n
\n {% if frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n \n {% endif %}\n
\n
\n
\n {{ _(\"Sales Invoice\") }}\n
\n
\n {{ doc.name }}\n
\n
\n
\n
\n
\n
{{ doc.company }}
\n \n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n \n
\n
\n
\n", + "content": "\n\n
\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n \n {% endif %}\n
\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n \n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n
\n
\n
{{ _(\"Invoice:\") }}
\n
{{ doc.name }}

\n
\n
\n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n
\n
\n", "disabled": 0, "docstatus": 0, "doctype": "Letter Head", @@ -40,8 +17,31 @@ "image_height": 0.0, "image_width": 0.0, "is_default": 1, + "letter_head_name": "Sales Invoice Letter Head", + "modified": "2025-09-10 14:21:04.051369", + "name": "Sales Invoice Letter Head", + "source": "HTML" + }, + { + "align": "Left", + "content": "\n\n
\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n \n {% endif %}\n
\n
\n
\n {{ _(\"Sales Invoice\") }}\n
\n
\n {{ doc.name }}\n
\n
\n
\n
\n
\n
{{ doc.company }}
\n \n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n \n
\n
\n
\n", + "disabled": 0, + "docstatus": 0, + "doctype": "Letter Head", + "footer": null, + "footer_align": "Left", + "footer_image": null, + "footer_image_height": 0.0, + "footer_image_width": 0.0, + "footer_script": null, + "footer_source": "HTML", + "header_script": null, + "image": null, + "image_height": 0.0, + "image_width": 0.0, + "is_default": 0, "letter_head_name": "Print Format Letter Head", - "modified": "2025-09-10 00:56:32.101771", + "modified": "2025-09-10 14:21:04.063016", "name": "Print Format Letter Head", "source": "HTML" } From ddf4a83cf86edc74f167fe24b463e54237b75ba7 Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Mon, 15 Sep 2025 16:22:39 +0530 Subject: [PATCH 08/45] fix: condition based address display --- .../sales_invoice_print_format.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html b/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html index 6a9b5f24564..a97d5f67790 100644 --- a/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html +++ b/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html @@ -171,9 +171,9 @@ print_heading_template=None) -%} {% if letter_head and not no_letterhead %}
{{ _("Bill From") }}:
{{ address }}
{{ _("Bill To") }}:
{{ company_address_display }}
+ + + + + +
+
+
Customer Name:
+
Bill to:
+
+
+
{{ doc.customer_name }}
+
{{ doc.address_display or "" }}
+
+
+
+
Invoice Number:
+
Invoice Date:
+
Payment Due Date:
+
+
+
{{ doc.name }}
+
{{ frappe.utils.format_date(doc.posting_date) }}
+
{{ frappe.utils.format_date(doc.due_date) }}
+
+
+ + + + + + + + + + + + + + + + + + + + + + + {% for item in doc.items %} + + + + + + + + + + {% endfor %} + +
{{ _("No") }}{{ _("Item") }}{{ _("HSN/SAC") }}{{ _("Quantity") }}{{ _("Rate") }}{{ _("Amount") }}
{{ loop.index }} +
+
+ {% if item.image %} +
+ {{ item.item_name }} +
+ {% endif %} +
+
{{ item.item_name }}
+
+
{{ item.gst_hsn_code }}{{ item.get_formatted("qty", 0) }} {{ item.uom }}{{ item.get_formatted("net_rate", doc) }}{{ item.get_formatted("net_amount", doc) }}
+ + + + + + + + + + + +
  + + + + + + + + + + {% set tax_rate = doc.taxes | selectattr("tax_amount") | sum(attribute="rate") %} {% if + tax_rate > 0 %} + + + + + {% endif %} +
{{ _("Sub Total:") }}{{ doc.get_formatted("total", doc) }}
+ {{ _("Discount") }} ({{ doc.additional_discount_percentage or 0 }}%): + {{ doc.get_formatted("discount_amount", doc) }}
{{ _("Tax") }} ({{ tax_rate }}%):{{ doc.get_formatted("total_taxes_and_charges", doc) }}
+
+
+ + + + + + +
+
{{ _("In Words: ") }}{{ doc.in_words }}
+
{{ _("Grand Total:") }} + + {{ doc.get_formatted("grand_total", doc) }} + +
+
+
+ + {% if doc.taxes_and_charges %} + +
{{ _("Tax Breakup") }}
+ + + + + {% for row in doc.taxes %} + + {% endfor %} + + + + {% for item in doc.items %} + + + + {% for row in doc.taxes %} {% set tax_amount = item.base_net_amount * (row.rate / 100) %} + + {% endfor %} + + {% endfor %} + +
{{ _("HSN/SAC") }}{{ _("Taxable Amount") }}{{ row.description }} ({{ row.rate }}%)
{{ item.gst_hsn_code }}{{ item.get_formatted("base_net_amount", doc) }} + {{ frappe.format_value(tax_amount, {"fieldtype": "Currency"}, doc) }} +
+ {% endif %} + + + {% if doc.terms %} +
+
{{ _("Terms and Conditions") }}
+ {{ doc.terms}} +
+ {% endif %} + +{% endfor %} diff --git a/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.json b/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.json new file mode 100644 index 00000000000..9952485cc28 --- /dev/null +++ b/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.json @@ -0,0 +1,32 @@ +{ + "absolute_value": 0, + "align_labels_right": 0, + "creation": "2025-09-15 16:31:00.732539", + "custom_format": 0, + "default_print_language": "en", + "disabled": 0, + "doc_type": "Sales Invoice", + "docstatus": 0, + "doctype": "Print Format", + "font_size": 14, + "idx": 0, + "line_breaks": 0, + "margin_bottom": 15.0, + "margin_left": 15.0, + "margin_right": 15.0, + "margin_top": 15.0, + "modified": "2025-09-15 16:31:00.732539", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Print Format Sales Invoice", + "owner": "Administrator", + "page_number": "Hide", + "pdf_generator": "wkhtmltopdf", + "print_format_builder": 0, + "print_format_builder_beta": 0, + "print_format_for": "DocType", + "print_format_type": "Jinja", + "raw_printing": 0, + "show_section_headings": 0, + "standard": "Yes" +} From e08f82909c371d6a50e18c73218525a010000a0a Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Mon, 15 Sep 2025 16:39:33 +0530 Subject: [PATCH 11/45] fix: radius of the items/tax table thead --- .../print_format_sales_invoice/print_format_sales_invoice.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.html b/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.html index aa1f9923326..233083b1f34 100644 --- a/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.html +++ b/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.html @@ -86,10 +86,12 @@ print_heading_template=None) -%} {% if letter_head and not no_letterhead %} .items-table tr:first-child td:first-child, .tax-table tr:first-child td:first-child { border-top-left-radius: 10px; + border-bottom-left-radius: 10px; } .items-table tr:first-child td:last-child, .tax-table tr:first-child td:last-child { border-top-right-radius: 10px; + border-bottom-right-radius: 10px; } .in-words { From 6b83309750eec9d51a506a4ebb9094ef08b7aba8 Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Tue, 16 Sep 2025 22:45:05 +0530 Subject: [PATCH 12/45] test: just debugging --- .../test_process_statement_of_accounts.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py b/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py index 4f9dd9a590d..5bf0c0b4464 100644 --- a/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py +++ b/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py @@ -81,7 +81,8 @@ class TestProcessStatementOfAccounts(AccountsTestMixin, IntegrationTestCase): process_soa = create_process_soa( name="_Test Process SOA", enable_auto_email=1, report="Accounts Receivable" ) - send_emails(process_soa.name, from_scheduler=True) + if not frappe.flags.in_migrate: + send_emails(process_soa.name, from_scheduler=True) process_soa.load_from_db() self.assertEqual(process_soa.posting_date, getdate(add_days(today(), 7))) From 17397ae652c6a47f5f8ba489f55b257e001f95bc Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Tue, 16 Sep 2025 23:09:42 +0530 Subject: [PATCH 13/45] test: add in_install condition for debugging --- .../test_process_statement_of_accounts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py b/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py index 5bf0c0b4464..acea3614c5e 100644 --- a/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py +++ b/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py @@ -81,7 +81,7 @@ class TestProcessStatementOfAccounts(AccountsTestMixin, IntegrationTestCase): process_soa = create_process_soa( name="_Test Process SOA", enable_auto_email=1, report="Accounts Receivable" ) - if not frappe.flags.in_migrate: + if not frappe.flags.in_migrate and not frappe.flags.in_install: send_emails(process_soa.name, from_scheduler=True) process_soa.load_from_db() self.assertEqual(process_soa.posting_date, getdate(add_days(today(), 7))) From f1a2e1b7258c161b20f56a3e00f7b388c6d473fb Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Tue, 16 Sep 2025 23:45:41 +0530 Subject: [PATCH 14/45] refactor: remove img tag for testing --- erpnext/fixtures/letter_head.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/fixtures/letter_head.json b/erpnext/fixtures/letter_head.json index 1b0eb0962c8..7c77cb5d9fe 100644 --- a/erpnext/fixtures/letter_head.json +++ b/erpnext/fixtures/letter_head.json @@ -1,7 +1,7 @@ [ { "align": "Left", - "content": "\n\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n
\n \n
\n {% endif %}\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n \n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n
\n
\n
{{ _(\"Invoice:\") }}
\n
{{ doc.name }}

\n
\n
\n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n
\n
\n", + "content": "\n\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n
\n
\n {% endif %}\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n \n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n
\n
\n
{{ _(\"Invoice:\") }}
\n
{{ doc.name }}

\n
\n
\n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n
\n
\n", "disabled": 0, "docstatus": 0, "doctype": "Letter Head", @@ -24,7 +24,7 @@ }, { "align": "Left", - "content": "\n\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n
\n \n
\n {% endif %}\n
\n
{{ doc.company }}
\n \n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n
\n
\n \n
\n
\n {{ _(\"Sales Invoice\") }}\n
\n
\n {{ doc.name }}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n \n
\n
\n
\n", + "content": "\n\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n
\n
\n {% endif %}\n
\n
{{ doc.company }}
\n \n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n
\n
\n \n
\n
\n {{ _(\"Sales Invoice\") }}\n
\n
\n {{ doc.name }}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n \n
\n
\n
\n", "disabled": 0, "docstatus": 0, "doctype": "Letter Head", From 5f97bec2b32ed0da7403e42dfce8f1c9c6575e70 Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Wed, 17 Sep 2025 01:02:51 +0530 Subject: [PATCH 15/45] refactor: revert debugging changes --- .../test_process_statement_of_accounts.py | 4 ++-- erpnext/fixtures/letter_head.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py b/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py index acea3614c5e..7d5cfb90af8 100644 --- a/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py +++ b/erpnext/accounts/doctype/process_statement_of_accounts/test_process_statement_of_accounts.py @@ -81,8 +81,8 @@ class TestProcessStatementOfAccounts(AccountsTestMixin, IntegrationTestCase): process_soa = create_process_soa( name="_Test Process SOA", enable_auto_email=1, report="Accounts Receivable" ) - if not frappe.flags.in_migrate and not frappe.flags.in_install: - send_emails(process_soa.name, from_scheduler=True) + + send_emails(process_soa.name, from_scheduler=True) process_soa.load_from_db() self.assertEqual(process_soa.posting_date, getdate(add_days(today(), 7))) diff --git a/erpnext/fixtures/letter_head.json b/erpnext/fixtures/letter_head.json index 7c77cb5d9fe..1b0eb0962c8 100644 --- a/erpnext/fixtures/letter_head.json +++ b/erpnext/fixtures/letter_head.json @@ -1,7 +1,7 @@ [ { "align": "Left", - "content": "\n\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n
\n
\n {% endif %}\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n \n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n
\n
\n
{{ _(\"Invoice:\") }}
\n
{{ doc.name }}

\n
\n
\n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n
\n
\n", + "content": "\n\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n
\n \n
\n {% endif %}\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n \n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n
\n
\n
{{ _(\"Invoice:\") }}
\n
{{ doc.name }}

\n
\n
\n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n
\n
\n", "disabled": 0, "docstatus": 0, "doctype": "Letter Head", @@ -24,7 +24,7 @@ }, { "align": "Left", - "content": "\n\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n
\n
\n {% endif %}\n
\n
{{ doc.company }}
\n \n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n
\n
\n \n
\n
\n {{ _(\"Sales Invoice\") }}\n
\n
\n {{ doc.name }}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n \n
\n
\n
\n", + "content": "\n\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n
\n \n
\n {% endif %}\n
\n
{{ doc.company }}
\n \n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n
\n
\n \n
\n
\n {{ _(\"Sales Invoice\") }}\n
\n
\n {{ doc.name }}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n \n
\n
\n
\n", "disabled": 0, "docstatus": 0, "doctype": "Letter Head", From 5c4f7782231bbbf45147cf4999a58c9dbd5ad934 Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Wed, 17 Sep 2025 12:35:55 +0530 Subject: [PATCH 16/45] style: center-align logo within its container div --- erpnext/fixtures/letter_head.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/erpnext/fixtures/letter_head.json b/erpnext/fixtures/letter_head.json index 1b0eb0962c8..41ab9ccd47c 100644 --- a/erpnext/fixtures/letter_head.json +++ b/erpnext/fixtures/letter_head.json @@ -1,7 +1,7 @@ [ { "align": "Left", - "content": "\n\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n
\n \n
\n {% endif %}\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n \n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n
\n
\n
{{ _(\"Invoice:\") }}
\n
{{ doc.name }}

\n
\n
\n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n
\n
\n", + "content": "\n\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n
\n \n
\n {% endif %}\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n \n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n
\n
\n
{{ _(\"Invoice:\") }}
\n
{{ doc.name }}

\n
\n
\n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n
\n
\n", "disabled": 0, "docstatus": 0, "doctype": "Letter Head", @@ -16,15 +16,15 @@ "image": null, "image_height": 0.0, "image_width": 0.0, - "is_default": 0, + "is_default": 1, "letter_head_name": "Sales Invoice Letter Head", - "modified": "2025-09-15 16:23:58.583661", + "modified": "2025-09-17 11:58:06.023854", "name": "Sales Invoice Letter Head", "source": "HTML" }, { "align": "Left", - "content": "\n\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n
\n \n
\n {% endif %}\n
\n
{{ doc.company }}
\n \n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n
\n
\n \n
\n
\n {{ _(\"Sales Invoice\") }}\n
\n
\n {{ doc.name }}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n \n
\n
\n
\n", + "content": "\n\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n
\n \n
\n {% endif %}\n
\n
{{ doc.company }}
\n \n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n
\n
\n \n
\n
\n {{ _(\"Sales Invoice\") }}\n
\n
\n {{ doc.name }}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n \n
\n
\n
\n", "disabled": 0, "docstatus": 0, "doctype": "Letter Head", @@ -41,7 +41,7 @@ "image_width": 0.0, "is_default": 0, "letter_head_name": "Print Format Letter Head", - "modified": "2025-09-15 16:14:24.080812", + "modified": "2025-09-17 12:10:40.229447", "name": "Print Format Letter Head", "source": "HTML" } From f4f2d11fa47fbe774f89767bed43a34bab9e56df Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Wed, 17 Sep 2025 12:37:25 +0530 Subject: [PATCH 17/45] style: always show border even when logo is missing --- erpnext/fixtures/letter_head.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/fixtures/letter_head.json b/erpnext/fixtures/letter_head.json index 41ab9ccd47c..f5bb820fc38 100644 --- a/erpnext/fixtures/letter_head.json +++ b/erpnext/fixtures/letter_head.json @@ -1,7 +1,7 @@ [ { "align": "Left", - "content": "\n\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n
\n \n
\n {% endif %}\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n \n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n
\n
\n
{{ _(\"Invoice:\") }}
\n
{{ doc.name }}

\n
\n
\n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n
\n
\n", + "content": "\n\n
\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n \n {% endif %}\n
\n
\n
{{ doc.company }}
\n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n \n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n
\n
\n
{{ _(\"Invoice:\") }}
\n
{{ doc.name }}

\n
\n
\n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n
\n
\n", "disabled": 0, "docstatus": 0, "doctype": "Letter Head", @@ -18,13 +18,13 @@ "image_width": 0.0, "is_default": 1, "letter_head_name": "Sales Invoice Letter Head", - "modified": "2025-09-17 11:58:06.023854", + "modified": "2025-09-17 12:31:46.314509", "name": "Sales Invoice Letter Head", "source": "HTML" }, { "align": "Left", - "content": "\n\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n
\n \n
\n {% endif %}\n
\n
{{ doc.company }}
\n \n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n
\n
\n \n
\n
\n {{ _(\"Sales Invoice\") }}\n
\n
\n {{ doc.name }}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n \n
\n
\n
\n", + "content": "\n\n
\n
\n
\n {% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %}\n {% if company_logo %}\n \n {% endif %}\n
\n
\n
{{ doc.company }}
\n \n {% set company_address = frappe.get_all(\n \"Dynamic Link\",\n fields=[\"parent\"],\n filters={\n \"link_doctype\": \"Company\",\n \"link_name\": doc.company,\n \"parenttype\": \"Address\"\n },\n limit=1\n ) %}\n \n {% if company_address %}\n {% set address = frappe.get_doc(\"Address\", company_address[0].parent) %}\n {{ address.address_line1 or \"\" }}
\n {% if address.address_line2 %}{{ address.address_line2 }}
{% endif %}\n {{ address.city or \"\" }} {{ address.state or \"\" }} {{ address.pincode or \"\" }} {{ address.country or \"\" }}
\n {% endif %}\n
\n
\n
\n
\n \n
\n
\n {{ _(\"Sales Invoice\") }}\n
\n
\n {{ doc.name }}\n
\n
\n\n
\n {% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n {% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n {% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n \n \n {% if website %}\n
\n
{{ _(\"Website:\") }}
\n
{{ website }}

\n
\n {% endif %}\n {% if email %}\n
\n
{{ _(\"Email:\") }}
\n
{{ email }}

\n
\n {% endif %}\n {% if phone_no %}\n
\n
{{ _(\"Contact:\") }}
\n
{{ phone_no }}

\n
\n {% endif %}\n \n
\n
\n
\n", "disabled": 0, "docstatus": 0, "doctype": "Letter Head", @@ -41,7 +41,7 @@ "image_width": 0.0, "is_default": 0, "letter_head_name": "Print Format Letter Head", - "modified": "2025-09-17 12:10:40.229447", + "modified": "2025-09-17 12:31:46.318339", "name": "Print Format Letter Head", "source": "HTML" } From 670361059687c0a31bfb08fc7054b46d0af64e66 Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Wed, 17 Sep 2025 13:14:56 +0530 Subject: [PATCH 18/45] fix: do not make letterhead default --- erpnext/fixtures/letter_head.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/fixtures/letter_head.json b/erpnext/fixtures/letter_head.json index f5bb820fc38..48d46ea937b 100644 --- a/erpnext/fixtures/letter_head.json +++ b/erpnext/fixtures/letter_head.json @@ -16,7 +16,7 @@ "image": null, "image_height": 0.0, "image_width": 0.0, - "is_default": 1, + "is_default": 0, "letter_head_name": "Sales Invoice Letter Head", "modified": "2025-09-17 12:31:46.314509", "name": "Sales Invoice Letter Head", From 39b6aab714fb9155dd4227c0441267a13ac3dfe8 Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Fri, 19 Sep 2025 02:14:32 +0530 Subject: [PATCH 19/45] fix: update styles to work with wkhtmltopdf rendering --- .../print_format_sales_invoice.html | 355 ++++++------ .../sales_invoice_print_format.html | 504 +++++++++--------- 2 files changed, 456 insertions(+), 403 deletions(-) diff --git a/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.html b/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.html index 233083b1f34..392b3af0dc1 100644 --- a/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.html +++ b/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.html @@ -2,23 +2,26 @@ print_heading_template=None) -%} {% if letter_head and not no_letterhead %}
{{ letter_head }}
{% endif %} {% if print_heading_template %} {{ frappe.render_template(print_heading_template, {"doc":doc}) }} -{% endif %} {%- if doc.meta.is_submittable and doc.docstatus==2 -%} -
-

{{ _("CANCELLED") }}

-
-{%- endif -%} {%- endmacro -%} {% for page in layout %} +{% endif %} {%- endmacro -%} {% for page in layout %}
{{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings) }}
- - - - - - -
-
-
Customer Name:
-
Bill to:
-
-
-
{{ doc.customer_name }}
-
{{ doc.address_display or "" }}
-
-
-
-
Invoice Number:
-
Invoice Date:
-
Payment Due Date:
-
-
-
{{ doc.name }}
-
{{ frappe.utils.format_date(doc.posting_date) }}
-
{{ frappe.utils.format_date(doc.due_date) }}
-
-
- - - - - - - - - - - - +
- - - - - - - - - - {% for item in doc.items %} - - - - - - - + - {% endfor %} - -
{{ _("No") }}{{ _("Item") }}{{ _("HSN/SAC") }}{{ _("Quantity") }}{{ _("Rate") }}{{ _("Amount") }}
{{ loop.index }} -
-
- {% if item.image %} -
- {{ item.item_name }} -
- {% endif %} -
-
{{ item.item_name }}
+
+
+
Customer Name:
+
Bill to:
+
+
+
{{ doc.customer_name }}
+
{{ doc.address_display or "" }}
{{ item.gst_hsn_code }}{{ item.get_formatted("qty", 0) }} {{ item.uom }}{{ item.get_formatted("net_rate", doc) }}{{ item.get_formatted("net_amount", doc) }} +
+
Invoice Number:
+
Invoice Date:
+
Payment Due Date:
+
+
+
{{ doc.name }}
+
{{ frappe.utils.format_date(doc.posting_date) }}
+
{{ frappe.utils.format_date(doc.due_date) }}
+
+
+
- - - + +
 
+ + + + + + + + + + + + + + + + + + + + {% for item in doc.items %} + + + - - + + + + + + {% endfor %} + +
{{ _("No") }}{{ _("Item") }}{{ _("HSN/SAC") }}{{ _("Quantity") }}{{ _("Rate") }}{{ _("Amount") }}
{{ loop.index }} +
+
+ {% if item.image %} +
+ {{ item.item_name }} +
+ {% endif %} +
+
{{ item.item_name }}
+
+
- - - - - - - - - - {% set tax_rate = doc.taxes | selectattr("tax_amount") | sum(attribute="rate") %} {% if - tax_rate > 0 %} - - - - - {% endif %} -
{{ _("Sub Total:") }}{{ doc.get_formatted("total", doc) }}
- {{ _("Discount") }} ({{ doc.additional_discount_percentage or 0 }}%): - {{ doc.get_formatted("discount_amount", doc) }}
{{ _("Tax") }} ({{ tax_rate }}%):{{ doc.get_formatted("total_taxes_and_charges", doc) }}
-
{{ item.gst_hsn_code }}{{ item.get_formatted("qty", 0) }} {{ item.uom }}{{ item.get_formatted("net_rate", doc) }}{{ item.get_formatted("net_amount", doc) }}
- - -
+ + + + + - -
  - - + + + + + - + + + {% set tax_rate = doc.taxes | selectattr("tax_amount") | sum(attribute="rate") %} {% + if tax_rate > 0 %} + + + {% endif %}
-
{{ _("In Words: ") }}{{ doc.in_words }}
+
{{ _("Sub Total:") }}{{ doc.get_formatted("total", doc) }}
+ {{ _("Discount") }} ({{ doc.additional_discount_percentage or 0 }}%): {{ _("Grand Total:") }}{{ doc.get_formatted("discount_amount", doc) }}
{{ _("Tax") }} ({{ tax_rate }}%): - - {{ doc.get_formatted("grand_total", doc) }} - + {{ doc.get_formatted("total_taxes_and_charges", doc) }}
- -
- - {% if doc.taxes_and_charges %} - -
{{ _("Tax Breakup") }}
- - - - - {% for row in doc.taxes %} - - {% endfor %} - - - - {% for item in doc.items %} - - - - {% for row in doc.taxes %} {% set tax_amount = item.base_net_amount * (row.rate / 100) %} - - {% endfor %} - {% endfor %} - -
{{ _("HSN/SAC") }}{{ _("Taxable Amount") }}{{ row.description }} ({{ row.rate }}%)
{{ item.gst_hsn_code }}{{ item.get_formatted("base_net_amount", doc) }} - {{ frappe.format_value(tax_amount, {"fieldtype": "Currency"}, doc) }}
- {% endif %} - - {% if doc.terms %} -
-
{{ _("Terms and Conditions") }}
- {{ doc.terms}} + + +
+ + + + + + +
+
+ {{ _("In Words: ") }}{{ doc.in_words }} +
+
{{ _("Grand Total:") }} + + {{ doc.get_formatted("grand_total", doc) }} + +
+
+ + + + + {% if doc.taxes_and_charges %} + +
{{ _("Tax Breakup") }}
+ + + + + {% for row in doc.taxes %} + + {% endfor %} + + + + {% for item in doc.items %} + + + + {% for row in doc.taxes %} {% set tax_amount = item.base_net_amount * (row.rate / 100) %} + + {% endfor %} + + {% endfor %} + +
{{ _("HSN/SAC") }}{{ _("Taxable Amount") }}{{ row.description }} ({{ row.rate }}%)
{{ item.gst_hsn_code }}{{ item.get_formatted("base_net_amount", doc) }} + {{ frappe.format_value(tax_amount, {"fieldtype": "Currency"}, doc) }} +
+ {% endif %} + + + {% if doc.terms %} +
+
{{ _("Terms and Conditions") }}
+ {{ doc.terms}} +
+ {% endif %}
- {% endif %}
{% endfor %} diff --git a/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html b/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html index a97d5f67790..4457b2ac7a6 100644 --- a/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html +++ b/erpnext/accounts/print_format/sales_invoice_print_format/sales_invoice_print_format.html @@ -12,278 +12,304 @@ print_heading_template=None) -%} {% if letter_head and not no_letterhead %} {{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings) }} - + .title { + color: #7c7c7c !important; + } - - - - - - - - - - - {% set address = (doc.address_display) %} {% if address and address.rstrip().endswith("
") %} {% set - address = address[:-5] %} {% endif %} {% set company_address_display = - (doc.company_address_display) %} {% if company_address_display and company_address_display.rstrip().endswith("
") %} {% - set company_address_display = company_address_display[:-5] %} {% endif %} - - - -
- {{ _("Customer Name") }}: {{doc.customer_name }} - - {{ _("Payment Due Date") }}: {{ - frappe.utils.format_date(doc.due_date) }} -
{{ _("Invoice Number") }}: {{ doc.name }} - {{ _("Invoice Date") }}: {{ - frappe.utils.format_date(doc.posting_date) }} -
{{ _("Bill From") }}:
{{ address }}
{{ _("Bill To") }}:
{{ company_address_display }}
+ .heading { + color: #525252 !important; + font-weight: 300; + } - - - - - - - - - - + .print-format { + color: #171717; + font-size: 14px; + font-style: normal; + font-weight: 420; + line-height: 21px; + padding: 0px; + letter-spacing: 0.14px; + margin-left: 0mm !important; + margin-right: 0mm !important; + } + .letter-head-footer { + margin-top: 0px !important; + } + .print-heading { + margin-top: 0px !important; + margin-bottom: 0px !important; + padding-bottom: 0px !important; + } + +
- - - - - + + - - - {% for item in doc.items %} - - - - - + + - {% endfor %} - -
{{ _("No") }}{{ _("Item") }}{{ _("Quantity") }}{{ _("Rate") }}{{ _("Amount") }} + {{ _("Customer Name") }}: {{doc.customer_name }} + + {{ _("Payment Due Date") }}: {{ + frappe.utils.format_date(doc.due_date) }} +
{{ loop.index }}{{ item.item_name }}{{ item.get_formatted("qty", 0) }} {{ item.uom }}{{ item.get_formatted("net_rate", doc) }}{{ item.get_formatted("net_amount", doc) }}{{ _("Invoice Number") }}: {{ doc.name }} + {{ _("Invoice Date") }}: {{ + frappe.utils.format_date(doc.posting_date) }} +
+ + {% set address = (doc.address_display) %} {% if address and address.rstrip().endswith("
") + %} {% set address = address[:-5] %} {% endif %} {% set company_address_display = + (doc.company_address_display) %} {% if company_address_display and + company_address_display.rstrip().endswith("
") %} {% set company_address_display = + company_address_display[:-5] %} {% endif %} + {{ _("Bill From") }}:
{{ address }} + {{ _("Bill To") }}:
{{ company_address_display }} + + - -
-
-
-

{{ _("Total in words") }}

-
{{ doc.in_words }}
-
-
-
- - - - - - - - - - {% set tax_rate = doc.taxes | selectattr("tax_amount") | sum(attribute="rate") %} {% if - tax_rate > 0 %} - - - - - {% endif %} - - - - -
{{ _("Sub Total:") }}{{ doc.get_formatted("total", doc) }}
- {{ _("Discount") }} ({{ doc.additional_discount_percentage }}%): - {{ doc.get_formatted("discount_amount", doc) }}
{{ _("Tax") }} ({{ tax_rate }}%):{{ doc.get_formatted("total_taxes_and_charges", doc) }}
{{ _("Grand Total:") }}{{ doc.get_formatted("grand_total", doc) }}
-
-
- - - {% if doc.taxes_and_charges %} -
{{ _("Tax Breakup") }}
-
- + +
+ + + + + + + - - - {% for row in doc.taxes %} - - {% endfor %} + + + + + {% for item in doc.items %} - - - {% for row in doc.taxes %} {% set tax_amount = item.base_net_amount * (row.rate / 100) %} - + + + + - {% endfor %} {% endfor %}
{{ _("HSN/SAC") }}{{ _("Taxable Amount") }}{{ row.description }}{{ _("No") }}{{ _("Item") }}{{ _("Quantity") }}{{ _("Rate") }}{{ _("Amount") }}
{{ item.gst_hsn_code }}{{ item.get_formatted("base_net_amount", doc) }} - ({{ (row.rate) }}%) {{ frappe.format_value(tax_amount, {"fieldtype": "Currency"}, doc) - }} + {{ loop.index }}{{ item.item_name }}{{ item.get_formatted("qty", 0) }} {{ item.uom }}{{ item.get_formatted("net_rate", doc) }} + {{ item.get_formatted("net_amount", doc) }}
-
- {% endif %} - - {% if doc.terms %} -
-
{{ _("Terms and Conditions") }}
- {{ doc.terms}} + +
+
+
+

{{ _("Total in words") }}

+
{{ doc.in_words }}
+
+
+
+ + + + + + + + + + {% set tax_rate = doc.taxes | selectattr("tax_amount") | sum(attribute="rate") %} {% if + tax_rate > 0 %} + + + + + {% endif %} + + + + +
{{ _("Sub Total:") }}{{ doc.get_formatted("total", doc) }}
+ {{ _("Discount") }} ({{ doc.additional_discount_percentage }}%): + {{ doc.get_formatted("discount_amount", doc) }}
{{ _("Tax") }} ({{ tax_rate }}%):{{ doc.get_formatted("total_taxes_and_charges", doc) }}
{{ _("Grand Total:") }}{{ doc.get_formatted("grand_total", doc) }}
+
+
+ + + {% if doc.taxes_and_charges %} +
{{ _("Tax Breakup") }}
+
+ + + + + + {% for row in doc.taxes %} + + {% endfor %} + + + + {% for item in doc.items %} + + + + {% for row in doc.taxes %} {% set tax_amount = item.base_net_amount * (row.rate / 100) + %} + + {% endfor %} + + {% endfor %} + +
{{ _("HSN/SAC") }}{{ _("Taxable Amount") }}{{ row.description }}
{{ item.gst_hsn_code }}{{ item.get_formatted("base_net_amount", doc) }} + ({{ (row.rate) }}%) {{ frappe.format_value(tax_amount, {"fieldtype": "Currency"}, + doc) }} +
+
+ {% endif %} + + + {% if doc.terms %} +
+
{{ _("Terms and Conditions") }}
+ {{ doc.terms}} +
+ {% endif %}
- {% endif %} {% endfor %} From e22373192491a11ec4d8904d40b256fb51ebfe94 Mon Sep 17 00:00:00 2001 From: khushi8112 Date: Fri, 19 Sep 2025 14:09:18 +0530 Subject: [PATCH 20/45] refactor: remove flex usage for better wkhtmltopdf support --- .../print_format_sales_invoice.html | 77 +++++++++++-------- 1 file changed, 45 insertions(+), 32 deletions(-) diff --git a/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.html b/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.html index 392b3af0dc1..2042b4271ba 100644 --- a/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.html +++ b/erpnext/accounts/print_format/print_format_sales_invoice/print_format_sales_invoice.html @@ -1,8 +1,13 @@ {%- macro add_header(page_num, max_pages, doc, letter_head, no_letterhead, footer, print_settings=None, -print_heading_template=None) -%} {% if letter_head and not no_letterhead %} -
{{ letter_head }}
-{% endif %} {% if print_heading_template %} {{ frappe.render_template(print_heading_template, {"doc":doc}) }} -{% endif %} {%- endmacro -%} {% for page in layout %} +print_heading_template=None) -%} +{% if letter_head and not no_letterhead %} +
{{ letter_head }}
+{% endif %} +{% if print_heading_template %} + {{ frappe.render_template(print_heading_template, {"doc":doc}) }} +{% endif %} +{%- endmacro -%} +{% for page in layout %}
{{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings) }} @@ -11,7 +16,7 @@ print_heading_template=None) -%} {% if letter_head and not no_letterhead %}