diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index e1ca58c4583..0b312cd6ac2 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -288,26 +288,35 @@ class SalesInvoice(SellingController):
"Company", self.company, ["company_logo", "website", "phone_no", "email"], as_dict=True
)
- address_display_list = get_address_display_list("Company", self.company)
- address_line = address_display_list[0] if address_display_list else ""
-
required_fields = [
company_details.get("company_logo"),
company_details.get("phone_no"),
company_details.get("email"),
- self.company_address,
- address_line,
]
- if not all(required_fields):
- if not frappe.has_permission("Company", "write", throw=False):
- frappe.msgprint(
- _(
- "Some required Company details are missing. You don't have permission to update them. Please contact your System Manager."
- )
+ if not all(required_fields) and not frappe.has_permission("Company", "write", throw=False):
+ frappe.msgprint(
+ _(
+ "Some required Company details are missing. You don't have permission to update them. Please contact your System Manager."
)
- return
+ )
+ return
+ if not self.company_address and not frappe.has_permission("Sales Invoice", "write", throw=False):
+ frappe.msgprint(
+ _(
+ "Company Address is missing. You don't have permission to update it. Please contact your System Manager."
+ )
+ )
+ return
+
+ address_display_list = get_address_display_list("Company", self.company)
+ address_line = address_display_list[0].get("address_line1") if address_display_list else ""
+
+ required_fields.append(self.company_address)
+ required_fields.append(address_line)
+
+ if not all(required_fields):
frappe.publish_realtime(
"sales_invoice_before_print",
{
diff --git a/erpnext/accounts/letterhead/letterhead_plain.html b/erpnext/accounts/letterhead/company_letterhead.html
similarity index 88%
rename from erpnext/accounts/letterhead/letterhead_plain.html
rename to erpnext/accounts/letterhead/company_letterhead.html
index 8fbf58ec68f..f4b8db863f6 100644
--- a/erpnext/accounts/letterhead/letterhead_plain.html
+++ b/erpnext/accounts/letterhead/company_letterhead.html
@@ -79,30 +79,27 @@
{% set company_details = frappe.db.get_value("Company", doc.company, ["website", "email", "phone_no"], as_dict=True) %}
- {% set website = company_details.website %}
- {% set email = company_details.email %}
- {% set phone_no = company_details.phone_no %}
{{ _("Invoice:") }}
{{ doc.name }}
- {% if website %}
+ {% if company_details.website %}
{{ _("Website:") }}
- {{ website }}
+ {{ company_details.website }}
{% endif %}
- {% if email %}
+ {% if company_details.email %}
{{ _("Email:") }}
- {{ email }}
+ {{ company_details.email }}
{% endif %}
- {% if phone_no %}
+ {% if company_details.phone_no %}
{{ _("Contact:") }}
- {{ phone_no }}
+ {{ company_details.phone_no }}
{% endif %}
|
diff --git a/erpnext/accounts/letterhead/letterhead_with_background_colour.html b/erpnext/accounts/letterhead/company_letterhead_grey.html
similarity index 79%
rename from erpnext/accounts/letterhead/letterhead_with_background_colour.html
rename to erpnext/accounts/letterhead/company_letterhead_grey.html
index 425a81ff081..3736c19084f 100644
--- a/erpnext/accounts/letterhead/letterhead_with_background_colour.html
+++ b/erpnext/accounts/letterhead/company_letterhead_grey.html
@@ -100,21 +100,23 @@
{% set company_details = frappe.db.get_value("Company", doc.company, ["website", "email", "phone_no"], as_dict=True) %}
- {% set website = company_details.website %} {% set email = company_details.email %} {% set phone_no = company_details.phone_no %} {% if website %}
-
- {{ _("Website:") }}{{ website }}
-
- {% endif %} {% if email %}
-
- {{ _("Email:") }}{{ email }}
-
- {% endif %} {% if phone_no %}
-
- {{ _("Contact:") }}{{ phone_no }}
-
+ {% if company_details.website %}
+
+ {{ _("Website:") }}{{ company_details.website }}
+
+ {% endif %}
+ {% if company_details.email %}
+
+ {{ _("Email:") }}{{ company_details.email }}
+
+ {% endif %}
+ {% if company_details.phone_no %}
+
+ {{ _("Contact:") }}{{ company_details.phone_no }}
+
{% endif %}
diff --git a/erpnext/accounts/print_format/sales_invoice_standard/sales_invoice_standard.json b/erpnext/accounts/print_format/sales_invoice_standard/sales_invoice_standard.json
index 42031d7dce5..f66861078d3 100644
--- a/erpnext/accounts/print_format/sales_invoice_standard/sales_invoice_standard.json
+++ b/erpnext/accounts/print_format/sales_invoice_standard/sales_invoice_standard.json
@@ -9,14 +9,14 @@
"docstatus": 0,
"doctype": "Print Format",
"font_size": 14,
- "html": "{%- macro add_header(page_num, max_pages, doc, letter_head, no_letterhead, footer, print_settings=None, print_heading_template=None) -%}\n\t{% if letter_head and not no_letterhead %}\n\t\t{{ letter_head }}
\n\t{% endif %}\n\t{% if print_heading_template %}\n\t\t{{ frappe.render_template(print_heading_template, {\"doc\":doc}) }}\n\t{% endif %}\n{%- endmacro -%}\n\n{% for page in layout %}\n\n\t\n\t{%- if doc.meta.is_submittable and doc.docstatus==2-%}\n\t\t
\n\t\t\t
{{ _(\"CANCELLED\") }}
\n\t\t\n\t{%- endif -%}\n\t{%- if doc.meta.is_submittable and doc.docstatus==0 and (print_settings==None or print_settings.add_draft_heading) -%}\n\t\t
\n\t\t\t
{{ _(\"DRAFT\") }}
\n\t\t\n\t{%- endif -%}\n\n\t\n\t
\n\t\t
\n\t\t\t\n\t\t\t\t| \n\t\t\t\t\t{{ _(\"Customer Name\") }}: {{doc.customer_name }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ _(\"Payment Due Date\") }}: {{\n\t\t\t\t\tfrappe.utils.format_date(doc.due_date) }}\n\t\t\t\t | \n\t\t\t
\n\t\t\t\n\t\t\t\t| {{ _(\"Invoice Number\") }}: {{ doc.name }} | \n\t\t\t\t\n\t\t\t\t\t{{ _(\"Invoice Date\") }}: {{\n\t\t\t\t\tfrappe.utils.format_date(doc.posting_date) }}\n\t\t\t\t | \n\t\t\t
\n\t\t\t\n\t\t\t\t{{ _(\"Bill From\") }}: \n\t\t\t\t\t{% if doc.customer_address %}\n\t\t\t\t\t\t{% set customer_address = frappe.db.get_value(\"Address\", doc.customer_address, [\"address_line1\", \"address_line2\", \"city\", \"state\", \"pincode\", \"country\"], as_dict=True) %}\n {{ doc.customer_name }} \n\t\t\t\t\t\t{{ customer_address.address_line1 or \"\" }} \n\t\t\t\t\t\t{% if customer_address.address_line2 %}{{ customer_address.address_line2 }} {% endif %}\n\t\t\t\t\t\t{{ customer_address.city or \"\" }} {{ customer_address.state or \"\" }} {{ customer_address.pincode or \"\" }} {{ customer_address.country or \"\" }} \n\t\t\t\t\t{% endif %}\n\t\t\t\t | \n\t\t\t\t{{ _(\"Bill To\") }}: \n\t\t\t\t\t{% if doc.company_address %}\n {% set company_address = frappe.db.get_value(\"Address\", doc.company_address, [\"address_line1\", \"address_line2\", \"city\", \"state\", \"pincode\", \"country\"], as_dict=True) %}\n {{ doc.company }} \n {{ company_address.get(\"address_line1\") or \"\" }} \n {% if company_address.get(\"address_line2\") %}{{ company_address.get(\"address_line2\") }} {% endif %}\n {{ company_address.get(\"city\") or \"\" }}, {{ company_address.get(\"state\") or \"\" }} {{ company_address.get(\"pincode\") or \"\" }}, {{ company_address.get(\"country\") or \"\" }} \n {% endif %}\n\t\t\t\t | \n\t\t\t
\n\t\t
\n\n\t\t\n\t\t{% set item_naming_by = frappe.db.get_single_value(\"Stock Settings\", \"item_naming_by\") %}\n\t\t
\n\t\t\t\n\t\t\t\n\t\t\t\t{% for item in doc.items %}\n\t\t\t\t\n\t\t\t\t\t| {{ loop.index }} | \n\t\t\t\t\t{{ item.item_name }} | \n\t\t\t\t\t{% if item_naming_by != \"Item Code\" %}\n\t\t\t\t\t\t{{ item.item_code }} | \n\t\t\t\t\t{% endif %}\n\t\t\t\t\t{{ item.get_formatted(\"qty\", 0) }} {{ item.uom }} | \n\t\t\t\t\t{{ item.get_formatted(\"net_rate\", doc) }} | \n\t\t\t\t\t\n\t\t\t\t\t\t{{ item.get_formatted(\"net_amount\", doc) }}\n\t\t\t\t\t | \n\t\t\t\t
\n\t\t\t\t{% endfor %}\n\t\t\t\n\t\t
\n\n\t\t\n\t\t
\n\t\t\t| \n\t\t\t\t {{ _(\"Total in words\") }} \n\t\t\t\t{{ doc.in_words }} \n\t\t\t | \n\t\t\t\n\t\t\t\t \n\t\t\t | \n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t| {{ _(\"Sub Total:\") }} | \n\t\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }} | \n\t\t\t\t\t \n\t\t\t\t\t{%- if doc.apply_discount_on == \"Net Total\" -%}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t| \n\t\t\t\t\t\t\t\t{{ _(\"Discount\") }} ({{ doc.additional_discount_percentage }}%):\n\t\t\t\t\t\t\t | \n\t\t\t\t\t\t\t{{ doc.get_formatted(\"discount_amount\", doc) }} | \n\t\t\t\t\t\t \n\t\t\t\t\t{%- endif -%}\n\t\t\t\t\t{%- for tax in doc.taxes -%}\n\t\t\t\t\t\t{%- if (tax.tax_amount or print_settings.print_taxes_with_zero_amount) and (not tax.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) -%}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t| {{ tax.get_formatted(\"description\") }} ({{ tax.get_formatted(\"rate\") }}%): | \n\t\t\t\t\t\t\t\t{{ tax.get_formatted(\"tax_amount\") }} | \n\t\t\t\t\t\t\t \n\t\t\t\t\t\t{%- endif -%}\n\t\t\t\t\t{%- endfor -%}\n\t\t\t\t\t{%- if doc.apply_discount_on == \"Grand Total\" -%}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t| \n\t\t\t\t\t\t\t\t{{ _(\"Discount\") }} ({{ doc.additional_discount_percentage }}%):\n\t\t\t\t\t\t\t | \n\t\t\t\t\t\t\t{{ doc.get_formatted(\"discount_amount\", doc) }} | \n\t\t\t\t\t\t \n\t\t\t\t\t{%- endif -%}\n\t\t\t\t\t\n\t\t\t\t\t\t| {{ _(\"Grand Total:\") }} | \n\t\t\t\t\t\t{{ doc.get_formatted(\"grand_total\", doc) }} | \n\t\t\t\t\t \n\t\t\t\t \n\t\t\t | \n\t\t
\n\n\t\t\n\t\t
\n\t\t\t{% if doc.terms %}\n\t\t\t
\n\t\t\t\t
{{ _(\"Terms and Conditions\") }}
\n\t\t\t\t{{ doc.terms}}\n\t\t\t
\n\t\t\t{% endif %}\n\t
\n
\n{% endfor %}\n",
+ "html": "{%- macro add_header(page_num, max_pages, doc, letter_head, no_letterhead, footer, print_settings=None, print_heading_template=None) -%}\n\t{% if letter_head and not no_letterhead %}\n\t\t
{{ letter_head }}
\n\t{% endif %}\n\t{% if print_heading_template %}\n\t\t{{ frappe.render_template(print_heading_template, {\"doc\":doc}) }}\n\t{% endif %}\n{%- endmacro -%}\n\n{% for page in layout %}\n
\n\t\n\t{%- if doc.meta.is_submittable and doc.docstatus==2-%}\n\t\t
\n\t\t\t
{{ _(\"CANCELLED\") }}
\n\t\t\n\t{%- endif -%}\n\t{%- if doc.meta.is_submittable and doc.docstatus==0 and (print_settings==None or print_settings.add_draft_heading) -%}\n\t\t
\n\t\t\t
{{ _(\"DRAFT\") }}
\n\t\t\n\t{%- endif -%}\n\n\t\n\t
\n\t\t
\n\t\t\t\n\t\t\t\t| \n\t\t\t\t\t{{ _(\"Customer Name\") }}: {{doc.customer_name }}\n\t\t\t\t | \n\t\t\t\t\n\t\t\t\t\t{{ _(\"Payment Due Date\") }}: {{\n\t\t\t\t\tfrappe.utils.format_date(doc.due_date) }}\n\t\t\t\t | \n\t\t\t
\n\t\t\t\n\t\t\t\t| {{ _(\"Invoice Number\") }}: {{ doc.name }} | \n\t\t\t\t\n\t\t\t\t\t{{ _(\"Invoice Date\") }}: {{\n\t\t\t\t\tfrappe.utils.format_date(doc.posting_date) }}\n\t\t\t\t | \n\t\t\t
\n\t\t\t\n\t\t\t\t{{ _(\"Bill From\") }}: \n\t\t\t\t\t{% if doc.company_address %}\n {% set company_address = frappe.db.get_value(\"Address\", doc.company_address, [\"address_line1\", \"address_line2\", \"city\", \"state\", \"pincode\", \"country\"], as_dict=True) %}\n {{ doc.company }} \n {{ company_address.get(\"address_line1\") or \"\" }} \n {% if company_address.get(\"address_line2\") %}{{ company_address.get(\"address_line2\") }} {% endif %}\n {{ company_address.get(\"city\") or \"\" }}, {{ company_address.get(\"state\") or \"\" }} {{ company_address.get(\"pincode\") or \"\" }}, {{ company_address.get(\"country\") or \"\" }} \n {% endif %}\n\t\t\t\t | \n\t\t\t\t{{ _(\"Bill To\") }}: \n\t\t\t\t {% if doc.customer_address %}\n\t\t\t\t\t\t{% set customer_address = frappe.db.get_value(\"Address\", doc.customer_address, [\"address_line1\", \"address_line2\", \"city\", \"state\", \"pincode\", \"country\"], as_dict=True) %}\n {{ doc.customer_name }} \n\t\t\t\t\t\t{{ customer_address.address_line1 or \"\" }} \n\t\t\t\t\t\t{% if customer_address.address_line2 %}{{ customer_address.address_line2 }} {% endif %}\n\t\t\t\t\t\t{{ customer_address.city or \"\" }} {{ customer_address.state or \"\" }} {{ customer_address.pincode or \"\" }} {{ customer_address.country or \"\" }} \n\t\t\t\t\t{% endif %}\n\t\t\t\t | \n\t\t\t
\n\t\t
\n\n\t\t\n\t\t{% set item_naming_by = frappe.db.get_single_value(\"Stock Settings\", \"item_naming_by\") %}\n\t\t
\n\t\t\t\n\t\t\t\n\t\t\t\t{% for item in doc.items %}\n\t\t\t\t\n\t\t\t\t\t| {{ loop.index }} | \n\t\t\t\t\t{{ item.item_name }} | \n\t\t\t\t\t{% if item_naming_by != \"Item Code\" %}\n\t\t\t\t\t\t{{ item.item_code }} | \n\t\t\t\t\t{% endif %}\n\t\t\t\t\t{{ item.get_formatted(\"qty\", 0) }} {{ item.uom }} | \n\t\t\t\t\t{{ item.get_formatted(\"net_rate\", doc) }} | \n\t\t\t\t\t\n\t\t\t\t\t\t{{ item.get_formatted(\"net_amount\", doc) }}\n\t\t\t\t\t | \n\t\t\t\t
\n\t\t\t\t{% endfor %}\n\t\t\t\n\t\t
\n\n\t\t\n\t\t
\n\t\t\t| \n\t\t\t\t {{ _(\"Total in words\") }} \n\t\t\t\t{{ doc.in_words }} \n\t\t\t | \n\t\t\t\n\t\t\t\t \n\t\t\t | \n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t| {{ _(\"Sub Total:\") }} | \n\t\t\t\t\t\t{{ doc.get_formatted(\"total\", doc) }} | \n\t\t\t\t\t \n\t\t\t\t\t{%- if doc.apply_discount_on == \"Net Total\" -%}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t| \n\t\t\t\t\t\t\t\t{{ _(\"Discount\") }} ({{ doc.additional_discount_percentage }}%):\n\t\t\t\t\t\t\t | \n\t\t\t\t\t\t\t{{ doc.get_formatted(\"discount_amount\", doc) }} | \n\t\t\t\t\t\t \n\t\t\t\t\t{%- endif -%}\n\t\t\t\t\t{%- for tax in doc.taxes -%}\n\t\t\t\t\t\t{%- if (tax.tax_amount or print_settings.print_taxes_with_zero_amount) and (not tax.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) -%}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t| {{ tax.get_formatted(\"description\") }} ({{ tax.get_formatted(\"rate\") }}%): | \n\t\t\t\t\t\t\t\t{{ tax.get_formatted(\"tax_amount\") }} | \n\t\t\t\t\t\t\t \n\t\t\t\t\t\t{%- endif -%}\n\t\t\t\t\t{%- endfor -%}\n\t\t\t\t\t{%- if doc.apply_discount_on == \"Grand Total\" -%}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t| \n\t\t\t\t\t\t\t\t{{ _(\"Discount\") }} ({{ doc.additional_discount_percentage }}%):\n\t\t\t\t\t\t\t | \n\t\t\t\t\t\t\t{{ doc.get_formatted(\"discount_amount\", doc) }} | \n\t\t\t\t\t\t \n\t\t\t\t\t{%- endif -%}\n\t\t\t\t\t\n\t\t\t\t\t\t| {{ _(\"Grand Total:\") }} | \n\t\t\t\t\t\t{{ doc.get_formatted(\"grand_total\", doc) }} | \n\t\t\t\t\t \n\t\t\t\t \n\t\t\t | \n\t\t
\n\n\t\t\n\t\t
\n\t\t\t{% if doc.terms %}\n\t\t\t
\n\t\t\t\t
{{ _(\"Terms and Conditions\") }}
\n\t\t\t\t{{ doc.terms}}\n\t\t\t
\n\t\t\t{% endif %}\n\t
\n
\n{% endfor %}\n",
"idx": 0,
"line_breaks": 0,
"margin_bottom": 15.0,
"margin_left": 15.0,
"margin_right": 15.0,
"margin_top": 15.0,
- "modified": "2025-10-10 18:30:16.740071",
+ "modified": "2025-10-12 17:18:38.613066",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Standard",
diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py
index 49550d8094d..ab29db3a4c8 100644
--- a/erpnext/setup/install.py
+++ b/erpnext/setup/install.py
@@ -286,8 +286,8 @@ def create_letter_head():
base_path = frappe.get_app_path("erpnext", "accounts", "letterhead")
letterheads = {
- "Letterhead with background colour": "letterhead_with_background_colour.html",
- "Letterhead Plain": "letterhead_plain.html",
+ "Company Letterhead": "company_letterhead.html",
+ "Company Letterhead - Grey": "company_letterhead_grey.html",
}
for name, filename in letterheads.items():