Bài trước ta gắn một report action vào model. Giờ đi vào chính nội dung — cách viết cái template QWeb vẽ ra trang in. QWeb là ngôn ngữ template của Odoo: HTML thường, cộng vài thuộc tính bắt đầu bằng t-. Chỉ cần nắm năm directive — t-field, t-esc, t-if/t-else, t-foreach, t-set — là bạn dựng được một trang in có bảng, vòng lặp, và cả dòng tổng cộng tự tính. Bài này thêm một bảng lịch sử điểm vào report thẻ thành viên.
Năm directive cốt lõi

Hình 1: Năm directive. t-field in một field và tự format theo kiểu (ngày → dd/mm/yyyy). t-esc in một biểu thức Python thô. t-if/t-else rẽ nhánh. t-foreach/t-as lặp một recordset (có sẵn biến ls và chỉ số ls_index). t-set/t-value đặt/cộng một biến ngay trong template — dùng để cộng dồn tổng.
Vài điểm đáng nhớ:
t-fieldvst-esc:t-fieldcần một field thật để biết cách format (ngày, tiền, selection ra nhãn);t-escin bất kỳ biểu thức nào nhưng không format — hợp cho số tính toán, chuỗi ghép.t-setcộng dồn: đặttong=0trước vòng lặp, mỗi vòngt-set tong t-value="tong + ...". Sau vòng lặp,tonglà tổng — in bằngt-esc.- Class Bootstrap có sẵn:
table,table-sm,table-bordered,text-end... dùng thẳng để bảng đẹp mà không cần CSS riêng.
Kết quả: bảng lịch sử có tổng
Thêm khối trên vào template, render report cho thẻ VIP-0001 (có 3 dòng lịch sử):

Hình 2: Report render đầy đủ. Mục "Lịch sử tích điểm" là bảng do t-foreach vẽ: mỗi dòng lịch sử một hàng (t-field cho ngày/điểm/ghi chú). Dòng cuối "Tổng cộng 120" là biến tong cộng dồn qua vòng lặp (40+50+30) rồi t-esc. Nếu thẻ chưa có lịch sử, t-else sẽ hiện "Chưa có lịch sử tích điểm" thay vì bảng rỗng.
Đây là sức mạnh của QWeb: cùng một template chạy cho mọi thẻ, tự lặp đúng số dòng lịch sử của từng thẻ, tự tính tổng — không cần biết trước có bao nhiêu dòng.
Mẹo viết và soi template
- Xem bản HTML để chỉnh nhanh: mở
/report/html/<report_name>/<id>(ví dụ/report/html/quan_ca_phe.report_the_document/1) thấy ngay kết quả, không cần dựng PDF. Lỗi template hiện rõ ở HTML. t-ifcho tập rỗng: luôn nghĩ tới trường hợp không có dòng con —t-elsebáo "chưa có" đẹp hơn một bảng trống.- Đừng nhồi logic nặng vào template: tính toán phức tạp nên làm ở model (compute field) rồi chỉ
t-fieldra; QWeb hợp cho lặp/rẽ nhánh trình bày, không phải nơi viết nghiệp vụ. ls_index(vàls_first,ls_last):t-foreachcấp sẵn chỉ số và cờ đầu/cuối, hữu ích để đánh số dòng hay tô màu xen kẽ.
Ba ý mang về
- Năm directive QWeb dựng nên trang in:
t-field(in + tự format),t-esc(in biểu thức thô),t-if/t-else(rẽ nhánh),t-foreach/t-as(lặp recordset),t-set/t-value(đặt/cộng biến). t-foreach+t-setcho bảng có tổng: lặp dòng con, cộng dồn một biến qua các vòng, in tổng bằngt-escsau vòng lặp; dùng class Bootstrap (table) cho bảng đẹp sẵn.- Soi bằng
/report/html/..., xử lý tập rỗng bằngt-else, giữ logic nặng ở model — template QWeb là nơi trình bày, không phải nơi viết nghiệp vụ.
Nội dung report đã đẹp. Nhưng nó đang in trên khổ A4 mặc định — nếu muốn khổ khác, lề khác thì sao? Phần sau về paperformat — khai khổ giấy, hướng dọc/ngang, lề, và gán cho report để bản in ra đúng kích thước mong muốn.