จากภาพหน้าจอจริงที่บันทึกมาจากระบบ:
| ตำแหน่ง | สภาพปัจจุบัน (As-Is) | เป้าหมายที่ต้องการ (To-Be) |
|---|---|---|
| Menu Path | Accounting > Reporting > Management > Invoice Analysis |
ตำแหน่งเดิมในการเข้าถึงรายงาน |
| Pivot View Grouping | กด Add Custom Group มีเฉพาะฟิลด์มาตรฐาน เช่น Company, Currency, Country, Due Date, Move, Move Type... | เพิ่มตัวเลือก Project Name (และ/หรือ Project) ให้สามารถเลือกจัดกลุ่มยอดขายตามโครงการได้ทันที |
| Data Source Model | account.move มีฟิลด์ project_name แล้ว แต่ account.invoice.report ยังไม่มี |
เชื่อมโยงดึง move.project_name เข้าสู่ account.invoice.report อย่างสมบูรณ์ |
ใน Odoo กลไกการแสดงฟิลด์ในปุ่ม "Add Custom Group" ของหน้า Pivot / Graph / Search View มีหลักการทำงานดังนี้:
หน้าสร้าง Invoice ทำงานบนโมเดล account.move ซึ่งโมดูล yell_account_ext ได้ประกาศฟิลด์ project_name ไว้เรียบร้อยแล้ว แต่หน้าจอ Invoice Analysis ทำงานบนโมเดลวิเคราะห์ข้อมูลเฉพาะคือ account.invoice.report
โมเดล account.invoice.report เป็นตาราง View เสมือนใน PostgreSQL สร้างจากคำสั่ง SQL SELECT ... FROM ... ไม่ใช่ตารางจริง หากไม่มีการเขียนคำสั่ง SQL ดึงคอลัมน์ project_name มารองรับ Odoo จะมองไม่เห็นฟิลด์นี้
เมื่อผู้ใช้คลิก "Add Custom Group" ฝั่ง Web Client จะยิงคำสั่ง fields_get() ไปยังเซิร์ฟเวอร์เพื่อขอรายชื่อฟิลด์ทั้งหมดของโมเดลรายงาน เมื่อในโมเดลไม่มีฟิลด์นี้ จึงไม่ถูกนำมาแสดงในดรอปดาวน์
ฟิลด์ project_name มีอยู่ใน "ใบแจ้งหนี้" (account.move) แต่ยังไม่ได้ถูกเพิ่มเข้าไปใน "กระดานรายงานวิเคราะห์" (account.invoice.report) จึงทำให้ระบบไม่สามารถนำมาใช้จัดกลุ่ม (Group By) ได้
การแก้ไขทำได้ง่ายและตรงไปตรงมา โดยการสืบทอดโมเดล (Inherit) account.invoice.report ในโมดูลเดิมที่มีอยู่แล้ว เช่น yell_account_ext โดยมี 4 ขั้นตอนหลักดังนี้:
สร้างไฟล์ Python เช่น models/account_invoice_report.py เพื่อเพิ่มฟิลด์ลงในโมเดลรายงาน พร้อมกำหนด readonly=True:
from odoo import fields, models
class AccountInvoiceReport(models.Model):
_inherit = 'account.invoice.report'
# 1. เพิ่มฟิลด์ project_name (ข้อความ) ตามที่ผู้ใช้ต้องการ
project_name = fields.Char(
string='Project Name',
readonly=True,
)
# 2. แนะนำเพิ่มเติม: ฟิลด์ project_id (Relational Many2one) เพื่อการจัดกลุ่มที่แม่นยำ
project_id = fields.Many2one(
comodel_name='project.project',
string='Project',
readonly=True,
)
def _select(self):
# ดึงข้อมูล project_name และ project_id จากตาราง account_move (alias: move)
select_str = super()._select()
select_str += ", move.project_name AS project_name, move.project_id AS project_id"
return select_str
แม้ว่าการเพิ่มฟิลด์ใน Python จะทำให้ฟิลด์โผล่ใน "Add Custom Group" อัตโนมัติแล้ว แต่เพื่อความสะดวกสูงสุดของผู้ใช้งาน ไม่ต้องเสียเวลากดเลือกดรอปดาวน์ทุกครั้ง ควรเพิ่มปุ่มลัดในแท็บ Group By โดยตรง:
xml: views/account_invoice_report_views.xml<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_account_invoice_report_search_inherit_project" model="ir.ui.view">
<field name="name">account.invoice.report.search.inherit.project</field>
<field name="model">account.invoice.report</field>
<field name="inherit_id" ref="account.view_account_invoice_report_search"/>
<field name="arch" type="xml">
<xpath expr="//group" position="inside">
<filter string="Project Name" name="group_by_project_name" context="{'group_by': 'project_name'}"/>
<filter string="Project" name="group_by_project" context="{'group_by': 'project_id'}"/>
</xpath>
</field>
</record>
</odoo>
models/__init__.py: from . import account_invoice_report__manifest__.py ภายใต้ 'data': ['views/account_invoice_report_views.xml', ...]เนื่องจากเป็นตาราง SQL View ใน Database จะต้องสั่ง Upgrade โมดูลเพื่อให้ Odoo รันคำสั่ง CREATE OR REPLACE VIEW account_invoice_report ใหม่:
odoo-bin -c /etc/odoo/odoo.conf -u yell_account_ext -d yell-main --stop-after-init
ตามที่ผู้ใช้ร้องขอให้ประเมินผลกระทบต่อส่วนต่างๆ ของระบบอย่างละเอียด ทีมงานได้วิเคราะห์ผลกระทบใน 5 มิติดังนี้:
ไม่มีผลกระทบใดๆ ทั้งสิ้น: โมเดล account.invoice.report ทำหน้าที่เป็นเพียงกระดานอ่านข้อมูล (Read-Only) สำหรับกราฟและตาราง ไม่ได้มีส่วนเกี่ยวข้องกับการ Post ใบแจ้งหนี้, การกระทบยอด (Reconciliation), การรับชำระเงิน หรือการลงสมุดบัญชีรายวัน
ปลอดภัยสูงมาก: ตาราง account_move มีการเชื่อม (JOIN) อยู่ใน SQL View ของ account.invoice.report อยู่แล้วแต่เดิม การเพิ่มเพียง move.project_name เข้าไปใน SELECT จึงเป็นการอ่านคอลัมน์ที่มีอยู่แล้ว ไม่มีการสร้าง Join ข้ามตารางใหม่ จึงไม่มีผลต่อความเร็วของระบบ
ไม่กระทบรายงานเดิม: การเพิ่มฟิลด์ใหม่ไม่กระทบกับตัวกรอง (Filters), Favorites หรือ Custom Dashboards ที่ผู้ใช้งานคนอื่นสร้างไว้เดิม เนื่องจากไม่มีการเปลี่ยนชื่อหรือลบฟิลด์เดิมออก
ผลของการจัดกลุ่ม: สำหรับใบแจ้งหนี้ในอดีตที่ไม่ได้เลือก Project เอาไว้ (project_id = False) ค่าของ project_name จะเป็นค่าว่าง (NULL) ซึ่งเมื่อกด Group By ใน Pivot View ระบบจะจัดเรคคอร์ดเหล่านี้ไปอยู่ในกลุ่ม "Undefined" ซึ่งเป็นพฤติกรรมมาตรฐานที่ถูกต้องของ Odoo
ข้อควรระวังของ Dev: ในการเขียน SQL ของ _select() ต้องมั่นใจว่าใส่เครื่องหมายจุลภาค (Comma ,) คั่นถูกต้อง หากไวยากรณ์ SQL ผิดพลาด ฐานข้อมูลจะไม่สามารถสร้าง View ได้ และจะส่งผลให้หน้าจอ Invoice Analysis เกิด Error จนกว่าจะแก้ไวยากรณ์และ Upgrade อีกครั้ง
เมื่อนำแนวทางนี้ไปมอบหมายให้ทีม Developer พัฒนาเสร็จสิ้น สามารถใช้ Checklist 6 ข้อนี้ในการตรวจรับงานได้ทันที:
Accounting > Reporting > Invoice Analysis แล้วหน้าจอ Pivot View โหลดข้อมูลขึ้นตามปกติ ไม่มีหน้าต่าง Error สีแดงCustomers > Invoices ได้อย่างราบรื่นตามเดิม