feat: print formats for Purchase Invoice, Purchase Order, Sales Order
Default Standard Purchase Invoice / Purchase Order / Sales Order, laid out like the Sales Invoice and Quotation formats: dates (and the supplier's or customer's reference numbers) in the heading, party block with Tax ID and contact, essentials-only item table, right-aligned totals with the amount in words beside Grand Total, signature lines. taxes include: purchase "Deduct" charges (withholding tax) print negative and "Valuation" charges are skipped so the lines add up to Grand Total; charge descriptions are translated so the WHT category names print in Thai.
This commit is contained in:
1 parent
e82d82dbcc
commit
e7d0a545b1
4 files changed
+127
-3
No files matched your search
@@ -101,6 +101,108 @@
|
|||||||
"show_section_headings": 0,
|
"show_section_headings": 0,
|
||||||
"standard": "No"
|
"standard": "No"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"absolute_value": 0,
|
||||||
|
"align_labels_right": 0,
|
||||||
|
"css": "/* Thai text needs a font with Thai glyphs; wkhtmltopdf only sees the server's fonts and a\n headless server rarely has one, so ship Sarabun (OFL, see public/fonts/OFL.txt) with the app.\n Asset URLs are made absolute for the PDF renderer by frappe.utils.scrub_urls. */\n@font-face {\n\tfont-family: \"Sarabun\";\n\tfont-weight: 400;\n\tsrc: url(\"/assets/default_thai_company/fonts/Sarabun-Regular.ttf\");\n}\n@font-face {\n\tfont-family: \"Sarabun\";\n\tfont-weight: 700;\n\tsrc: url(\"/assets/default_thai_company/fonts/Sarabun-Bold.ttf\");\n}\n.print-format {\n\tfont-family: Sarabun, Inter, \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n}\n\n/* Print Style \"Redesign\" gives .letter-head a 30px margin; tighten it. */\n.print-format .letter-head {\n\tmargin-bottom: 5px;\n}\n\n/* One vertical rhythm for every label/value line. \"Redesign\" stacks field rows with\n margin-top: 15px (doubled where Total/Taxes nest a layout .row) while the custom\n Supplier table and the heading dates had none; use line-height 1.8 everywhere\n and no row margins instead. */\n.print-format .row:not(.section-break) {\n\tmargin-top: 0 !important;\n\tline-height: 1.8;\n}\n.print-format .heading-dates,\n.print-format .supplier-details td {\n\tline-height: 1.8;\n}\n\n/* standard.css gives .table 20px top/bottom margins; keep the item table close to its neighbours. */\n.print-format [data-fieldname=\"items\"] > .table {\n\tmargin-top: 5px;\n\tmargin-bottom: 5px;\n}",
|
||||||
|
"custom_format": 1,
|
||||||
|
"default_print_language": null,
|
||||||
|
"disabled": 0,
|
||||||
|
"doc_type": "Purchase 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{#- ERPNext hides taxes marked \"Is this Tax included in Basic Rate?\" unless Accounts Settings\n enables \"Show Inclusive Tax in Print\"; always show them here so the tax line and\n \"Total (Without Tax)\" appear on invoices with inclusive tax. -#}\n{%- if doc.get(\"taxes\", {\"included_in_print_rate\": 1}) -%}\n\t{%- set ignored = doc.flags.update({\"show_inclusive_tax_in_print\": 1}) -%}\n{%- endif -%}\n{#- App copies of ERPNext's totals includes, printing the posted figures: \"total\" is the net before\n the Additional Discount; \"taxes\" prints the discount's net share, Net Total and each charge after\n discount (withholding tax as a deduction), so the lines add up to Grand Total. -#}\n{%- set ignored = doc.print_templates.update({\"total\": \"default_thai_company/templates/print_formats/includes/total.html\"}) -%}\n{%- if doc.print_templates.get(\"taxes\") -%}\n\t{%- set ignored = doc.print_templates.update({\"taxes\": \"default_thai_company/templates/print_formats/includes/taxes.html\"}) -%}\n{%- endif -%}\n{#- Standard layout prints every non-empty field; drop the ones this invoice does not need.\n posting_date / due_date and the supplier's invoice reference are printed in the heading,\n supplier fields in the Supplier section, in_words in the left column of the Totals section,\n the company's billing address in the letter head. -#}\n{%- set hidden_fields = [\n\t\"total_qty\", \"tax_withholding_net_total\", \"update_outstanding_for_self\",\n\t\"update_billed_amount_in_purchase_order\", \"update_billed_amount_in_purchase_receipt\",\n\t\"billing_address\", \"billing_address_display\", \"supplier_group\", \"disable_rounded_total\",\n\t\"posting_date\", \"due_date\", \"bill_no\", \"bill_date\",\n\t\"supplier_name\", \"address_display\", \"contact_display\", \"contact_mobile\", \"contact_email\", \"tax_id\",\n\t\"in_words\",\n] -%}\n{#- rounded_total keeps a value even when rounding is disabled, so the standard layout would print it. -#}\n{%- if doc.is_rounded_total_disabled() -%}{%- set ignored = hidden_fields.append(\"rounded_total\") -%}{%- endif -%}\n{#- add_header renders this string via frappe.render_template with {\"doc\": doc}, so it is kept\n unrendered with {% raw %}. Same markup as the stock heading plus a right-aligned date block. -#}\n{%- set heading_template -%}\n{% raw %}\n<div class=\"print-heading\">\n\t<style>\n\t\t.print-heading .heading-dates { float: right; text-align: right; margin-top: 4px; white-space: nowrap; }\n\t\t.print-heading .heading-dates label { display: inline; font-weight: 700; margin: 0 4px 0 0; }\n\t\t.print-heading .heading-clear { clear: both; }\n\t</style>\n\t<div class=\"heading-dates\">\n\t\t<div><label>{{ _(doc.meta.get_label(\"posting_date\")) }}:</label> {{ doc.get_formatted(\"posting_date\") }}</div>\n\t\t{%- if doc.due_date %}\n\t\t<div><label>{{ _(doc.meta.get_label(\"due_date\")) }}:</label> {{ doc.get_formatted(\"due_date\") }}</div>\n\t\t{%- endif %}\n\t\t{%- if doc.bill_no %}\n\t\t<div><label>{{ _(doc.meta.get_label(\"bill_no\")) }}:</label> {{ doc.bill_no }}</div>\n\t\t{%- endif %}\n\t\t{%- if doc.bill_date %}\n\t\t<div><label>{{ _(doc.meta.get_label(\"bill_date\")) }}:</label> {{ doc.get_formatted(\"bill_date\") }}</div>\n\t\t{%- endif %}\n\t</div>\n\t<h2>\n\t\t<div>{{ _(doc.select_print_heading) or (_(doc.print_heading) if doc.print_heading != None else _(doc.doctype)) }}</div>\n\t\t<small class=\"sub-heading\">{{ _(doc.sub_heading) if doc.sub_heading != None else _(doc.name) }}</small>\n\t</h2>\n\t<div class=\"heading-clear\"></div>\n</div>\n{% endraw %}\n{%- endset -%}\n{#- Standard layout prints every non-empty child column; keep the item table to the essentials.\n Purchase Invoice Item marks item_code print_hide (it prints item_name instead); show the code\n as the other formats do. -#}\n{%- set item_columns = [\n\t{\"fieldname\": \"item_code\", \"print_hide\": 0},\n\t{\"fieldname\": \"description\"},\n\t{\"fieldname\": \"qty\"},\n\t{\"fieldname\": \"rate\"},\n\t{\"fieldname\": \"amount\"},\n] -%}\n\n{%- macro render_fields(fields, no_of_cols) -%}\n\t{%- for df in fields -%}\n\t\t{%- if df.fieldname not in hidden_fields -%}\n\t\t\t{%- if df.fieldname == \"items\" -%}\n\t\t\t\t{%- set df = df.as_dict() -%}\n\t\t\t\t{%- set ignored = df.update({\"visible_columns\": item_columns}) -%}\n\t\t\t{%- endif -%}\n\t\t\t{{ render_field(df, doc, no_of_cols) }}\n\t\t{%- endif -%}\n\t{%- endfor -%}\n{%- endmacro -%}\n\n{% for page in layout %}\n<div class=\"page-break\">\n\t<div {% if print_settings.repeat_header_footer %} id=\"header-html\" class=\"hidden-pdf\" {% endif %}>\n\t\t{{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings, heading_template) }}\n\t</div>\n\n\t{% if loop.first %}\n\t<div class=\"row section-break\" data-label=\"{{ _(\"Supplier\") }}\">\n\t\t<div clLine truncated
|
||||||
|
"line_breaks": 0,
|
||||||
|
"margin_bottom": 15.0,
|
||||||
|
"margin_left": 15.0,
|
||||||
|
"margin_right": 15.0,
|
||||||
|
"margin_top": 15.0,
|
||||||
|
"modified": "2026-09-23 12:00:00.000000",
|
||||||
|
"module": "Default Thai Company",
|
||||||
|
"name": "Default Standard Purchase 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"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"absolute_value": 0,
|
||||||
|
"align_labels_right": 0,
|
||||||
|
"css": "/* Thai text needs a font with Thai glyphs; wkhtmltopdf only sees the server's fonts and a\n headless server rarely has one, so ship Sarabun (OFL, see public/fonts/OFL.txt) with the app.\n Asset URLs are made absolute for the PDF renderer by frappe.utils.scrub_urls. */\n@font-face {\n\tfont-family: \"Sarabun\";\n\tfont-weight: 400;\n\tsrc: url(\"/assets/default_thai_company/fonts/Sarabun-Regular.ttf\");\n}\n@font-face {\n\tfont-family: \"Sarabun\";\n\tfont-weight: 700;\n\tsrc: url(\"/assets/default_thai_company/fonts/Sarabun-Bold.ttf\");\n}\n.print-format {\n\tfont-family: Sarabun, Inter, \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n}\n\n/* Print Style \"Redesign\" gives .letter-head a 30px margin; tighten it. */\n.print-format .letter-head {\n\tmargin-bottom: 5px;\n}\n\n/* One vertical rhythm for every label/value line. \"Redesign\" stacks field rows with\n margin-top: 15px (doubled where Total/Taxes nest a layout .row) while the custom\n Supplier table and the heading dates had none; use line-height 1.8 everywhere\n and no row margins instead. */\n.print-format .row:not(.section-break) {\n\tmargin-top: 0 !important;\n\tline-height: 1.8;\n}\n.print-format .heading-dates,\n.print-format .supplier-details td {\n\tline-height: 1.8;\n}\n\n/* standard.css gives .table 20px top/bottom margins; keep the item table close to its neighbours. */\n.print-format [data-fieldname=\"items\"] > .table {\n\tmargin-top: 5px;\n\tmargin-bottom: 5px;\n}",
|
||||||
|
"custom_format": 1,
|
||||||
|
"default_print_language": null,
|
||||||
|
"disabled": 0,
|
||||||
|
"doc_type": "Purchase Order",
|
||||||
|
"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{#- ERPNext hides taxes marked \"Is this Tax included in Basic Rate?\" unless Accounts Settings\n enables \"Show Inclusive Tax in Print\"; always show them here so the tax line and\n \"Total (Without Tax)\" appear on orders with inclusive tax. -#}\n{%- if doc.get(\"taxes\", {\"included_in_print_rate\": 1}) -%}\n\t{%- set ignored = doc.flags.update({\"show_inclusive_tax_in_print\": 1}) -%}\n{%- endif -%}\n{#- App copies of ERPNext's totals includes, printing the posted figures: \"total\" is the net before\n the Additional Discount; \"taxes\" prints the discount's net share, Net Total and each charge after\n discount (withholding tax as a deduction), so the lines add up to Grand Total. -#}\n{%- set ignored = doc.print_templates.update({\"total\": \"default_thai_company/templates/print_formats/includes/total.html\"}) -%}\n{%- if doc.print_templates.get(\"taxes\") -%}\n\t{%- set ignored = doc.print_templates.update({\"taxes\": \"default_thai_company/templates/print_formats/includes/taxes.html\"}) -%}\n{%- endif -%}\n{#- Purchase Order has no Tax ID field; read the supplier's. -#}\n{%- set tax_id = frappe.db.get_value(\"Supplier\", doc.supplier, \"tax_id\") -%}\n{#- Standard layout prints every non-empty field; drop the ones this order does not need.\n transaction_date / schedule_date are printed in the heading, supplier and shipping fields in the\n Supplier section, in_words in the left column of the Totals section, the company's billing\n address in the letter head. Withholding shows as a deduction in the taxes, not as its flag. -#}\n{%- set hidden_fields = [\n\t\"total_qty\", \"tax_withholding_net_total\", \"apply_tds\", \"tax_withholding_category\", \"has_unit_price_items\",\n\t\"billing_address\", \"billing_address_display\", \"disable_rounded_total\",\n\t\"transaction_date\", \"schedule_date\",\n\t\"supplier_name\", \"address_display\", \"contact_display\", \"contact_mobile\", \"contact_email\", \"shipping_address_display\",\n\t\"in_words\",\n] -%}\n{#- rounded_total keeps a value even when rounding is disabled, so the standard layout would print it. -#}\n{%- if doc.is_rounded_total_disabled() -%}{%- set ignored = hidden_fields.append(\"rounded_total\") -%}{%- endif -%}\n{#- add_header renders this string via frappe.render_template with {\"doc\": doc}, so it is kept\n unrendered with {% raw %}. Same markup as the stock heading plus a right-aligned date block. -#}\n{%- set heading_template -%}\n{% raw %}\n<div class=\"print-heading\">\n\t<style>\n\t\t.print-heading .heading-dates { float: right; text-align: right; margin-top: 4px; white-space: nowrap; }\n\t\t.print-heading .heading-dates label { display: inline; font-weight: 700; margin: 0 4px 0 0; }\n\t\t.print-heading .heading-clear { clear: both; }\n\t</style>\n\t<div class=\"heading-dates\">\n\t\t<div><label>{{ _(doc.meta.get_label(\"transaction_date\")) }}:</label> {{ doc.get_formatted(\"transaction_date\") }}</div>\n\t\t{%- if doc.schedule_date %}\n\t\t<div><label>{{ _(doc.meta.get_label(\"schedule_date\")) }}:</label> {{ doc.get_formatted(\"schedule_date\") }}</div>\n\t\t{%- endif %}\n\t</div>\n\t<h2>\n\t\t<div>{{ _(doc.select_print_heading) or (_(doc.print_heading) if doc.print_heading != None else _(doc.doctype)) }}</div>\n\t\t<small class=\"sub-heading\">{{ _(doc.sub_heading) if doc.sub_heading != None else _(doc.name) }}</small>\n\t</h2>\n\t<div class=\"heading-clear\"></div>\n</div>\n{% endraw %}\n{%- endset -%}\n{#- Standard layout prints every non-empty child column; keep the item table to the essentials -#}\n{%- set item_columns = [\n\t{\"fieldname\": \"item_code\"},\n\t{\"fieldname\": \"description\"},\n\t{\"fieldname\": \"qty\"},\n\t{\"fieldname\": \"rate\"},\n\t{\"fieldname\": \"amount\"},\n] -%}\n\n{%- macro render_fields(fields, no_of_cols) -%}\n\t{%- for df in fields -%}\n\t\t{%- if df.fieldname not in hidden_fields -%}\n\t\t\t{%- if df.fieldname == \"items\" -%}\n\t\t\t\t{%- set df = df.as_dict() -%}\n\t\t\t\t{%- set ignored = df.update({\"visible_columns\": item_columns}) -%}\n\t\t\t{%- endif -%}\n\t\t\t{{ render_field(df, doc, no_of_cols) }}\n\t\t{%- endif -%}\n\t{%- endfor -%}\n{%- endmacro -%}\n\n{% for page in layout %}\n<div class=\"page-break\">\n\t<div {% if print_settings.repeat_header_footer %} id=\"header-html\" class=\"hidden-pdf\" {% endif %}>\n\t\t{{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings, heading_template) }}\n\t</div>\n\n\t{% if loop.first %}\n\t<div class=\"row section-break\" data-label=\"{{ _(\"Supplier\") }}\">\n\t\t<div class=\"col-xs-12 column-break\">\n\t\t\t<h4>{{ _(\"Supplier\") }}</h4>\n\t\t\t<style>\n\t\t\t\t.supplier-details { width: 100%; }\n\t\t\t\t.supplier-details td { padding: 0 !important; border: 0; vertical-align: top; }\n\t\t\t\t.supplier-details td.text-muted { width: 40%; padding-right: 1em !important; whLine truncated
|
||||||
|
"line_breaks": 0,
|
||||||
|
"margin_bottom": 15.0,
|
||||||
|
"margin_left": 15.0,
|
||||||
|
"margin_right": 15.0,
|
||||||
|
"margin_top": 15.0,
|
||||||
|
"modified": "2026-09-23 12:00:00.000000",
|
||||||
|
"module": "Default Thai Company",
|
||||||
|
"name": "Default Standard Purchase Order",
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"absolute_value": 0,
|
||||||
|
"align_labels_right": 0,
|
||||||
|
"css": "/* Thai text needs a font with Thai glyphs; wkhtmltopdf only sees the server's fonts and a\n headless server rarely has one, so ship Sarabun (OFL, see public/fonts/OFL.txt) with the app.\n Asset URLs are made absolute for the PDF renderer by frappe.utils.scrub_urls. */\n@font-face {\n\tfont-family: \"Sarabun\";\n\tfont-weight: 400;\n\tsrc: url(\"/assets/default_thai_company/fonts/Sarabun-Regular.ttf\");\n}\n@font-face {\n\tfont-family: \"Sarabun\";\n\tfont-weight: 700;\n\tsrc: url(\"/assets/default_thai_company/fonts/Sarabun-Bold.ttf\");\n}\n.print-format {\n\tfont-family: Sarabun, Inter, \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n}\n\n/* Print Style \"Redesign\" gives .letter-head a 30px margin; tighten it. */\n.print-format .letter-head {\n\tmargin-bottom: 5px;\n}\n\n/* One vertical rhythm for every label/value line. \"Redesign\" stacks field rows with\n margin-top: 15px (doubled where Total/Taxes nest a layout .row) while the custom\n Customer table and the heading dates had none; use line-height 1.8 everywhere\n and no row margins instead. */\n.print-format .row:not(.section-break) {\n\tmargin-top: 0 !important;\n\tline-height: 1.8;\n}\n.print-format .heading-dates,\n.print-format .customer-details td {\n\tline-height: 1.8;\n}\n\n/* standard.css gives .table 20px top/bottom margins; keep the item table close to its neighbours. */\n.print-format [data-fieldname=\"items\"] > .table {\n\tmargin-top: 5px;\n\tmargin-bottom: 5px;\n}",
|
||||||
|
"custom_format": 1,
|
||||||
|
"default_print_language": null,
|
||||||
|
"disabled": 0,
|
||||||
|
"doc_type": "Sales Order",
|
||||||
|
"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{#- ERPNext hides taxes marked \"Is this Tax included in Basic Rate?\" unless Accounts Settings\n enables \"Show Inclusive Tax in Print\"; always show them here so the tax line and\n \"Total (Without Tax)\" appear on orders with inclusive tax. -#}\n{%- if doc.get(\"taxes\", {\"included_in_print_rate\": 1}) -%}\n\t{%- set ignored = doc.flags.update({\"show_inclusive_tax_in_print\": 1}) -%}\n{%- endif -%}\n{#- App copies of ERPNext's totals includes, printing the posted figures: \"total\" is the net before\n the Additional Discount; \"taxes\" prints the discount's net share, Net Total and each charge after\n discount, so the lines add up to Grand Total whichever total the discount applies on. -#}\n{%- set ignored = doc.print_templates.update({\"total\": \"default_thai_company/templates/print_formats/includes/total.html\"}) -%}\n{%- if doc.print_templates.get(\"taxes\") -%}\n\t{%- set ignored = doc.print_templates.update({\"taxes\": \"default_thai_company/templates/print_formats/includes/taxes.html\"}) -%}\n{%- endif -%}\n{#- Standard layout prints every non-empty field; drop the ones this order does not need.\n transaction_date / delivery_date and the customer's PO reference are printed in the heading,\n customer and shipping fields in the Customer section, in_words in the left column of the Totals\n section, the company address in the letter head. -#}\n{%- set hidden_fields = [\n\t\"total_qty\", \"has_unit_price_items\", \"amount_eligible_for_commission\", \"per_picked\", \"loyalty_points\",\n\t\"company_address\", \"company_address_display\", \"disable_rounded_total\",\n\t\"transaction_date\", \"delivery_date\", \"po_no\", \"po_date\",\n\t\"customer_name\", \"tax_id\", \"address_display\", \"contact_display\", \"contact_phone\", \"contact_mobile\", \"contact_email\", \"shipping_address\",\n\t\"in_words\",\n] -%}\n{#- rounded_total keeps a value even when rounding is disabled, so the standard layout would print it. -#}\n{%- if doc.is_rounded_total_disabled() -%}{%- set ignored = hidden_fields.append(\"rounded_total\") -%}{%- endif -%}\n{#- add_header renders this string via frappe.render_template with {\"doc\": doc}, so it is kept\n unrendered with {% raw %}. Same markup as the stock heading plus a right-aligned date block. -#}\n{%- set heading_template -%}\n{% raw %}\n<div class=\"print-heading\">\n\t<style>\n\t\t.print-heading .heading-dates { float: right; text-align: right; margin-top: 4px; white-space: nowrap; }\n\t\t.print-heading .heading-dates label { display: inline; font-weight: 700; margin: 0 4px 0 0; }\n\t\t.print-heading .heading-clear { clear: both; }\n\t</style>\n\t<div class=\"heading-dates\">\n\t\t<div><label>{{ _(doc.meta.get_label(\"transaction_date\")) }}:</label> {{ doc.get_formatted(\"transaction_date\") }}</div>\n\t\t{%- if doc.delivery_date %}\n\t\t<div><label>{{ _(doc.meta.get_label(\"delivery_date\")) }}:</label> {{ doc.get_formatted(\"delivery_date\") }}</div>\n\t\t{%- endif %}\n\t\t{%- if doc.po_no %}\n\t\t<div><label>{{ _(doc.meta.get_label(\"po_no\")) }}:</label> {{ doc.po_no }}</div>\n\t\t{%- endif %}\n\t\t{%- if doc.po_date %}\n\t\t<div><label>{{ _(doc.meta.get_label(\"po_date\")) }}:</label> {{ doc.get_formatted(\"po_date\") }}</div>\n\t\t{%- endif %}\n\t</div>\n\t<h2>\n\t\t<div>{{ _(doc.select_print_heading) or (_(doc.print_heading) if doc.print_heading != None else _(doc.doctype)) }}</div>\n\t\t<small class=\"sub-heading\">{{ _(doc.sub_heading) if doc.sub_heading != None else _(doc.name) }}</small>\n\t</h2>\n\t<div class=\"heading-clear\"></div>\n</div>\n{% endraw %}\n{%- endset -%}\n{#- Standard layout prints every non-empty child column; keep the item table to the essentials -#}\n{%- set item_columns = [\n\t{\"fieldname\": \"item_code\"},\n\t{\"fieldname\": \"description\"},\n\t{\"fieldname\": \"qty\"},\n\t{\"fieldname\": \"rate\"},\n\t{\"fieldname\": \"amount\"},\n] -%}\n\n{%- macro render_fields(fields, no_of_cols) -%}\n\t{%- for df in fields -%}\n\t\t{%- if df.fieldname not in hidden_fields -%}\n\t\t\t{%- if df.fieldname == \"items\" -%}\n\t\t\t\t{%- set df = df.as_dict() -%}\n\t\t\t\t{%- set ignored = df.update({\"visible_columns\": item_columns}) -%}\n\t\t\t{%- endif -%}\n\t\t\t{{ render_field(df, doc, no_of_cols) }}\n\t\t{%- endif -%}\n\t{%- endfor -%}\n{%- endmacro -%}\n\n{% for page in layout %}\n<div class=\"page-break\">\n\t<div {% if print_settings.repeat_header_footer %} id=\"header-html\" class=\"hidden-pdf\" {% endif %}>\n\t\t{{ add_header(loop.index, layout|len, doc, letter_head, no_letterhead, footer, print_settings, heading_template) }}\n\t</div>\n\n\t{% if loop.first %}\n\t<div class=\"row section-break\" data-label=\"{{ _(\"Customer\") }}\">\n\t\t<div class=\"col-xs-12 column-break\">\n\t\t\t<h4>{{ _(\"Customer\") }}</h4>\n\t\t\t<style>\n\t\t\t\t.customer-details { width: 100%; }\n\t\t\t\t.customer-details td { Line truncated
|
||||||
|
"line_breaks": 0,
|
||||||
|
"margin_bottom": 15.0,
|
||||||
|
"margin_left": 15.0,
|
||||||
|
"margin_right": 15.0,
|
||||||
|
"margin_top": 15.0,
|
||||||
|
"modified": "2026-09-23 12:00:00.000000",
|
||||||
|
"module": "Default Thai Company",
|
||||||
|
"name": "Default Standard Sales Order",
|
||||||
|
"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"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"absolute_value": 0,
|
"absolute_value": 0,
|
||||||
"align_labels_right": 0,
|
"align_labels_right": 0,
|
||||||
|
|||||||
@@ -104,6 +104,9 @@ fixtures = [
|
|||||||
"Default Standard Sales Invoice",
|
"Default Standard Sales Invoice",
|
||||||
"Default Standard Tax Invoice/Receipt",
|
"Default Standard Tax Invoice/Receipt",
|
||||||
"Default Standard Quotation",
|
"Default Standard Quotation",
|
||||||
|
"Default Standard Sales Order",
|
||||||
|
"Default Standard Purchase Order",
|
||||||
|
"Default Standard Purchase Invoice",
|
||||||
"Withholding Tax Certificate",
|
"Withholding Tax Certificate",
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -10,7 +10,11 @@
|
|||||||
Net Total and the charges. Otherwise the Total line is the net before the discount, so the
|
Net Total and the charges. Otherwise the Total line is the net before the discount, so the
|
||||||
discount is its net share, followed by Net Total and the charges. A discount that is not
|
discount is its net share, followed by Net Total and the charges. A discount that is not
|
||||||
distributed (cash / non-trade) comes off the grand total only and stays after the charges,
|
distributed (cash / non-trade) comes off the grand total only and stays after the charges,
|
||||||
as upstream. -#}
|
as upstream.
|
||||||
|
|
||||||
|
Purchase documents: a "Deduct" charge (withholding tax) is taken off the total, so it is
|
||||||
|
printed negative; a "Valuation" charge only affects stock value and is not printed. Charge
|
||||||
|
descriptions are translated: the withholding categories' are in translations/th.csv. -#}
|
||||||
{%- macro amount_row(label, value) -%}
|
{%- macro amount_row(label, value) -%}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
|
<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
|
||||||
@@ -39,8 +43,8 @@
|
|||||||
{{ amount_row(_(doc.meta.get_label("net_total")), doc.get_formatted("net_total", doc)) }}
|
{{ amount_row(_(doc.meta.get_label("net_total")), doc.get_formatted("net_total", doc)) }}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- for charge in data -%}
|
{%- for charge in data -%}
|
||||||
{%- if (charge.tax_amount or print_settings.print_taxes_with_zero_amount) and (not charge.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) -%}
|
{%- if (charge.tax_amount or print_settings.print_taxes_with_zero_amount) and (not charge.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) and charge.get("category") != "Valuation" -%}
|
||||||
{{ amount_row(charge.get_formatted("description"), charge.get_formatted("tax_amount_after_discount_amount", doc)) }}
|
{{ amount_row(charge.get_formatted("description", translated=True), ("- " if charge.get("add_deduct_tax") == "Deduct" else "") ~ charge.get_formatted("tax_amount_after_discount_amount", doc)) }}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
{%- if doc.discount_amount and not net_discount -%}
|
{%- if doc.discount_amount and not net_discount -%}
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ Receiver,ผู้รับ
|
|||||||
Issuer,ผู้ออก
|
Issuer,ผู้ออก
|
||||||
Accepted By,ผู้อนุมัติสั่งซื้อ
|
Accepted By,ผู้อนุมัติสั่งซื้อ
|
||||||
Quoted By,ผู้เสนอราคา
|
Quoted By,ผู้เสนอราคา
|
||||||
|
Approved By,ผู้อนุมัติ
|
||||||
|
Prepared By,ผู้จัดทำ
|
||||||
|
Acknowledged By,ผู้รับใบสั่งซื้อ
|
||||||
Tax Invoice,ใบกำกับภาษี
|
Tax Invoice,ใบกำกับภาษี
|
||||||
Tax Invoice/Receipt,ใบกำกับภาษี/ใบเสร็จรับเงิน
|
Tax Invoice/Receipt,ใบกำกับภาษี/ใบเสร็จรับเงิน
|
||||||
"Commission, brokerage, agency fees - Sec. 40(2), juristic payee (P.N.D.53)",ค่านายหน้า ค่าตัวแทน - มาตรา 40(2) ผู้รับเป็นนิติบุคคล (ภ.ง.ด.53)
|
"Commission, brokerage, agency fees - Sec. 40(2), juristic payee (P.N.D.53)",ค่านายหน้า ค่าตัวแทน - มาตรา 40(2) ผู้รับเป็นนิติบุคคล (ภ.ง.ด.53)
|
||||||
@@ -39,6 +42,18 @@ Sec. 40(2)-(6) income paid to non-resident individuals - Sec. 50(2) (P.N.D.3),
|
|||||||
"Dividends to foreign companies not doing business in Thailand - Sec. 70, pre-DTA (P.N.D.54)",เงินปันผลจ่ายให้บริษัทต่างประเทศที่มิได้ประกอบกิจการในประเทศไทย - มาตรา 70 ก่อนใช้อนุสัญญาภาษีซ้อน (ภ.ง.ด.54)
|
"Dividends to foreign companies not doing business in Thailand - Sec. 70, pre-DTA (P.N.D.54)",เงินปันผลจ่ายให้บริษัทต่างประเทศที่มิได้ประกอบกิจการในประเทศไทย - มาตรา 70 ก่อนใช้อนุสัญญาภาษีซ้อน (ภ.ง.ด.54)
|
||||||
Sales Invoice,ใบแจ้งหนี้
|
Sales Invoice,ใบแจ้งหนี้
|
||||||
Sales Order,ใบสั่งขาย
|
Sales Order,ใบสั่งขาย
|
||||||
|
Purchase Invoice,ใบแจ้งหนี้ซื้อ
|
||||||
|
Purchase Order,ใบสั่งซื้อ
|
||||||
|
Required By,วันที่ต้องการรับสินค้า
|
||||||
|
Supplier Invoice No,เลขที่ใบแจ้งหนี้ผู้จัดจำหน่าย
|
||||||
|
Supplier Invoice Date,วันที่ใบแจ้งหนี้ผู้จัดจำหน่าย
|
||||||
|
Customer's Purchase Order,เลขที่ใบสั่งซื้อของลูกค้า
|
||||||
|
Customer's Purchase Order Date,วันที่ใบสั่งซื้อของลูกค้า
|
||||||
|
Contact Name,ชื่อผู้ติดต่อ
|
||||||
|
Contact Mobile No,โทรศัพท์มือถือ
|
||||||
|
Supplier Contact,ผู้ติดต่อ
|
||||||
|
Shipping Address,ที่อยู่จัดส่ง
|
||||||
|
Accepted Qty,จำนวนที่รับ
|
||||||
Posting Date,วันที่
|
Posting Date,วันที่
|
||||||
Payment Due Date,วันครบกำหนดชำระ
|
Payment Due Date,วันครบกำหนดชำระ
|
||||||
Contact Person,ผู้ติดต่อ
|
Contact Person,ผู้ติดต่อ
|
||||||
|
|||||||
|
Reference in new issue
Block a user