Email báo ra ngoài cho khách. Nhưng nhắc nội bộ — "thẻ này hết hạn rồi, ai đó gọi khách gia hạn trong 3 ngày" — thì cần một thứ khác: hoạt động (activity). Đó là một việc-cần-làm gắn thẳng vào bản ghi, có hạn chót và người phụ trách, hiện lên trong khung trao đổi và cả biểu tượng đồng hồ trên thanh hệ thống. Bài này giao một việc như vậy từ code, chỉ với một lời gọi.
Một dòng để giao việc
Điều kiện duy nhất: model phải kế thừa mail.activity.mixin (thẻ đã có — nên view_mode của nó có cả chế độ activity). Khi đó mọi bản ghi có sẵn method activity_schedule:

Hình 1: activity_schedule('mail.mail_activity_data_todo', ...) tạo một hoạt động loại To-Do với hạn chót, tiêu đề, ghi chú và người phụ trách (user_id). Loại hoạt động là external id: mail.mail_activity_data_todo, ..._call, ..._meeting, ..._email. Nếu cần kiểm soát nhiều trường hơn, tạo thẳng mail.activity với res_model_id + res_id. Đọc lại bằng record.activity_ids (recordset) và record.activity_state (planned/today/overdue).
Nó hiện trong chatter, có hạn và người phụ trách
Sau lời gọi, mở form thẻ VIP-0002 là thấy hoạt động nằm ngay trong khung trao đổi:

Hình 2: Hoạt động thật trong chatter thẻ VIP-0002. Odoo tự tính và hiển thị "Đến hạn trong N ngày" từ date_deadline, tên việc, người phụ trách (Administrator), và ghi chú. Ba nút Hoàn tất / Chỉnh sửa / Hủy để nhân viên xử lý ngay. Cùng lúc, việc này còn hiện ở biểu tượng đồng hồ trên thanh hệ thống của người được giao và trong chế độ xem Hoạt động của model — nên không ai bỏ sót.
Kiểm bằng shell cho chắc các trường đã đúng:

Hình 3: activity_schedule trả về bản ghi mail.activity — loại To-Do, hạn 2026-09-20 (hôm nay + 3), giao Administrator. activity_state của thẻ thành planned (chưa tới hạn). Ba nơi cùng phản ánh việc này: chatter, systray, và chế độ xem Hoạt động. Đo xong tôi xoá hoạt động test để giữ thẻ sạch.
Đánh dấu hoàn tất và vài lưu ý
activity_feedback(['mail.mail_activity_data_todo'], feedback='...')đánh dấu hoạt động xong: nó ghi một dòng vào chatter rồi xoá activity khỏi danh sách đang mở. Đây là cách đúng để "đóng" việc từ code, không phảiunlink(unlink chỉ huỷ, không để lại vết).user_idmặc định là người đang chạy code. Muốn giao cho người khác thì truyềnuser_idrõ ràng; giao cho cả nhóm thì cân nhắc tạo nhiều activity.activity_statelà field tính sẵn (planned/today/overdue) — lọc/nhóm được trong view, tiện làm bộ lọc "việc quá hạn".- Đừng lạm dụng. Mỗi activity là một dòng
mail.activityvà một thông báo cho người phụ trách; tạo hàng loạt vô tội vạ (ví dụ trong một cron quét nghìn bản ghi mỗi ngày) sẽ làm ngập systray của nhân viên. Lọc kỹ điều kiện trước khi giao.
Ba ý mang về
record.activity_schedule(type_xmlid, date_deadline, summary, user_id, note)giao một việc-cần-làm gắn vào bản ghi — cần model kế thừamail.activity.mixin. Loại việc là external id (mail.mail_activity_data_todo...).- Hoạt động hiện ở ba nơi: chatter của bản ghi, systray đồng hồ của người phụ trách, và chế độ xem Hoạt động của model;
activity_ids/activity_stateđể đọc lại. - Đóng việc bằng
activity_feedback(ghi vết + xoá khỏi danh sách mở), không phảiunlink; và lọc kỹ điều kiện để không giao việc tràn lan.
Hoạt động và feedback đều đổ vào khung trao đổi của bản ghi. Cái khung đó — chatter — còn là nơi ghi lại mọi thay đổi và trao đổi. Phần sau mổ xẻ message_post — ghi vào chatter từ code: log nội bộ, thông báo cho follower, và khác gì với activity.