Developer Logs

Print report ทั้งที ขอเก็บเป็นไฟล์เอาไว้ด้วยสิ ? (built-in function)

odoo
Reporting
Programming
Python

สั่ง print report แต่ก็อยากให้เก็บเป็นไฟล์แนบเอาไว้ด้วย ? (built-in function)

Days: 2 | Publish : 19/01/2025

odoo pdf report with attachment on records with built-in function

Print report ทั้งที ขอเก็บเป็นไฟล์เอาไว้ด้วยสิ ? (built-in function)

จากปัญหาก่อนหน้านี้ Print report ทั้งที ขอเก็บเป็นไฟล์เอาไว้ด้วยสิ ?
ที่จะต้อง print pdf แล้วก็มี attachment ด้วย
ก็เลยเป็นโอกาสที่ได้ไป find out มาเพิ่มว่าแท้จริงแล้ว
ตัว odoo ที่เป็น core function ก็สามารถทำเรื่องนี้ได้ดีมากพอสมควรแล้ว

.

วันนี้เลยอยากพาไปดูกันว่า การใช้งาน attachment on records เนี่ย
มันทำอะไรได้บ้าง แล้วถ้าจะเอาไปใช้งาน เราจะ implement ไปถึงประมาณไหน


แต่ถ้าจะมาจบอยู่แค่ การ config แค่นั้นก็จะไม่สาแก่ใจสักเท่าไร
เพราะฉะนั้น ผมจะขอเพิ่มส่วนของ coding แทรกเข้าไปด้วย
เพื่อเพิ่มความสามารถที่ทำได้ให้ตอบโจทย์ที่หลากหลายได้มากขึ้น

.

อืม… แล้วไอเจ้า attachment on records ที่ติดมากับ core function เนี่ย
มันทำอะไรได้บ้างนะ ??

.

ลุยยยยยยยยยย

อันแรกสุดที่เชื่อว่าทุกคนคุ้นเคยกันอยู่แล้ว ก็ตรงเมนู print นี่แหละ
ซึ่งในที่นี้ก็จะเห็นได้ว่า เราสามารถ print ได้ทั้งหมด 2 reports
คือ PDF Quote กับ Quotation / Order

odoo print function

แต่ๆ ๆ …
เรายังสามารถทำให้มันล้ำไปมากกว่านี้ได้อีก คือ ให้เราเข้าไป config ที่
เมนู Settings -> Technical -> Reports (เปิด debug ก่อนด้วย)

odoo tree view sale order

แล้วเราจะเห็นหน้าสำหรับ config report หน้าตาประมาณด้านบนนี้
ซึ่ง ณ ตอนนี้ จุดที่ผมสนใจจะเป็น report ที่อยู่ใน model sale.order

.

odoo reports config with object name

หลังจากนั้นให้มาที่ Advanced Properties tab
จะเห็นว่าเราจะสามารถเซ็ตให้มัน generate ออกมาเป็น attachment ได้ด้วยที่นี่เลย
ซึ่งในที่นี้ ผมจะต้องการให้ไฟล์เป็นชื่อเดียวกับชื่อ record
เราก็จะมาใส่ในช่อง Save as Attachment Prefix ให้เป็น format ตามนี้
object.name ซึ่ง name ก็คือให้ดึง field ที่ชื่อว่า name มาเป็น prefix ของไฟล์นั่นเอง

.

และเมื่อกลับไปสั่ง print ไฟล์ที่หน้าจอเดิม (sale.order)
เราก็จะเห็นว่ามันจะเกิด attachment ไฟล์แนบเข้ามาที่ records ที่เราต้องการโดยอัตโนมัติ

odoo show attachment after config

และถ้าลองสั่ง print ซ้ำ ๆ ดู ก็จะพบว่า
ไม่ว่าเราจะสั่ง print สักกี่ครั้ง มันก็จะยังออกมาเป็นแค่ 1 ไฟล์เท่านั้นไม่มีอะไรเปลี่ยนแปลง

ซึ่งไฟล์ก็จะยังเป็นไฟล์เก่าอยู่ด้วย (ทดสอบได้ด้วยการลองเปลี่ยนข้อมูลแล้วสั่ง print ซ้ำ)
เนื่องจากตัวระบบมองว่ามีไฟล์นี้อยู่แล้ว ไม่ต้องสร้างใหม่ให้
ก็จะข้าม process ในการสร้าง attachment file ไป
** แต่ไฟล์ที่เรากดแล้วได้รับ download file มา จะเป็นข้อมูลในปัจจุบันแล้วนะ

ตรงนี้ก็ค่อนข้าง Tricky นิดนึง ถ้าใครจะเอา feature นี้ไปใช้ ก็อย่าลืมคิดถึงในส่วนนี้กันด้วย

.

ทีนี้ ด้วยความที่ชื่อของเรามันซ้ำกันทุกครั้งที่มีการ print ใช่มั้ยครับ
จะทำยังไงไม่ให้ซ้ำได้บ้างล่ะ ???


Solution

ก็เอาเวลาเข้ามาเกี่ยวข้องในชื่อซะเลยสิ
จะได้มีเงื่อนไขอะไรสักอย่างที่ทำให้มัน Unique ได้

.

ทีนี้พอเป็นเงื่อนไขของเวลา
เราก็จะมีอยู่ประมาณสัก 2 ทางเลือกที่พอจะเป็นไปได้ในเงื่อนไขนี้

- ใช้เวลาเป็นเวลาปัจจุบัน
- ใช้เป็น datetime เมื่อมีการ edit file เกิดขึ้น

.

1. Stamp เวลาปัจจุบัน

ถ้าเราจะใช้เป็นเวลาปัจจุบัน Format ก็จะเป็นตามนี้


"%s_%s" % (object.name, time.strftime("%Y-%m-%d_%H-%M-%S"))

odoo reports config name and current time

ซึ่งถ้าไปดูเมื่อเราสั่ง print เอกสาร จะมีการแปะ datetime ปัจจุบันติดมาด้วยแล้ว

odoo attachment with current time stamp


2. Stamp เวลาเมื่อมีการแก้ไขไฟล์

ถัดมาเป็น Approach ที่เราจะใช้เงื่อนไขของ core function เข้ามาร่วมด้วย
ทุก ๆ ครั้งที่มีการ edit record เกิดขึ้น …
ตัว odoo เองจะมีการ stamp datetime เก็บไว้ด้วยทุกครั้ง
โดยจะเก็บไว้ใน field ที่ชื่อ write_date

.

เพราะฉะนั้นเราจะ adapt เอาเรื่องนี้เข้ามาใช้กับไฟล์ของเรา
ก็จะได้โค้ดหน้าตาประมาณนี้…


"%s_%s" % (object.name, object.write_date.strftime("%Y-%m-%d_%H-%M-%S"))

odoo reports config name and write date field

ซึ่งถ้าตามเงื่อนไขก่อนหน้านี้ จะเป็นการสั่ง print ใหม่ทุก ๆ ครั้ง
แต่ถ้าเปลี่ยนมาเป็นเงื่อนไขนี้ ถ้าไม่มีการเปลี่ยนแปลงอะไรเกิดขึ้นที่ไฟล์
ก็จะไม่มีไฟล์ใหม่เกิดขึ้น เมื่อมีการสั่ง print

.
.
.

ในบทความนี้ก็จะเป็นการแนะนำการ adapt ใช้ core function
เพิ่มการ config เพิ่มนิดหน่อย เพื่อให้ตอบโจทย์ที่หลากหลายมากขึ้น

.

แต่ในความง่าย ที่เราสามารถ config ผ่านหน้าระบบได้โดยไม่ต้อง coding ใด ๆ
ก็ยังจะมีข้อจำกัดอยู่บ้างในบางกรณี ที่เราอาจจะไม่สามารถ implement ให้ตอบโจทย์ได้


Takeaway

จะเห็นได้ว่าถ้าเราลองเล่นตัวระบบ ให้หลากหลายฟังก์ชันมากขึ้น
ผสมกับเทคนิคในฝั่ง programming เพิ่มเติมเล็กน้อย
ก็จะได้ความยืดหยุ่นเพิ่มขึ้นอีกพอสมควร

หลาย ๆ ครั้งก็พอจะลดเวลาที่จะต้อง implement ไปได้อีกพอประมาณ

ซึ่งถ้าในมุมของ developer การรู้ส่วนของ functional เพิ่มเติม
บางฟังก์ชัน ก็อาจจะช่วยลดเวลาชีวิต ลดความยุ่งยากของเราไปได้เยอะอยู่เหมือนกันนะครับ

.

แล้วเพื่อน ๆ มีฟังก์ชันอะไรเด็ด ๆ ที่รู้สึกว่าปลดล๊อคความง่ายให้ตัวเองเพิ่มขึ้นกันบ้างมั้ย ? แชร์กันได้นะคร้าบบบ