Skip to Content

คู่มือ Customize PDF Report ด้วย QWeb ใน Odoo 19 สำหรับ Developer

บทนำ: ทำไม QWeb Report จึงสำคัญ


เอกสาร PDF ใน Odoo ไม่ว่าจะเป็นใบแจ้งหนี้ ใบสั่งขาย ใบรับสินค้า หรือรายงานการผลิต ล้วนสร้างจาก QWeb Templating Engine ทั้งสิ้น สำหรับ developer ที่รับงาน customize Odoo ให้กับลูกค้าไทย การเข้าใจ QWeb อย่างลึกซึ้งเป็นทักษะที่ขาดไม่ได้ บทความนี้ครอบคลุมตั้งแต่โครงสร้างพื้นฐาน ไปจนถึงเทคนิคขั้นสูงสำหรับ PDF report customization ที่ใช้ได้จริงในงาน production


สถาปัตยกรรมของ QWeb Report


QWeb Report ประกอบด้วย 3 ส่วนหลัก ได้แก่ Report Action ที่กำหนดใน XML ผ่าน ir.actions.report เพื่อเชื่อม model กับ template และกำหนดประเภท output เป็น qweb-pdf หรือ qweb-html, QWeb Template ที่เขียนเป็น XML โดยเรียก t-call="web.external_layout" เพื่อดึง layout มาตรฐานที่มี header, footer และ page margin และสุดท้าย Rendering Pipeline ที่ Odoo ใช้แปลง XML template เป็น HTML ก่อน แล้วส่งให้ wkhtmltopdf แปลงเป็น PDF ขั้นตอนนี้มีผลโดยตรงต่อ CSS ที่รองรับได้

XML Tags ที่ต้องรู้


t-field ใช้สำหรับแสดงค่าที่ต้องการ format ตาม locale เช่น สกุลเงิน วันที่ และตัวเลข แนะนำให้ใช้แทน t-esc เสมอเมื่อต้องการ localization ที่ถูกต้อง ตัวอย่างเช่น การใช้ t-field กับ o.amount_total จะแสดงจำนวนเงินพร้อม format ตามสกุลเงินของเอกสารโดยอัตโนมัติ รองรับการใช้ t-options เพื่อระบุ widget เช่น monetary สำหรับแสดงสกุลเงิน


t-out ใช้สำหรับ output ข้อมูลที่อาจมี HTML content โดยไม่ escape ทำให้ render HTML ได้โดยตรง ใน Odoo 19 แนะนำให้ใช้ t-out แทน t-esc ในกรณีที่ต้องการรองรับ rich text content เช่น field ประเภท Html


t-foreach ใช้สำหรับวนซ้ำผ่าน One2many หรือ list เช่น การใช้ t-foreach กับ o.order_line พร้อม t-as="line" เพื่อวนสร้างแถวในตารางสำหรับแต่ละ order line ควรระบุ t-key ที่เป็น unique identifier ในแต่ละรอบเพื่อ performance ที่ดีขึ้น


t-if ใช้สำหรับ conditional rendering เช่น แสดงส่วน withholding tax เฉพาะเมื่อมีการตั้งค่า WHT เท่านั้น ช่วยให้ report ปรับตัวตามข้อมูลแต่ละ document และไม่แสดงส่วนที่ว่างเปล่า


t-call ใช้สำหรับเรียก sub-template มาแทรก เช่น การเรียก web.external_layout เพื่อรับ header และ footer มาตรฐาน หรือ custom component ที่สร้างขึ้นมาใช้ซ้ำในหลาย report


Template Inheritance: วิธีที่ถูกต้องและปลอดภัย


หลักการสำคัญที่สุดคือห้ามแก้ไข core template โดยตรง ให้ใช้ template inheritance ผ่าน inherit_id และ XPath เสมอ เพราะการแก้ไข core จะทำให้ upgrade Odoo ยากและอาจสูญเสียการแก้ไขทั้งหมดได้เมื่อ update module


โครงสร้าง inheritance ที่ถูกต้องคือการระบุ inherit_id ชี้ไปที่ template ต้นทาง แล้วใช้ xpath element เพื่อระบุตำแหน่งที่ต้องการแก้ไขด้วย attr expression ที่เป็น XPath expression และ position ที่กำหนดว่าจะแทรกก่อน หลัง แทนที่ หรือภายใน element ที่ระบุ position options ได้แก่ replace, before, after, inside และ attributes


ตัวอย่าง use case ที่ใช้บ่อยในงานลูกค้าไทย เช่น การเพิ่มช่อง Withholding Tax บนใบแจ้งหนี้ การแสดงเลขที่ใบกำกับภาษีสาขา หรือการเพิ่มลายเซ็นผู้อนุมัติในรายงานสั่งซื้อ ล้วนทำผ่าน inheritance ทั้งสิ้น


การเพิ่ม Custom Field ใน Report


ขั้นตอนมาตรฐานในการเพิ่มข้อมูลใหม่ในรายงานมี 3 ส่วน ได้แก่ เพิ่ม field ใน model ถ้าเป็น field ใหม่, สร้าง template inheritance ที่ชี้ไปตำแหน่งที่ต้องการด้วย XPath, และ render ค่าด้วย t-field หรือ t-out ตามความเหมาะสม สำหรับ computed field ที่ซับซ้อนควรคำนวณผ่าน method ใน model แล้ว expose เป็น field แทนที่จะคำนวณใน template โดยตรง เพื่อให้ template อ่านง่ายและ debug ได้สะดวก


ข้อควรระวังสำหรับ wkhtmltopdf


เนื่องจาก Odoo ใช้ wkhtmltopdf ในการแปลง HTML เป็น PDF ซึ่งใช้ WebKit engine รุ่นเก่า CSS ที่ไม่รองรับ ได้แก่ Flexbox, CSS Grid และ CSS properties สมัยใหม่หลายรายการ ควรทดสอบใน HTML mode ก่อนเสมอโดยเปิด URL report ด้วย ?debug=1 แล้วดู HTML output และใช้ float-based layout หรือ table layout แทน modern CSS layout


สำหรับปัญหา font ภาษาไทย ให้ประกาศ @font-face ใน template style และ copy font file ไว้ใน static directory ของ module ทดสอบทั้งบน Ubuntu server และ Docker container environment เพราะ font path อาจต่างกัน


ในกรณี Odoo Docker deployment ต้องตรวจสอบว่า report.url ใน System Parameters ชี้ไปยัง URL ที่ถูกต้องภายใน container มิฉะนั้น CSS จะไม่โหลดและ PDF จะแสดงผลผิดพลาด ซึ่งเป็นปัญหาที่พบบ่อยในการ deploy Odoo บน Docker และ Odoo.sh


Debug และ Troubleshooting


เทคนิคที่ developer ควรรู้ ได้แก่ เปิด URL report ด้วย parameter ?debug=1 เพื่อดู HTML output ก่อน PDF ซึ่งเร็วกว่าการ render PDF มาก, ใช้ developer mode ใน Odoo เพื่อดู technical name ของ element สำหรับเขียน XPath ที่แม่นยำ และหาก XPath ไม่ตรงให้ตรวจสอบ element name ใน developer mode แทนการเดาจาก label ที่แสดงบน UI


Common issues ที่พบบ่อย ได้แก่ XPath not matching เมื่อ element name เปลี่ยนใน Odoo version ใหม่ซึ่งต้องตรวจสอบใหม่ทุกครั้งที่ upgrade, PDF rendering แตกต่างจาก HTML preview เนื่องจาก CSS ที่ wkhtmltopdf ไม่รองรับ และ empty field display ที่ควร wrap ด้วย t-if ก่อน render เพื่อป้องกัน error เมื่อ field เป็น False


Best Practices สำหรับ Production


ควรเก็บ customization ทั้งหมดไว้ใน dedicated custom module มีโครงสร้าง views/report_*.xml ที่ชัดเจน ทดสอบ inheritance กับ Odoo version ใหม่ก่อน upgrade เสมอ และเขียน unit test สำหรับ computed field ที่ใช้ใน report เพื่อให้มั่นใจว่าข้อมูลที่แสดงถูกต้องตลอดเวลา


สรุปสำหรับ Developer


การ customize QWeb report ใน Odoo 19 ต้องอาศัยการเข้าใจทั้ง XML template structure, XPath inheritance และข้อจำกัดของ wkhtmltopdf ไปพร้อมกัน การยึดหลัก inheritance-first และการทดสอบใน HTML mode ก่อนจะช่วยลดเวลา debug ได้อย่างมาก และทำให้ module ที่พัฒนาสามารถรองรับการ upgrade Odoo ในอนาคตได้อย่างมั่นคง


Reference Links:

- Odoo 19 QWeb Reporting Guide: https://arsalanyasin.com.au/odoo-19-report-custom-qweb-spreadsheet-reports/

- Odoo QWeb Report Customization Developer Guide: https://www.odooskillz.com/blog/odoo-skillz-insights-1/odoo-qweb-report-customization-developer-guide-pdf-reports-invoices-templates-362

- Building Custom Reports in Odoo 19: https://bytelegions.com/build-custom-reports-odoo19-from-basic-to-advanced/


#Odoo #OdooThailand #OdooDeveloper #QWeb #OdooPDF #ERP #Odoo19 #OdooTips

แชร์โพสต์นี้
เก็บถาวร