Mở một đơn hàng, một hoá đơn, một phiếu nghỉ phép trong Odoo — góc trên bên phải luôn có một dải các bước: Nháp → Đã xác nhận → Hoàn tất, với bước hiện tại được tô sáng. Dải đó tên là statusbar, và nó chỉ là một field Selection được hiển thị bằng một widget đặc biệt. Nó biến một field trạng thái khô khan thành một quy trình mà người dùng nhìn phát biết đang ở đâu. Bài này biến field trang_thai của thẻ thành viên thành statusbar và xem nó chạy.
Field Selection + widget statusbar
statusbar cần hai thứ: một field Selection (các bước) và widget statusbar đặt trong <header>:
# Model: field Selection các bước quy trình
trang_thai = fields.Selection([
('moi', 'Mới cấp'), ('dang_dung', 'Đang dùng'),
('het_han', 'Hết hạn'), ('khoa', 'Đã khoá')], default='moi')
<header>
<button name="action_gia_han" type="object" string="Gia hạn thẻ"/>
<field name="trang_thai" widget="statusbar"
statusbar_visible="moi,dang_dung,het_han" <!-- các bước LUÔN hiện -->
options="{'clickable': '1'}"/> <!-- cho bấm để chuyển -->
</header>

Hình 1: Cấu tạo statusbar. Field trang_thai là Selection bình thường; widget="statusbar" trong <header> biến nó thành dải bước. statusbar_visible liệt kê các bước luôn hiện (moi,dang_dung,het_han); bước không liệt kê (khoa) chỉ hiện khi đang ở đó rồi ẩn — hợp cho trạng thái ngoại lệ. options="{'clickable': '1'}" cho người dùng bấm thẳng vào bước để chuyển.
Xem thật: quy trình ở đầu form
Đặt statusbar vào header và mở thẻ VIP-0003 (đang ở "Đang dùng"):

Hình 2: statusbar chạy thật. Dải "Mới cấp → Đang dùng → Hết hạn" nằm góc phải header; bước "Đang dùng" được tô sáng (dạng mũi tên tím) vì thẻ đang ở trạng thái đó. Người dùng nhìn phát biết thẻ đang ở đâu trong vòng đời. Trạng thái "Đã khoá" không hiện ở đây (không nằm trong statusbar_visible) — nó chỉ xuất hiện khi thẻ thực sự bị khoá.
Nhờ clickable, người dùng có thể bấm thẳng vào "Hết hạn" để chuyển trạng thái — hoặc dùng nút quy trình (như "Gia hạn thẻ") để chuyển kèm logic. Hai cách bổ trợ nhau.
statusbar_visible: giấu bước ngoại lệ
Đây là điểm tinh tế hay bị bỏ qua. Một quy trình thường có luồng chính (nháp → xác nhận → xong) và vài trạng thái ngoại lệ (huỷ, khoá). Bạn muốn dải bước chỉ hiện luồng chính cho gọn, còn trạng thái ngoại lệ chỉ hiện khi đang ở đó:
- Liệt kê luồng chính trong
statusbar_visible→ luôn hiện, thành các bước cố định. - Không liệt kê trạng thái ngoại lệ → nó chỉ hiện khi bản ghi thực sự ở đó, xong thì ẩn.
Ví dụ ở đây: moi,dang_dung,het_han là luồng chính; khoa không liệt kê nên chỉ hiện khi thẻ bị khoá. Nhờ vậy dải bước không bị rối bởi mọi trạng thái có thể có.
Kết hợp statusbar với nút quy trình
Trong thực tế, statusbar hiếm khi đứng một mình — nó đi cùng nút (xem bài nút):
- Nút chạy logic khi chuyển trạng thái (kiểm điều kiện, cộng điểm, gửi mail) rồi
writetrạng thái mới. - statusbar hiển thị trạng thái và (nếu
clickable) cho chuyển nhanh những bước không cần logic.
Mẫu điển hình: nút "Xác nhận" (có logic) + statusbar hiện luồng. Người dùng bấm nút cho bước quan trọng, bấm statusbar cho bước đơn giản.
Vài lưu ý Odoo 19
- statusbar đặt trong
<header>, thường góc phải (Odoo tự căn). clickablecho bấm chuyển thẳng — cẩn thận: nó bỏ qua logic nút, nên chỉ bật khi chuyển bước không cần kiểm gì.statusbar_visibledùng tên kỹ thuật của các giá trị (không phải nhãn), ngăn cách bằng dấu phẩy.- Field Selection động (sinh từ method) vẫn dùng statusbar được, miễn các giá trị ổn định.
- Với quy trình phức tạp nhiều nhánh, cân nhắc field
statechuẩn +tracking=Trueđể chatter ghi lại mỗi lần đổi (bài sau).
Ba ý mang về
- statusbar biến một field Selection thành dải bước quy trình ở đầu form:
widget="statusbar"trong<header>, bước hiện tại tô sáng. Đã chứng minh: "Mới cấp → Đang dùng → Hết hạn" với "Đang dùng" sáng. statusbar_visible="a,b,c"liệt kê luồng chính luôn hiện; trạng thái ngoại lệ (nhưkhoa) không liệt kê thì chỉ hiện khi đang ở đó — giữ dải bước gọn.options="{'clickable': '1'}"cho bấm chuyển thẳng; kết hợp với nút quy trình (nút chạy logic + write, statusbar hiển thị) là mẫu chuẩn.
statusbar hiển thị trạng thái, nhưng ai đã đổi và khi nào? Đó là việc của khung trao đổi bên phải form: Phần sau mổ xẻ chatter — gắn mail.thread lên form để có lịch sử thay đổi, ghi chú, và trao đổi ngay trên bản ghi.