From f31b3749bcc39476395911a333fa9eaedeb6377c Mon Sep 17 00:00:00 2001 From: Shllokkk Date: Sat, 16 May 2026 17:54:02 +0530 Subject: [PATCH] feat: standard letterheads for doctype and reports --- erpnext/accounts/letter_head/__init__.py | 0 .../company_letterhead/__init__.py | 0 .../company_letterhead.json | 26 ++++ .../company_letterhead___grey/__init__.py | 0 .../company_letterhead___grey.json | 26 ++++ .../company_letterhead_report/__init__.py | 0 .../company_letterhead_report.json | 26 ++++ .../letterhead/company_letterhead.html | 108 --------------- .../letterhead/company_letterhead_grey.html | 127 ------------------ erpnext/setup/install.py | 25 ---- 10 files changed, 78 insertions(+), 260 deletions(-) create mode 100644 erpnext/accounts/letter_head/__init__.py create mode 100644 erpnext/accounts/letter_head/company_letterhead/__init__.py create mode 100644 erpnext/accounts/letter_head/company_letterhead/company_letterhead.json create mode 100644 erpnext/accounts/letter_head/company_letterhead___grey/__init__.py create mode 100644 erpnext/accounts/letter_head/company_letterhead___grey/company_letterhead___grey.json create mode 100644 erpnext/accounts/letter_head/company_letterhead_report/__init__.py create mode 100644 erpnext/accounts/letter_head/company_letterhead_report/company_letterhead_report.json delete mode 100644 erpnext/accounts/letterhead/company_letterhead.html delete mode 100644 erpnext/accounts/letterhead/company_letterhead_grey.html diff --git a/erpnext/accounts/letter_head/__init__.py b/erpnext/accounts/letter_head/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/letter_head/company_letterhead/__init__.py b/erpnext/accounts/letter_head/company_letterhead/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/letter_head/company_letterhead/company_letterhead.json b/erpnext/accounts/letter_head/company_letterhead/company_letterhead.json new file mode 100644 index 00000000000..e0b41c42e51 --- /dev/null +++ b/erpnext/accounts/letter_head/company_letterhead/company_letterhead.json @@ -0,0 +1,26 @@ +{ + "align": "Left", + "content": "\n\t\n\t\t\n\t\t\t\n\n\t\t\t\n\n\t\t\t\n\t\t\n\t\n
\n\t\t\t\t
\n\t\t\t\t\t{% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %} {% if\n\t\t\t\t\tcompany_logo %}\n\t\t\t\t\t\"Company\n\t\t\t\t\t{% endif %}\n\t\t\t\t
\n\t\t\t
\n\t\t\t\t
{{ doc.company }}
\n\t\t\t\t{% if doc.company_address %} {% set company_address = frappe.db.get_value(\"Address\",\n\t\t\t\tdoc.company_address, [\"address_line1\", \"address_line2\", \"city\", \"state\", \"pincode\",\n\t\t\t\t\"country\"], as_dict=True) %} {% elif doc.billing_address %} {% set company_address =\n\t\t\t\tfrappe.db.get_value(\"Address\", doc.billing_address, [\"address_line1\", \"address_line2\", \"city\",\n\t\t\t\t\"state\", \"pincode\", \"country\"], as_dict=True) %} {% endif %} {% if company_address %} {{\n\t\t\t\tcompany_address.address_line1 or \"\" }}
\n\t\t\t\t{% if company_address.address_line2 %} {{ company_address.address_line2 }}
\n\t\t\t\t{% endif %} {{ company_address.city or \"\" }}, {{ company_address.state or \"\" }} {{\n\t\t\t\tcompany_address.pincode or \"\" }}, {{ company_address.country or \"\"}}
\n\t\t\t\t{% endif %}\n\t\t\t
\n\t\t\t\t{% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %} {% set email =\n\t\t\t\tfrappe.db.get_value(\"Company\", doc.company, \"email\") %} {% set phone_no =\n\t\t\t\tfrappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n\n\t\t\t\t
\n\t\t\t\t\t{{ doc.doctype }}\n\t\t\t\t\t{{ doc.name }}\n\t\t\t\t
\n\t\t\t\t{% if website %}\n\t\t\t\t
\n\t\t\t\t\t{{ _(\"Website:\") }}\n\t\t\t\t\t{{ website }}\n\t\t\t\t
\n\t\t\t\t{% endif %} {% if email %}\n\t\t\t\t
\n\t\t\t\t\t{{ _(\"Email:\") }}\n\t\t\t\t\t{{ email }}\n\t\t\t\t
\n\t\t\t\t{% endif %} {% if phone_no %}\n\t\t\t\t
\n\t\t\t\t\t{{ _(\"Contact:\") }}\n\t\t\t\t\t{{ phone_no }}\n\t\t\t\t
\n\t\t\t\t{% endif %}\n\t\t\t
", + "creation": "2026-05-15 15:21:48.255627", + "custom_css": "\t.letter-head {\n\t\tborder-radius: 18px;\n\t\tpadding-right: 12px;\n\t\tmargin-left: 12px;\n\t\tmargin-right: 12px;\n\t}\n\n\t.letter-head td {\n\t\tpadding: 0px !important;\n\t}\n\t.invoice-header {\n\t\twidth: 100%;\n\t}\n\t.logo-cell {\n\t\twidth: 100px;\n\t\ttext-align: center;\n\t\tposition: relative;\n\t}\n\t.logo-container {\n\t\twidth: 90px;\n\t\tdisplay: block;\n\t}\n\t.logo-container img {\n\t\tmax-width: 90px;\n\t\tmax-height: 90px;\n\t\tdisplay: inline-block;\n\t\tborder-radius: 15px;\n\t}\n\t.company-details {\n\t\twidth: 40%;\n\t\talign-content: center;\n\t}\n\t.company-name {\n\t\tfont-size: 14px;\n\t\tfont-weight: bold;\n\t\tcolor: #171717;\n\t\tmargin-bottom: 4px;\n\t}\n\t.invoice-info-cell {\n\t\tfloat: right;\n\t\tvertical-align: top;\n\t}\n\t.invoice-info {\n\t\tmargin-bottom: 2px;\n\t}\n\t.invoice-label {\n\t\tcolor: #7c7c7c;\n\t\tdisplay: inline-block;\n\t\tmargin-right: 5px;\n\t}", + "disabled": 0, + "docstatus": 0, + "doctype": "Letter Head", + "footer_align": "Left", + "footer_image_height": 0.0, + "footer_image_width": 0.0, + "footer_source": "Image", + "idx": 0, + "image_height": 0.0, + "image_width": 0.0, + "is_default": 0, + "letter_head_for": "DocType", + "letter_head_name": "Company Letterhead", + "modified": "2026-05-16 15:15:23.014622", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Company Letterhead", + "owner": "Administrator", + "source": "HTML", + "standard": "Yes" +} diff --git a/erpnext/accounts/letter_head/company_letterhead___grey/__init__.py b/erpnext/accounts/letter_head/company_letterhead___grey/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/letter_head/company_letterhead___grey/company_letterhead___grey.json b/erpnext/accounts/letter_head/company_letterhead___grey/company_letterhead___grey.json new file mode 100644 index 00000000000..0f0f903dad9 --- /dev/null +++ b/erpnext/accounts/letter_head/company_letterhead___grey/company_letterhead___grey.json @@ -0,0 +1,26 @@ +{ + "align": "Left", + "content": "\n\t\n\t\t\n\t\t\t\n\n\t\t\t\n\t\t\n\t\n
\n\t\t\t\t{% set company_logo = frappe.db.get_value(\"Company\", doc.company, \"company_logo\") %} {% if\n\t\t\t\tcompany_logo %}\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\t{% endif %}\n\t\t\t\t
{{ doc.company }}
\n\t\t\t\t
\n\t\t\t\t\t{% if doc.company_address %} {% set company_address = frappe.db.get_value(\"Address\",\n\t\t\t\t\tdoc.company_address, [\"address_line1\", \"address_line2\", \"city\", \"state\", \"pincode\",\n\t\t\t\t\t\"country\"], as_dict=True) %} {% elif doc.billing_address %} {% set company_address =\n\t\t\t\t\tfrappe.db.get_value(\"Address\", doc.billing_address, [\"address_line1\", \"address_line2\",\n\t\t\t\t\t\"city\", \"state\", \"pincode\", \"country\"], as_dict=True) %} {% endif %} {% if company_address\n\t\t\t\t\t%} {{ company_address.address_line1 or \"\" }}
\n\t\t\t\t\t{% if company_address.address_line2 %} {{ company_address.address_line2 }}
\n\t\t\t\t\t{% endif %} {{ company_address.city or \"\" }}, {{ company_address.state or \"\" }} {{\n\t\t\t\t\tcompany_address.pincode or \"\" }}, {{ company_address.country or \"\"}}
\n\t\t\t\t\t{% endif %}\n\t\t\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t
{{ doc.doctype }}
\n\t\t\t\t\t
{{ doc.name }}
\n\t\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t{% set company_details = frappe.db.get_value(\"Company\", doc.company, [\"website\", \"email\",\n\t\t\t\t\t\"phone_no\"], as_dict=True) %} {% set website = company_details.website %} {% set email =\n\t\t\t\t\tcompany_details.email %} {% set phone_no = company_details.phone_no %} {% if website %}\n\t\t\t\t\t
\n\t\t\t\t\t\t{{ _(\"Website:\") }}{{ website }}\n\t\t\t\t\t
\n\t\t\t\t\t{% endif %} {% if email %}\n\t\t\t\t\t
\n\t\t\t\t\t\t{{ _(\"Email:\") }}{{ email }}\n\t\t\t\t\t
\n\t\t\t\t\t{% endif %} {% if phone_no %}\n\t\t\t\t\t
\n\t\t\t\t\t\t{{ _(\"Contact:\") }}{{ phone_no }}\n\t\t\t\t\t
\n\t\t\t\t\t{% endif %}\n\t\t\t\t
\n\t\t\t
\n", + "creation": "2026-05-15 15:21:48.373815", + "custom_css": "\t.print-format-preview {\n\t\tmargin-top: 12px;\n\t}\n\t.letter-head {\n\t\tborder-radius: 18px;\n\t\tbackground: #f8f8f8;\n\t\tpadding: 12px;\n\t\tmargin-left: 12px;\n\t\tmargin-right: 12px;\n\t}\n\t.letterhead-container {\n\t\twidth: 100%;\n\t}\n\t.letterhead-container .other-details {\n\t\tposition: absolute;\n\t\tright: 0;\n\t\tbottom: 0;\n\t}\n\t.logo-address {\n\t\twidth: 65%;\n\t\tvertical-align: top;\n\t}\n\n\t.letter-head .logo {\n\t\twidth: 90px;\n\t\tdisplay: block;\n\t\tmargin-bottom: 10px;\n\t}\n\n\t.letter-head .logo img {\n\t\tborder-radius: 15px;\n\t}\n\n\t.company-name {\n\t\tcolor: #171717;\n\t\tfont-weight: bold;\n\t\tline-height: 23px;\n\t\tmargin-bottom: 5px;\n\t}\n\n\t.company-address {\n\t\tcolor: #171717;\n\t\twidth: 300px;\n\t}\n\n\t.invoice-title {\n\t\tfont-weight: bold;\n\t}\n\n\t.invoice-number {\n\t\tcolor: #7c7c7c;\n\t}\n\n\t.contact-title {\n\t\tcolor: #7c7c7c;\n\t\twidth: 60px;\n\t\tdisplay: inline-block;\n\t\tvertical-align: top;\n\t\tmargin-right: 10px;\n\t}\n\n\t.contact-value {\n\t\tcolor: #171717;\n\t\tdisplay: inline-block;\n\t}\n\t.letterhead-container td {\n\t\tpadding: 0px !important;\n\t\tposition: relative;\n\t}", + "disabled": 0, + "docstatus": 0, + "doctype": "Letter Head", + "footer_align": "Left", + "footer_image_height": 0.0, + "footer_image_width": 0.0, + "footer_source": "Image", + "idx": 0, + "image_height": 0.0, + "image_width": 0.0, + "is_default": 0, + "letter_head_for": "DocType", + "letter_head_name": "Company Letterhead - Grey", + "modified": "2026-05-16 15:15:19.942207", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Company Letterhead - Grey", + "owner": "Administrator", + "source": "HTML", + "standard": "Yes" +} diff --git a/erpnext/accounts/letter_head/company_letterhead_report/__init__.py b/erpnext/accounts/letter_head/company_letterhead_report/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/letter_head/company_letterhead_report/company_letterhead_report.json b/erpnext/accounts/letter_head/company_letterhead_report/company_letterhead_report.json new file mode 100644 index 00000000000..cc158d71aed --- /dev/null +++ b/erpnext/accounts/letter_head/company_letterhead_report/company_letterhead_report.json @@ -0,0 +1,26 @@ +{ + "align": "Left", + "content": "\n\t\n\t\t\n\n\t\t\t\n\n\t\t\t\n\n\t\t\t\n\n\t\t\n\t\n
\n\t\t\t\t{% set company = frappe.get_doc(\"Company\", doc.company) %}\n\n\t\t\t\t
\n\t\t\t\t\t{% if company.company_logo %}\n\t\t\t\t\t\"Company\n\t\t\t\t\t{% endif %}\n\t\t\t\t
\n\t\t\t
\n\t\t\t\t
{{ company.name }}
\n\n\t\t\t\t{% set company_address_name = frappe.db.get_value(\n\t\t\t\t\t\"Dynamic Link\",\n\t\t\t\t\t{\n\t\t\t\t\t\t\"link_doctype\": \"Company\",\n\t\t\t\t\t\t\"link_name\": company.name,\n\t\t\t\t\t\t\"parenttype\": \"Address\"\n\t\t\t\t\t},\n\t\t\t\t\t\"parent\"\n\t\t\t\t) %}\n\n\t\t\t\t{% if company_address_name %}\n\t\t\t\t\t{% set company_address = frappe.db.get_value(\n\t\t\t\t\t\t\"Address\",\n\t\t\t\t\t\tcompany_address_name,\n\t\t\t\t\t\t[\"address_line1\", \"address_line2\", \"city\", \"state\", \"pincode\", \"country\"],\n\t\t\t\t\t\tas_dict=True\n\t\t\t\t\t) %}\n\t\t\t\t{% endif %}\n\n\t\t\t\t{% if company_address %}\n\t\t\t\t
\n\t\t\t\t\t{{ company_address.address_line1 or \"\" }}\n\n\t\t\t\t\t{% if company_address.address_line2 %}\n\t\t\t\t\t\t
{{ company_address.address_line2 }}\n\t\t\t\t\t{% endif %}\n\n\t\t\t\t\t
\n\n\t\t\t\t\t{{ company_address.city or \"\" }}\n\t\t\t\t\t{% if company_address.state %}, {{ company_address.state }}{% endif %}\n\t\t\t\t\t{{ company_address.pincode or \"\" }}\n\n\t\t\t\t\t{% if company_address.country %}\n\t\t\t\t\t\t, {{ company_address.country }}\n\t\t\t\t\t{% endif %}\n\t\t\t\t
\n\t\t\t\t{% endif %}\n\t\t\t
\n\n\t\t\t\t{% set website = frappe.db.get_value(\"Company\", doc.company, \"website\") %}\n\t\t\t\t{% set email = frappe.db.get_value(\"Company\", doc.company, \"email\") %}\n\t\t\t\t{% set phone_no = frappe.db.get_value(\"Company\", doc.company, \"phone_no\") %}\n\n\t\t\t\t{% if website %}\n\t\t\t\t
\n\t\t\t\t\t{{ _(\"Website:\") }}\n\t\t\t\t\t{{ website }}\n\t\t\t\t
\n\t\t\t\t{% endif %}\n\n\t\t\t\t{% if email %}\n\t\t\t\t
\n\t\t\t\t\t{{ _(\"Email:\") }}\n\t\t\t\t\t{{ email }}\n\t\t\t\t
\n\t\t\t\t{% endif %}\n\n\t\t\t\t{% if phone_no %}\n\t\t\t\t
\n\t\t\t\t\t{{ _(\"Contact:\") }}\n\t\t\t\t\t{{ phone_no }}\n\t\t\t\t
\n\t\t\t\t{% endif %}\n\t\t\t
", + "creation": "2026-05-15 19:49:47.582252", + "custom_css": ".letter-head {\n\tborder-radius: 18px;\n\tpadding: 8px 10px;\n\tmargin: 10px 0 14px;\n\tfont-family: Inter, sans-serif;\n\tfont-size: 14px;\n\tcolor: #171717;\n}\n\n.letter-head td {\n\tpadding: 0 !important;\n\tvertical-align: middle;\n}\n\n.invoice-header {\n\twidth: 100%;\n\tborder-collapse: collapse;\n\ttable-layout: fixed;\n\tborder-bottom: 1px solid #ededed;\n\tpadding-bottom: 10px;\n}\n\n.logo-cell {\n\twidth: 100px;\n\ttext-align: center;\n\twhite-space: nowrap;\n}\n\n.logo-container {\n\tdisplay: inline-block;\n\tmargin: auto;\n}\n\n.logo-container img {\n\tmax-width: 95px;\n\tmax-height: 95px;\n\tdisplay: block;\n\tborder-radius: 12px;\n}\n\n.company-details {\n\twidth: 55%;\n\tpadding-left: 10px !important;\n\tline-height: 1.5;\n}\n\n.company-name {\n\tfont-size: 14px;\n\tfont-weight: 600;\n\tcolor: #171717;\n\tmargin-bottom: 4px;\n}\n\n.company-address {\n\tfont-size: 14px;\n\tline-height: 1.5;\n\tcolor: #171717;\n}\n\n.invoice-info-cell {\n\twidth: 240px;\n\ttext-align: right;\n\tvertical-align: top !important;\n\tline-height: 1.5;\n}\n\n.document-name {\n\tfont-size: 14px;\n\tfont-weight: 600;\n\tcolor: #171717;\n\tmargin-bottom: 6px;\n}\n\n.invoice-info {\n\tfont-size: 14px;\n\tcolor: #171717;\n\tmargin-bottom: 2px;\n\tfont-variant-numeric: tabular-nums;\n}\n\n.invoice-label {\n\tcolor: #7c7c7c;\n\tfont-weight: 500;\n\tmargin-right: 4px;\n\tdisplay: inline-block;\n}", + "disabled": 0, + "docstatus": 0, + "doctype": "Letter Head", + "footer_align": "Left", + "footer_image_height": 0.0, + "footer_image_width": 0.0, + "footer_source": "Image", + "idx": 0, + "image_height": 0.0, + "image_width": 0.0, + "is_default": 0, + "letter_head_for": "Report", + "letter_head_name": "Company Letterhead Report", + "modified": "2026-05-16 15:15:26.155770", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Company Letterhead Report", + "owner": "Administrator", + "source": "HTML", + "standard": "Yes" +} diff --git a/erpnext/accounts/letterhead/company_letterhead.html b/erpnext/accounts/letterhead/company_letterhead.html deleted file mode 100644 index 7cdf58cb6e0..00000000000 --- a/erpnext/accounts/letterhead/company_letterhead.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - - - - - - -
-
- {% set company_logo = frappe.db.get_value("Company", doc.company, "company_logo") %} {% if - company_logo %} - Company Logo - {% endif %} -
-
-
{{ doc.company }}
- {% if doc.company_address %} {% set company_address = frappe.db.get_value("Address", - doc.company_address, ["address_line1", "address_line2", "city", "state", "pincode", - "country"], as_dict=True) %} {% elif doc.billing_address %} {% set company_address = - frappe.db.get_value("Address", doc.billing_address, ["address_line1", "address_line2", "city", - "state", "pincode", "country"], as_dict=True) %} {% endif %} {% if company_address %} {{ - company_address.address_line1 or "" }}
- {% if company_address.address_line2 %} {{ company_address.address_line2 }}
- {% endif %} {{ company_address.city or "" }}, {{ company_address.state or "" }} {{ - company_address.pincode or "" }}, {{ company_address.country or ""}}
- {% endif %} -
- {% set website = frappe.db.get_value("Company", doc.company, "website") %} {% set email = - frappe.db.get_value("Company", doc.company, "email") %} {% set phone_no = - frappe.db.get_value("Company", doc.company, "phone_no") %} - -
- {{ doc.doctype }} - {{ doc.name }} -
- {% if website %} -
- {{ _("Website:") }} - {{ website }} -
- {% endif %} {% if email %} -
- {{ _("Email:") }} - {{ email }} -
- {% endif %} {% if phone_no %} -
- {{ _("Contact:") }} - {{ phone_no }} -
- {% endif %} -
diff --git a/erpnext/accounts/letterhead/company_letterhead_grey.html b/erpnext/accounts/letterhead/company_letterhead_grey.html deleted file mode 100644 index a46d33ebd95..00000000000 --- a/erpnext/accounts/letterhead/company_letterhead_grey.html +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - - - -
- {% set company_logo = frappe.db.get_value("Company", doc.company, "company_logo") %} {% if - company_logo %} - - {% endif %} -
{{ doc.company }}
-
- {% if doc.company_address %} {% set company_address = frappe.db.get_value("Address", - doc.company_address, ["address_line1", "address_line2", "city", "state", "pincode", - "country"], as_dict=True) %} {% elif doc.billing_address %} {% set company_address = - frappe.db.get_value("Address", doc.billing_address, ["address_line1", "address_line2", - "city", "state", "pincode", "country"], as_dict=True) %} {% endif %} {% if company_address - %} {{ company_address.address_line1 or "" }}
- {% if company_address.address_line2 %} {{ company_address.address_line2 }}
- {% endif %} {{ company_address.city or "" }}, {{ company_address.state or "" }} {{ - company_address.pincode or "" }}, {{ company_address.country or ""}}
- {% endif %} -
-
-
-
{{ doc.doctype }}
-
{{ doc.name }}
-
-
-
- {% 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 }} -
- {% endif %} -
-
diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py index b80ad82c9d3..3ae247fe810 100644 --- a/erpnext/setup/install.py +++ b/erpnext/setup/install.py @@ -37,7 +37,6 @@ def after_install(): make_default_operations() update_pegged_currencies() set_default_print_formats() - create_letter_head() toggle_hidden_fields() frappe.db.commit() @@ -342,30 +341,6 @@ def set_default_print_formats(): ) -def create_letter_head(): - base_path = frappe.get_app_path("erpnext", "accounts", "letterhead") - - letterheads = { - "Company Letterhead": "company_letterhead.html", - "Company Letterhead - Grey": "company_letterhead_grey.html", - } - - for name, filename in letterheads.items(): - if not frappe.db.exists("Letter Head", name): - content = frappe.read_file(os.path.join(base_path, filename)) - doc = frappe.get_doc( - { - "doctype": "Letter Head", - "letter_head_name": name, - "source": "HTML", - "content": content, - "is_default": 1 if name == "Company Letterhead - Grey" else 0, - "letter_head_for": "Report", - } - ) - doc.insert(ignore_permissions=True) - - def toggle_hidden_fields(): from erpnext.accounts.doctype.accounts_settings.accounts_settings import ( toggle_accounting_dimension_sections,