From e35179d413c78d8a82f82f85e283e26ff6586b5a Mon Sep 17 00:00:00 2001 From: kurogeek Date: Thu, 10 Sep 2026 08:04:37 +0000 Subject: [PATCH] feat: default Sales Invoice print format Add the "Default Standard Sales Invoice" Print Format fixture and the Property Setter that makes it the default for Sales Invoice. The format reproduces Frappe's standard layout and appends a Bank Account Details section on the last page when the company has an enabled Bank Account flagged Is Company Account + Is Default Account (get_company_bank_account jinja method). --- .../fixtures/print_format.json | 36 +++++++++++++++++++ .../fixtures/property_setter.json | 18 ++++++++++ default_thai_company/hooks.py | 10 +++++- default_thai_company/utils.py | 22 ++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 default_thai_company/fixtures/print_format.json create mode 100644 default_thai_company/fixtures/property_setter.json diff --git a/default_thai_company/fixtures/print_format.json b/default_thai_company/fixtures/print_format.json new file mode 100644 index 0000000..9a51f93 --- /dev/null +++ b/default_thai_company/fixtures/print_format.json @@ -0,0 +1,36 @@ +[ + { + "absolute_value": 0, + "align_labels_right": 0, + "css": null, + "custom_format": 1, + "default_print_language": null, + "disabled": 0, + "doc_type": "Sales Invoice", + "docstatus": 0, + "doctype": "Print Format", + "font": null, + "font_size": 14, + "format_data": null, + "html": "{%- from \"templates/print_formats/standard_macros.html\" import add_header, render_field with context -%}\n{%- set bank_account = get_company_bank_account(doc.company) -%}\n\n{% for page in layout %}\n
\n\t
\n\t\t{{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings, print_heading_template) }}\n\t
\n\n\t{% for section in page %}\n\t
\n\t\t{%- if doc.print_line_breaks and loop.index != 1 -%}
{%- endif -%}\n\t\t{%- if doc.print_section_headings and section.label and section.has_data -%}\n\t\t

{{ _(section.label) }}

\n\t\t{%- endif -%}\n\t\t{%- set no_of_cols = section.columns|len -%}\n\t\t{% for column in section.columns %}\n\t\t\t
\n\t\t\t{% for df in column.fields %}\n\t\t\t\t{{ render_field(df, doc, no_of_cols) }}\n\t\t\t{% endfor %}\n\t\t\t
\n\t\t{% endfor %}\n\t
\n\t{% endfor %}\n\n\t{% if loop.last and bank_account %}\n\t
\n\t\t{%- if doc.print_line_breaks -%}
{%- endif -%}\n\t\t
\n\t\t\t

{{ _(\"Bank Account Details\") }}

\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\n\t\t\t\t\t{% if bank_account.bank_account_no %}\n\t\t\t\t\t\n\t\t\t\t\t{% endif %}\n\t\t\t\t\t{% if bank_account.iban %}\n\t\t\t\t\t\n\t\t\t\t\t{% endif %}\n\t\t\t\t\t{% if bank_account.branch_code %}\n\t\t\t\t\t\n\t\t\t\t\t{% endif %}\n\t\t\t\t\t{% if bank_account.swift_number %}\n\t\t\t\t\t\n\t\t\t\t\t{% endif %}\n\t\t\t\t\n\t\t\t\n\t\t
\n\t
\n\t{% endif %}\n\n\t
\n\t\t{% if not no_letterhead and footer %}\n\t\t
\n\t\t\t{{ footer }}\n\t\t
\n\t\t{% endif %}\n\t\t{% if print_settings.repeat_header_footer %}\n\t\t\t

\n\t\t\t\t{{ _(\"Page {0} of {1}\").format('', '') }}\n\t\t\t

\n\t\t{% endif %}\n\t
\n
\n{% endfor %}\n", + "line_breaks": 0, + "margin_bottom": 15.0, + "margin_left": 15.0, + "margin_right": 15.0, + "margin_top": 15.0, + "modified": "2026-09-10 14:59:44.872542", + "module": "Default Thai Company", + "name": "Default Standard Sales Invoice", + "page_number": "Hide", + "pdf_generator": "wkhtmltopdf", + "print_format_builder": 0, + "print_format_builder_beta": 0, + "print_format_for": "DocType", + "print_format_type": "Jinja", + "raw_commands": null, + "raw_printing": 0, + "report": null, + "show_section_headings": 0, + "standard": "No" + } +] \ No newline at end of file diff --git a/default_thai_company/fixtures/property_setter.json b/default_thai_company/fixtures/property_setter.json new file mode 100644 index 0000000..3fe2e50 --- /dev/null +++ b/default_thai_company/fixtures/property_setter.json @@ -0,0 +1,18 @@ +[ + { + "default_value": null, + "doc_type": "Sales Invoice", + "docstatus": 0, + "doctype": "Property Setter", + "doctype_or_field": "DocType", + "field_name": null, + "is_system_generated": 1, + "modified": "2026-09-10 13:55:13.996942", + "module": null, + "name": "Sales Invoice-main-default_print_format", + "property": "default_print_format", + "property_type": "Data", + "row_name": null, + "value": "Default Standard Sales Invoice" + } +] \ No newline at end of file diff --git a/default_thai_company/hooks.py b/default_thai_company/hooks.py index 38648fc..7139065 100644 --- a/default_thai_company/hooks.py +++ b/default_thai_company/hooks.py @@ -75,7 +75,10 @@ required_apps = ["erpnext"] # add methods and filters to jinja environment jinja = { - "methods": ["default_thai_company.utils.get_letter_head_company"], + "methods": [ + "default_thai_company.utils.get_letter_head_company", + "default_thai_company.utils.get_company_bank_account", + ], } # Fixtures @@ -84,6 +87,11 @@ jinja = { fixtures = [ {"doctype": "Letter Head", "filters": [["name", "in", ["Default Letter Head"]]]}, {"doctype": "Address Template", "filters": [["name", "in", ["Thailand"]]]}, + {"doctype": "Print Format", "filters": [["name", "in", ["Default Standard Sales Invoice"]]]}, + { + "doctype": "Property Setter", + "filters": [["name", "in", ["Sales Invoice-main-default_print_format"]]], + }, ] # Installation diff --git a/default_thai_company/utils.py b/default_thai_company/utils.py index 84da132..4b9952b 100644 --- a/default_thai_company/utils.py +++ b/default_thai_company/utils.py @@ -29,6 +29,28 @@ def get_letter_head_company(doc=None): ) +def get_company_bank_account(company=None): + """Default company Bank Account for print formats. + + Returns the enabled Bank Account flagged `Is Company Account` and + `Is Default Account` for `company`, or None when there is none. + """ + if not company: + return None + + account = frappe.db.get_value( + "Bank Account", + {"company": company, "is_company_account": 1, "is_default": 1, "disabled": 0}, + ["account_name", "bank", "bank_account_no", "iban", "branch_code"], + as_dict=True, + ) + if not account: + return None + + account.swift_number = frappe.db.get_value("Bank", account.bank, "swift_number") + return account + + 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