From c82666d5636005b5b357078d14b86a614b095787 Mon Sep 17 00:00:00 2001 From: kurogeek Date: Thu, 10 Sep 2026 10:45:22 +0700 Subject: [PATCH] feat: default letter head --- .../fixtures/address_template.json | 11 +++++ .../fixtures/letter_head.json | 25 ++++++++++++ default_thai_company/hooks.py | 31 ++++++++------ default_thai_company/utils.py | 40 +++++++++++++++++++ 4 files changed, 94 insertions(+), 13 deletions(-) create mode 100644 default_thai_company/fixtures/address_template.json create mode 100644 default_thai_company/fixtures/letter_head.json create mode 100644 default_thai_company/utils.py diff --git a/default_thai_company/fixtures/address_template.json b/default_thai_company/fixtures/address_template.json new file mode 100644 index 0000000..fc0a8eb --- /dev/null +++ b/default_thai_company/fixtures/address_template.json @@ -0,0 +1,11 @@ +[ + { + "country": "Thailand", + "docstatus": 0, + "doctype": "Address Template", + "is_default": 1, + "modified": "2026-09-09 17:23:33.559202", + "name": "Thailand", + "template": "{{ address_line1 }}{% if address_line2 %} {{ address_line2 }}{% endif %}
\n{% if county %}{{ county }} {% endif -%}{{ city }}{% if state %} {{ state }}{% endif -%}{% if pincode %} {{ pincode }}{% endif -%}{% if country != \"Thailand\" %} {{ country }}{% endif %}
\n{% if phone or fax or email_id %}
{% endif -%}\n{% if phone %}{{ _(\"Phone\") }}: {{ phone }}
{% endif -%}\n{% if fax %}{{ _(\"Fax\") }}: {{ fax }}
{% endif -%}\n{% if email_id %}{{ _(\"Email\") }}: {{ email_id }}
{% endif -%}\n" + } +] diff --git a/default_thai_company/fixtures/letter_head.json b/default_thai_company/fixtures/letter_head.json new file mode 100644 index 0000000..d3e1ee3 --- /dev/null +++ b/default_thai_company/fixtures/letter_head.json @@ -0,0 +1,25 @@ +[ + { + "align": "Left", + "content": "\n{% set company = get_letter_head_company(doc) %}\n{% if company %}\n
\n {% if company.company_logo %}\n \"{{\n {% endif %}\n
\n

{{ company.company_name }}

\n \n {% if company.tax_id %}
Tax ID: {{ company.tax_id }}
{% endif %}\n {% if company.address %}
{{ company.address }}
{% endif %}\n {% if company.phone_no %}
Phone: {{ company.phone_no }}
{% endif %}\n {% if company.email %}
Email: {{ company.email }}
{% endif %}\n
\n
\n
\n{% endif %}\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": "Default Letter Head", + "modified": "2026-09-10 09:51:23.933752", + "name": "Default Letter Head", + "source": "HTML" + } +] diff --git a/default_thai_company/hooks.py b/default_thai_company/hooks.py index 22adbe7..38648fc 100644 --- a/default_thai_company/hooks.py +++ b/default_thai_company/hooks.py @@ -8,7 +8,7 @@ app_license = "gpl-3.0" # Apps # ------------------ -# required_apps = [] +required_apps = ["erpnext"] # Each item in the list will be shown as an app in the apps page # add_to_apps_screen = [ @@ -74,10 +74,17 @@ app_license = "gpl-3.0" # ---------- # add methods and filters to jinja environment -# jinja = { -# "methods": "default_thai_company.utils.jinja_methods", -# "filters": "default_thai_company.utils.jinja_filters" -# } +jinja = { + "methods": ["default_thai_company.utils.get_letter_head_company"], +} + +# Fixtures +# -------- + +fixtures = [ + {"doctype": "Letter Head", "filters": [["name", "in", ["Default Letter Head"]]]}, + {"doctype": "Address Template", "filters": [["name", "in", ["Thailand"]]]}, +] # Installation # ------------ @@ -137,13 +144,12 @@ app_license = "gpl-3.0" # --------------- # Hook on document methods and events -# doc_events = { -# "*": { -# "on_update": "method", -# "on_cancel": "method", -# "on_trash": "method" -# } -# } +doc_events = { + "Letter Head": { + "before_import": "default_thai_company.utils.stash_letter_head_source", + "before_insert": "default_thai_company.utils.restore_letter_head_source", + } +} # Scheduled Tasks # --------------- @@ -246,4 +252,3 @@ app_license = "gpl-3.0" # ------------ # List of apps whose translatable strings should be excluded from this app's translations. # ignore_translatable_strings_from = [] - diff --git a/default_thai_company/utils.py b/default_thai_company/utils.py new file mode 100644 index 0000000..84da132 --- /dev/null +++ b/default_thai_company/utils.py @@ -0,0 +1,40 @@ +import frappe +from erpnext import get_default_company +from frappe.contacts.doctype.address.address import get_default_address, render_address + + +def get_letter_head_company(doc=None): + """Company details for the Letter Head template. + + Resolves the company from the printed document's `company` field, falling + back to the user's/global default company for documents without one. + Returns None when no company can be resolved. + """ + company_name = (doc.get("company") if doc else None) or get_default_company() + if not company_name or not frappe.db.exists("Company", company_name): + return None + + company = frappe.get_cached_doc("Company", company_name) + address_name = get_default_address("Company", company_name) + + return frappe._dict( + name=company.name, + company_name=company.company_name, + tax_id=company.tax_id, + phone_no=company.phone_no, + email=company.email, + website=company.website, + company_logo=company.company_logo, + address=render_address(address_name, check_permissions=False) if address_name else None, + ) + + +def stash_letter_head_source(doc, method=None): + """Fixture import re-inserts the Letter Head; remember the fixture's `source`.""" + doc.flags.fixture_source = doc.source + + +def restore_letter_head_source(doc, method=None): + """LetterHead.before_insert forces `source = "Image"`; restore the fixture's value.""" + if doc.flags.fixture_source: + doc.source = doc.flags.fixture_source