Mixins và các lớp hữu ích

SoOn triển khai một số lớp và mixin hữu ích giúp bạn dễ dàng thêm các hành vi thường dùng vào đối tượng của mình. Hướng dẫn này sẽ trình bày chi tiết hầu hết chúng, kèm theo các ví dụ và trường hợp sử dụng.

Tính năng nhắn tin

Tích hợp tin nhắn

Hệ thống nhắn tin cơ bản

Việc tích hợp các tính năng nhắn tin vào mô hình của bạn cực kỳ dễ dàng. Chỉ cần kế thừa mô hình mail.thread và thêm các trường nhắn tin (và các tiện ích thích hợp của chúng) vào chế độ xem biểu mẫu của bạn sẽ giúp bạn thiết lập và chạy ngay lập tức.

Example

Hãy tạo một mô hình đơn giản thể hiện một chuyến công tác. Vì việc tổ chức loại chuyến đi này thường có nhiều người và nhiều cuộc thảo luận nên hãy thêm tính năng hỗ trợ trao đổi tin nhắn trên mô hình.

class BusinessTrip(models.Model):
    _name = 'business.trip'
    _inherit = ['mail.thread']
    _description = 'Business Trip'

    name = fields.Char()
    partner_id = fields.Many2one('res.partner', 'Responsible')
    guest_ids = fields.Many2many('res.partner', 'Participants')

Trong chế độ xem biểu mẫu:

<record id="business_trip_form" model="ir.ui.view">
    <field name="name">business.trip.form</field>
    <field name="model">business.trip</field>
    <field name="arch" type="xml">
        <form string="Business Trip">
            <!-- Your usual form view goes here
            ...
            Then comes chatter integration -->
            <div class="oe_chatter">
                <field name="message_follower_ids" widget="mail_followers"/>
                <field name="message_ids" widget="mail_thread"/>
            </div>
        </form>
    </field>
</record>

Sau khi bạn đã thêm hỗ trợ trò chuyện trên mô hình của mình, người dùng có thể dễ dàng thêm tin nhắn hoặc ghi chú nội bộ vào bất kỳ bản ghi nào trong mô hình của bạn; mỗi người trong số đó sẽ gửi thông báo (đến tất cả những người theo dõi để nhận tin nhắn, tới người dùng nhân viên (base.group_user) để nhận ghi chú nội bộ). Nếu cổng thư và địa chỉ nhận toàn bộ thư của bạn được định cấu hình chính xác, những thông báo này sẽ được gửi qua e-mail và có thể được trả lời trực tiếp từ ứng dụng thư của bạn; hệ thống định tuyến tự động sẽ định tuyến câu trả lời đến đúng chuỗi.

Phía máy chủ, có một số chức năng trợ giúp để giúp bạn dễ dàng gửi tin nhắn và quản lý người theo dõi trong hồ sơ của bạn:

Đăng tin nhắn

message_post(self, body='', subject=None, message_type='notification', subtype=None, parent_id=False, attachments=None, **kwargs)

Đăng một tin nhắn mới trong một chuỗi hiện có, trả về ID mail.message mới.

Tham số
  • body (str | Markup) -- nội dung của tin nhắn. Sẽ được thoát nếu str. Sử dụng đối tượng Markup cho nội dung HTML.

  • message_type (str) -- xem trường mail_message.message_type

  • parent_id (int) -- xử lý việc trả lời tin nhắn trước đó bằng cách thêm đối tác chính vào tin nhắn trong trường hợp thảo luận riêng tư

  • attachments (list(tuple(str,str))) -- danh sách các bộ dữ liệu đính kèm ở dạng (tên,nội dung), trong đó nội dung KHÔNG được mã hóa base64

  • body_is_html (bool) -- cho biết liệu body có nên được coi là HTML hay không, ngay cả khi str.

  • **kwargs -- đối số từ khóa bổ sung sẽ được sử dụng làm giá trị cột mặc định cho bản ghi mail.message mới

Trả về

ID của mail.message mới được tạo

Kiểu trả về

int

message_post_with_view(views_or_xmlid, **kwargs):

Phương thức trợ giúp để gửi thư/đăng tin nhắn bằng view_id để hiển thị bằng công cụ ir.qweb. Phương pháp này độc lập vì không có gì trong mẫu và trình soạn thảo cho phép xử lý các chế độ xem theo lô. Phương pháp này có thể sẽ biến mất khi các mẫu xử lý chế độ xem ir ui.

Tham số

record (str or ir.ui.view) -- id bên ngoài hoặc bản ghi của chế độ xem sẽ được gửi

message_post_with_template(template_id, **kwargs)

Phương pháp trợ giúp để gửi thư có mẫu

Tham số
  • template_id -- id của mẫu cần hiển thị để tạo nội dung thư

  • **kwargs -- tham số để tạo trình hướng dẫn mail.compose.message (kế thừa từ mail.message)

Nhận tin nhắn

Các phương thức này được gọi khi một e-mail mới được xử lý bởi cổng thư. Những e-mail này có thể là chuỗi mới (nếu chúng đến qua alias) hoặc đơn giản là trả lời từ một chuỗi hiện có. Việc ghi đè chúng cho phép bạn đặt các giá trị trên bản ghi của chuỗi tùy thuộc vào một số giá trị từ chính email đó (tức là cập nhật ngày hoặc địa chỉ email, thêm địa chỉ của CC làm người theo dõi, v.v.).

message_new(msg_dict, custom_values=None)

Được gọi bởi message_process khi nhận được một tin nhắn mới cho một mô hình luồng nhất định, nếu tin nhắn đó không thuộc về một luồng hiện có.

Hành vi mặc định là tạo bản ghi mới của mô hình tương ứng (dựa trên một số thông tin rất cơ bản được trích xuất từ thông báo). Hành vi bổ sung có thể được thực hiện bằng cách ghi đè phương pháp này.

Tham số
  • msg_dict (dict) -- một bản đồ chứa chi tiết email và tệp đính kèm. Xem message_processmail.message.parse để biết chi tiết

  • custom_values (dict) -- từ điển tùy chọn gồm các giá trị trường bổ sung cần chuyển tới create() khi tạo bản ghi luồng mới; hãy cẩn thận, những giá trị này có thể ghi đè bất kỳ giá trị nào khác đến từ thông báo

Kiểu trả về

int

Trả về

id của đối tượng luồng mới được tạo

message_update(msg_dict, update_vals=None)

Được gọi bởi message_process khi nhận được tin nhắn mới cho chuỗi hiện có. Hành vi mặc định là cập nhật bản ghi với update_vals được lấy từ email đến.

Hành vi bổ sung có thể được thực hiện bằng cách ghi đè phương pháp này.

Tham số
  • msg_dict (dict) -- bản đồ chứa chi tiết email và tệp đính kèm; xem message_processmail.message.parse() để biết chi tiết.

  • update_vals (dict) -- một lệnh chứa các giá trị để cập nhật các bản ghi có id của chúng; nếu lệnh là Không có hoặc không có giá trị thì không có thao tác ghi nào được thực hiện.

Trả về

True

Quản lý người theo dõi

message_subscribe(partner_ids=None, channel_ids=None, subtype_ids=None, force=True)

Thêm đối tác vào người theo dõi hồ sơ.

Tham số
  • partner_ids (list(int)) -- ID của các đối tác sẽ được đăng ký vào hồ sơ

  • channel_ids (list(int)) -- ID của các kênh sẽ được đăng ký vào bản ghi

  • subtype_ids (list(int)) -- ID của các loại phụ mà các kênh/đối tác sẽ đăng ký (mặc định là các loại phụ mặc định nếu Không )

  • force -- nếu Đúng, hãy xóa những người theo dõi hiện có trước khi tạo người theo dõi mới bằng cách sử dụng các kiểu con được cung cấp trong tham số

Trả về

Thành công thất bại

Kiểu trả về

bool

message_unsubscribe(partner_ids=None, channel_ids=None)

Xóa đối tác khỏi những người theo dõi hồ sơ.

Tham số
  • partner_ids (list(int)) -- ID của các đối tác sẽ được đăng ký vào hồ sơ

  • channel_ids (list(int)) -- ID của các kênh sẽ được đăng ký vào bản ghi

Trả về

True

Kiểu trả về

bool

message_unsubscribe_users(user_ids=None)

Trình bao bọc trên message_subscribe, sử dụng user.

Tham số

user_ids (list(int)) -- ID của người dùng sẽ bị hủy đăng ký bản ghi; nếu Không, thay vào đó hãy hủy đăng ký người dùng hiện tại.

Trả về

True

Kiểu trả về

bool

Ghi nhật ký thay đổi

Mô-đun mail bổ sung hệ thống theo dõi mạnh mẽ trên các trường, cho phép bạn ghi nhật ký các thay đổi đối với các trường cụ thể trong cuộc trò chuyện của bản ghi. Để thêm theo dõi vào một trường, chỉ cần đặt thuộc tính theo dõi thành True.

Example

Hãy cùng theo dõi những thay đổi về tên gọi và trách nhiệm chuyến công tác của chúng ta:

class BusinessTrip(models.Model):
    _name = 'business.trip'
    _inherit = ['mail.thread']
    _description = 'Business Trip'

    name = fields.Char(tracking=True)
    partner_id = fields.Many2one('res.partner', 'Responsible',
                                 tracking=True)
    guest_ids = fields.Many2many('res.partner', 'Participants')

Từ giờ trở đi, mỗi lần thay đổi tên chuyến đi hoặc người chịu trách nhiệm sẽ ghi vào hồ sơ. Trường tên cũng sẽ được hiển thị trong thông báo để cung cấp thêm ngữ cảnh về thông báo (ngay cả khi tên không thay đổi).

Tiểu loại

Các loại phụ cung cấp cho bạn quyền kiểm soát chi tiết hơn đối với tin nhắn. Các loại phụ hoạt động như một hệ thống phân loại thông báo, cho phép người đăng ký tài liệu tùy chỉnh loại thông báo phụ mà họ muốn nhận.

Các kiểu con được tạo dưới dạng dữ liệu trong mô-đun của bạn; mô hình có các trường sau:

name (bắt buộc) - Char

tên của loại phụ, sẽ được hiển thị trong cửa sổ bật lên tùy chỉnh thông báo

description - Char

mô tả sẽ được thêm vào trong thông báo được đăng cho loại phụ này. Nếu trống, tên sẽ được thêm vào thay thế

internal - Boolean

các tin nhắn có loại phụ nội bộ sẽ chỉ được hiển thị bởi nhân viên, hay còn gọi là thành viên của nhóm base.group_user

parent_id - Many2one

liên kết các kiểu con để đăng ký tự động; ví dụ: các kiểu con dự án được liên kết với các kiểu con nhiệm vụ thông qua liên kết này. Khi ai đó đăng ký vào một dự án, anh ta sẽ được đăng ký tất cả các nhiệm vụ của dự án này với các kiểu con được tìm thấy bằng cách sử dụng kiểu con cha

relation_field - Char

Ví dụ: khi liên kết các kiểu con dự án và nhiệm vụ, trường quan hệ là trường project_id của nhiệm vụ

res_model - Char

mô hình mà kiểu con áp dụng; nếu Sai, loại phụ này áp dụng cho tất cả các kiểu máy

mặc định - Boolean

liệu loại phụ có được kích hoạt theo mặc định khi đăng ký hay không

trình tự - Integer

được sử dụng để sắp xếp các loại phụ trong cửa sổ bật lên tùy chỉnh thông báo

hidden - Boolean

liệu loại phụ có bị ẩn trong cửa sổ bật lên tùy chỉnh thông báo hay không

Việc kết nối các loại phụ với theo dõi trường cho phép đăng ký các loại thông báo khác nhau tùy thuộc vào những gì người dùng có thể quan tâm. Để thực hiện việc này, bạn có thể ghi đè hàm _track_subtype():

_track_subtype(init_values)

Cung cấp loại phụ được kích hoạt bởi những thay đổi trên bản ghi theo các giá trị đã được cập nhật.

Tham số

init_values (dict) -- giá trị ban đầu của bản ghi; chỉ các trường được sửa đổi mới có trong dict

Trả về

id bên ngoài đầy đủ của loại phụ hoặc Sai nếu không có loại phụ nào được kích hoạt

Example

Hãy thêm trường state vào lớp mẫu của chúng ta và kích hoạt thông báo với một loại phụ cụ thể khi trường này thay đổi giá trị.

Đầu tiên, hãy xác định kiểu con của chúng ta:

<record id="mt_state_change" model="mail.message.subtype">
    <field name="name">Trip confirmed</field>
    <field name="res_model">business.trip</field>
    <field name="default" eval="True"/>
    <field name="description">Business Trip confirmed!</field>
</record>

Sau đó, chúng ta cần ghi đè hàm track_subtype(). Hàm này được hệ thống theo dõi gọi để biết loại phụ nào sẽ được sử dụng tùy thuộc vào thay đổi hiện đang được áp dụng. Trong trường hợp của chúng tôi, chúng tôi muốn sử dụng kiểu con mới sáng bóng của mình khi trường state thay đổi từ dự thảo thành xác nhận:

class BusinessTrip(models.Model):
    _name = 'business.trip'
    _inherit = ['mail.thread']
    _description = 'Business Trip'

    name = fields.Char(tracking=True)
    partner_id = fields.Many2one('res.partner', 'Responsible',
                                 tracking=True)
    guest_ids = fields.Many2many('res.partner', 'Participants')
    state = fields.Selection([('draft', 'New'), ('confirmed', 'Confirmed')],
                             tracking=True)

    def _track_subtype(self, init_values):
        # init_values contains the modified fields' values before the changes
        #
        # the applied values can be accessed on the record as they are already
        # in cache
        self.ensure_one()
        if 'state' in init_values and self.state == 'confirmed':
            return self.env.ref('my_module.mt_state_change')
        return super(BusinessTrip, self)._track_subtype(init_values)

Tùy chỉnh thông báo

Khi gửi thông báo đến những người theo dõi, việc thêm các nút trong mẫu để cho phép thực hiện các thao tác nhanh trực tiếp từ e-mail có thể khá hữu ích. Ngay cả một nút đơn giản để liên kết trực tiếp đến chế độ xem biểu mẫu của bản ghi cũng có thể hữu ích; tuy nhiên trong hầu hết các trường hợp, bạn không muốn hiển thị các nút này cho người dùng cổng thông tin.

Hệ thống thông báo cho phép tùy chỉnh mẫu thông báo theo các cách sau:

  • Hiển thị Nút truy cập: các nút này hiển thị ở đầu email thông báo và cho phép người nhận truy cập trực tiếp vào chế độ xem biểu mẫu của bản ghi

  • Hiển thị Nút theo dõi: các nút này cho phép người nhận đăng ký trực tiếp nhanh chóng từ bản ghi

  • Hiển thị Nút hủy theo dõi: các nút này cho phép người nhận trực tiếp hủy đăng ký nhanh chóng khỏi bản ghi

  • Hiển thị Nút hành động tùy chỉnh: các nút này gọi đến các tuyến cụ thể và cho phép bạn thực hiện một số hành động hữu ích có sẵn trực tiếp từ e-mail (tức là chuyển đổi khách hàng tiềm năng thành cơ hội, xác thực bảng chi phí cho Người quản lý chi phí, v.v.)

Các cài đặt nút này có thể được áp dụng cho các nhóm khác nhau mà bạn có thể tự xác định bằng cách ghi đè hàm _notify_get_groups.

_notify_get_groups(message, groups)

Cung cấp loại phụ được kích hoạt bởi những thay đổi trên bản ghi theo các giá trị đã được cập nhật.

Tham số
  • message (record) -- Bản ghi mail.message hiện đang được gửi

  • groups (list(tuple)) -- danh sách các bộ dữ liệu có dạng (group_name, group_func,group_data) trong đó: group_name là mã định danh chỉ được sử dụng để có thể ghi đè và thao tác các nhóm. Các nhóm mặc định là người dùng (người nhận được liên kết với người dùng nhân viên), portal (người nhận được liên kết với người dùng cổng thông tin) và khách hàng (người nhận không được liên kết với bất kỳ người dùng nào). Một ví dụ về việc sử dụng ghi đè là thêm một nhóm được liên kết với các nhóm res.group như Cán bộ nhân sự để đặt các nút hành động cụ thể cho họ. group_func là một con trỏ hàm lấy bản ghi đối tác làm tham số. Phương pháp này sẽ được áp dụng để người nhận biết họ có thuộc một nhóm nhất định hay không. Chỉ có nhóm phù hợp đầu tiên được giữ lại. Thứ tự đánh giá là thứ tự danh sách. group_data là một lệnh chứa các tham số cho email thông báo với các khóa - giá trị có thể có sau: - has_button_access có hiển thị Access <Document> trong email hay không. Đúng theo mặc định cho các nhóm mới, Sai cho cổng thông tin / khách hàng. - lệnh Button_access với url và tiêu đề của nút - has_button_follow có hiển thị Theo dõi trong email hay không (nếu người nhận hiện không theo dõi chuỗi). Đúng theo mặc định cho các nhóm mới, Sai cho cổng thông tin / khách hàng. - lệnh Button_follow với url và tiêu đề của nút - has_button_unfollow có hiển thị Hủy theo dõi trong email hay không (nếu người nhận hiện đang theo dõi chuỗi). Đúng theo mặc định cho các nhóm mới, Sai cho cổng thông tin / khách hàng. - lệnh Button_unfollow với url và tiêu đề của nút - danh sách hành động của các nút hành động sẽ hiển thị trong email thông báo. Mỗi hành động là một lệnh chứa url và tiêu đề của nút.

Trả về

id bên ngoài đầy đủ của loại phụ hoặc Sai nếu không có loại phụ nào được kích hoạt

Các url trong danh sách hành động có thể được tạo tự động bằng cách gọi hàm _notify_get_action_link():

Tạo một liên kết cho loại đã cho trên bản ghi hiện tại (hoặc trên một bản ghi cụ thể nếu kwargs modelres_id được đặt).

Tham số

link_type (str) -- loại liên kết được tạo ra; có thể là bất kỳ giá trị nào sau đây: view link to form view of record sign gán người dùng đã đăng nhập vào trường user_id của bản ghi (nếu nó tồn tại) follow self -giải thích hủy theo dõi phương thức tự giải thích gọi một phương thức trong hồ sơ; tên của phương thức phải được cung cấp dưới dạng kwarg phương thức mới mở chế độ xem biểu mẫu trống cho bản ghi mới; bạn có thể chỉ định một hành động cụ thể bằng cách cung cấp id của nó (id cơ sở dữ liệu hoặc id bên ngoài được phân giải đầy đủ) trong kwarg action_id

Trả về

liên kết thuộc loại được chọn cho bản ghi

Kiểu trả về

str

Example

Hãy thêm nút tùy chỉnh vào thông báo thay đổi trạng thái Chuyến công tác; nút này sẽ đặt lại trạng thái thành Bản nháp và sẽ chỉ hiển thị với thành viên của nhóm (ảo) Travel Manager (business.group_trip_manager)

class BusinessTrip(models.Model):
    _name = 'business.trip'
    _inherit = ['mail.thread', 'mail.alias.mixin']
    _description = 'Business Trip'

    # Pevious code goes here

    def action_cancel(self):
        self.write({'state': 'draft'})

    def _notify_get_groups(self, message, groups):
        """ Handle Trip Manager recipients that can cancel the trip at the last
        minute and kill all the fun. """
        groups = super(BusinessTrip, self)._notify_get_groups(message, groups)

        self.ensure_one()
        if self.state == 'confirmed':
            app_action = self._notify_get_action_link('method',
                                method='action_cancel')
            trip_actions = [{'url': app_action, 'title': _('Cancel')}]

        new_group = (
            'group_trip_manager',
            lambda partner: bool(partner.user_ids) and
            any(user.has_group('business.group_trip_manager')
            for user in partner.user_ids),
            {
                'actions': trip_actions,
            })

        return [new_group] + groups

Lưu ý rằng tôi có thể xác định hàm đánh giá của mình bên ngoài phương pháp này và xác định hàm toàn cục để thực hiện nó thay vì lambda, nhưng để ngắn gọn hơn và ít dài dòng hơn trong các tệp tài liệu đôi khi có thể nhàm chán này, tôi chọn cái trước thay vì cái sau.

Ghi đè mặc định

Có một số cách bạn có thể tùy chỉnh hành vi của mô hình mail.thread, bao gồm (nhưng không giới hạn):

_mail_post_access - Model thuộc tính

quyền truy cập cần thiết để có thể đăng tin nhắn trên mô hình; theo mặc định, cần có quyền truy cập ghi, cũng có thể được đặt thành đọc

Phím ngữ cảnh:

Các khóa ngữ cảnh này có thể được sử dụng để kiểm soát phần nào các tính năng của mail.thread như tự động đăng ký hoặc theo dõi trường trong khi gọi đến create() hoặc write() (hoặc bất kỳ phương thức nào khác mà nó có thể trở nên hữu ích).

  • mail_create_nosubscribe: khi tạo hoặc message_post, không đăng ký người dùng hiện tại vào chuỗi bản ghi

  • mail_create_nolog: khi tạo, không ghi thông báo '<Document> đã tạo' tự động

  • mail_notrack: khi tạo và viết, không thực hiện theo dõi giá trị tạo thư

  • tracking_disable: khi tạo và viết, không thực hiện tính năng MailThread (đăng ký tự động, theo dõi, đăng bài, ...)

  • mail_auto_delete: tự động xóa thông báo thư; Đúng theo mặc định

  • mail_notify_force_send: nếu gửi ít hơn 50 thông báo email, hãy gửi trực tiếp thay vì sử dụng hàng đợi; Đúng theo mặc định

  • mail_notify_user_signature: thêm chữ ký người dùng hiện tại vào thông báo qua email; Đúng theo mặc định

Bí danh thư

Bí danh là các địa chỉ email có thể định cấu hình được liên kết với một bản ghi cụ thể (thường kế thừa mô hình mail.alias.mixin) sẽ tạo các bản ghi mới khi được liên hệ qua e-mail. Chúng là một cách dễ dàng để giúp hệ thống của bạn có thể truy cập được từ bên ngoài, cho phép người dùng hoặc khách hàng nhanh chóng tạo các bản ghi trong cơ sở dữ liệu của bạn mà không cần kết nối trực tiếp với SoOn.

Bí danh so với Cổng thư đến

Một số người sử dụng Cổng thư đến cho cùng mục đích này. Bạn vẫn cần một cổng thư được cấu hình chính xác để sử dụng bí danh, tuy nhiên, chỉ cần một miền tổng hợp duy nhất là đủ vì tất cả việc định tuyến sẽ được thực hiện bên trong SoOn. Bí danh có một số lợi thế so với Cổng Thư:

  • Dễ dàng cấu hình hơn
    • Một cổng vào duy nhất có thể được sử dụng bởi nhiều bí danh; điều này tránh phải định cấu hình nhiều email trên tên miền của bạn (tất cả cấu hình được thực hiện bên trong SoOn)

    • Không cần quyền truy cập hệ thống để định cấu hình bí danh

  • Mạch lạc hơn
    • Có thể định cấu hình trên bản ghi liên quan, không phải trong menu con Cài đặt

  • Dễ dàng ghi đè phía máy chủ hơn
    • Mô hình Mixin được xây dựng để mở rộng ngay từ đầu, cho phép bạn trích xuất dữ liệu hữu ích từ các e-mail đến dễ dàng hơn so với cổng thư.

Tích hợp hỗ trợ bí danh

Bí danh thường được định cấu hình trên mô hình gốc, sau đó sẽ tạo bản ghi cụ thể khi được liên hệ qua e-mail. Ví dụ: Project có bí danh để tạo nhiệm vụ hoặc vấn đề, Nhóm bán hàng có bí danh để tạo Khách hàng tiềm năng.

Ghi chú

Mô hình sẽ được tạo bởi bí danh phải kế thừa mô hình mail_thread.

Hỗ trợ bí danh được thêm vào bằng cách kế thừa mail.alias.mixin; Mixin này sẽ tạo ra một bản ghi mail.alias mới cho mỗi bản ghi của lớp cha được tạo (ví dụ: mọi bản ghi project.project có bản ghi mail.alias của nó được khởi tạo khi tạo ).

Ghi chú

Bí danh cũng có thể được tạo thủ công và được hỗ trợ bởi trường Many2one đơn giản. Hướng dẫn này giả định rằng bạn muốn tích hợp hoàn chỉnh hơn với tính năng tự động tạo bí danh, giá trị mặc định dành riêng cho bản ghi, v.v.

Không giống như kế thừa mail.thread, mail.alias.mixin yêu cầu một số ghi đè cụ thể để hoạt động chính xác. Các phần ghi đè này sẽ chỉ định các giá trị của bí danh đã tạo, như loại bản ghi mà nó phải tạo và có thể một số giá trị mặc định mà các bản ghi này có thể có tùy thuộc vào đối tượng cha:

_get_alias_model_name(vals)

Trả lại tên mẫu cho bí danh. Các email đến không trả lời các bản ghi hiện có sẽ tạo ra một bản ghi mới của mô hình bí danh này. Giá trị có thể phụ thuộc vào vals, mệnh lệnh của các giá trị được truyền cho create khi bản ghi của mô hình này được tạo.

Tham số

dict (vals) -- giá trị của bản ghi mới được tạo sẽ giữ bí danh

Trả về

tên mẫu

Kiểu trả về

str

_get_alias_values()

Trả về các giá trị để tạo bí danh hoặc để viết bí danh sau khi tạo. Mặc dù không hoàn toàn bắt buộc nhưng thường phải đảm bảo rằng các bản ghi mới được tạo sẽ được liên kết với cha mẹ của bí danh (tức là các tác vụ được tạo trong đúng dự án) bằng cách đặt từ điển các giá trị mặc định trong bí danh' alias_defaults cánh đồng.

Trả về

từ điển các giá trị sẽ được ghi vào bí danh mới

Kiểu trả về

dict

Ghi đè _get_alias_values() đặc biệt thú vị vì nó cho phép bạn sửa đổi hành vi của bí danh của mình một cách dễ dàng. Trong số các trường có thể được đặt trên bí danh, những trường sau đây được đặc biệt quan tâm:

alias_name - Char

tên của bí danh email, ví dụ: 'việc làm' nếu bạn muốn nhận email về <jobs@example.odoo.com>

alias_user_id - Many2one (res.users)

chủ sở hữu hồ sơ được tạo khi nhận email có bí danh này; nếu trường này không được đặt, hệ thống sẽ cố gắng tìm đúng chủ sở hữu dựa trên địa chỉ (Từ) người gửi hoặc sẽ sử dụng tài khoản Quản trị viên nếu không tìm thấy người dùng hệ thống nào cho địa chỉ đó

alias_defaults - Text

Từ điển Python sẽ được đánh giá để cung cấp các giá trị mặc định khi tạo bản ghi mới cho bí danh này

alias_force_thread_id - Integer

ID tùy chọn của một chuỗi (bản ghi) mà tất cả các tin nhắn đến sẽ được đính kèm, ngay cả khi chúng không trả lời nó; nếu được đặt, điều này sẽ vô hiệu hóa hoàn toàn việc tạo bản ghi mới

alias_contact - Selection

Chính sách gửi tin nhắn lên tài liệu bằng cổng thư

  • mọi người: mọi người đều có thể đăng bài

  • đối tác: chỉ các đối tác được xác thực

  • người theo dõi: chỉ những người theo dõi tài liệu liên quan hoặc thành viên của các kênh sau

Lưu ý rằng bí danh sử dụng kế thừa ủy quyền, có nghĩa là trong khi bí danh được lưu trữ trong một bảng khác, bạn có quyền truy cập vào tất cả các trường này trực tiếp từ đối tượng cha của mình. Điều này cho phép bạn dễ dàng cấu hình bí danh của mình từ chế độ xem biểu mẫu của bản ghi.

Example

Hãy thêm bí danh vào lớp đi công tác của chúng ta để tạo chi phí nhanh chóng qua e-mail.

class BusinessTrip(models.Model):
    _name = 'business.trip'
    _inherit = ['mail.thread', 'mail.alias.mixin']
    _description = 'Business Trip'

    name = fields.Char(tracking=True)
    partner_id = fields.Many2one('res.partner', 'Responsible',
                                 tracking=True)
    guest_ids = fields.Many2many('res.partner', 'Participants')
    state = fields.Selection([('draft', 'New'), ('confirmed', 'Confirmed')],
                             tracking=True)
    expense_ids = fields.One2many('business.expense', 'trip_id', 'Expenses')
    alias_id = fields.Many2one('mail.alias', string='Alias', ondelete="restrict",
                               required=True)

    def _get_alias_model_name(self, vals):
    """ Specify the model that will get created when the alias receives a message """
        return 'business.expense'

    def _get_alias_values(self):
    """ Specify some default values that will be set in the alias at its creation """
        values = super(BusinessTrip, self)._get_alias_values()
        # alias_defaults holds a dictionary that will be written
        # to all records created by this alias
        #
        # in this case, we want all expense records sent to a trip alias
        # to be linked to the corresponding business trip
        values['alias_defaults'] = {'trip_id': self.id}
        # we only want followers of the trip to be able to post expenses
        # by default
        values['alias_contact'] = 'followers'
        return values

class BusinessExpense(models.Model):
    _name = 'business.expense'
    _inherit = ['mail.thread']
    _description = 'Business Expense'

    name = fields.Char()
    amount = fields.Float('Amount')
    trip_id = fields.Many2one('business.trip', 'Business Trip')
    partner_id = fields.Many2one('res.partner', 'Created by')

Chúng tôi muốn bí danh của mình có thể dễ dàng cấu hình từ chế độ xem biểu mẫu của các chuyến công tác, vì vậy hãy thêm phần sau vào chế độ xem biểu mẫu của chúng tôi:

<page string="Emails">
    <group name="group_alias">
        <label for="alias_name" string="Email Alias"/>
        <div name="alias_def">
            <!-- display a link while in view mode and a configurable field
            while in edit mode -->
            <field name="alias_id" class="oe_read_only oe_inline"
                    string="Email Alias" required="0"/>
            <div class="oe_edit_only oe_inline" name="edit_alias"
                 style="display: inline;" >
                <field name="alias_name" class="oe_inline"/>
                @
                <field name="alias_domain" class="oe_inline" readonly="1"/>
            </div>
        </div>
        <field name="alias_contact" class="oe_inline"
                string="Accept Emails From"/>
    </group>
</page>

Bây giờ chúng ta có thể thay đổi địa chỉ bí danh trực tiếp từ chế độ xem biểu mẫu và thay đổi ai có thể gửi e-mail đến bí danh.

Sau đó, chúng tôi có thể ghi đè message_new() trên mô hình chi phí của mình để tìm nạp các giá trị từ email khi chi phí được tạo:

class BusinessExpense(models.Model):
    # Previous code goes here
    # ...

    def message_new(self, msg, custom_values=None):
        """ Override to set values according to the email.

        In this simple example, we simply use the email title as the name
        of the expense, try to find a partner with this email address and
        do a regex match to find the amount of the expense."""
        name = msg_dict.get('subject', 'New Expense')
        # Match the last occurrence of a float in the string
        # Example: '50.3 bar 34.5' becomes '34.5'. This is potentially the price
        # to encode on the expense. If not, take 1.0 instead
        amount_pattern = '(\d+(\.\d*)?|\.\d+)'
        expense_price = re.findall(amount_pattern, name)
        price = expense_price and float(expense_price[-1][0]) or 1.0
        # find the partner by looking for it's email
        partner = self.env['res.partner'].search([('email', 'ilike', email_address)],
                                                 limit=1)
        defaults = {
            'name': name,
            'amount': price,
            'partner_id': partner.id
        }
        defaults.update(custom_values or {})
        res = super(BusinessExpense, self).message_new(msg, custom_values=defaults)
        return res

Theo dõi hoạt động

Hoạt động là những hành động mà người dùng phải thực hiện trên một tài liệu như gọi điện thoại hoặc tổ chức một cuộc họp. Các hoạt động đi kèm với mô-đun thư vì chúng được tích hợp trong Trò chuyện nhưng không được gói cùng với mail.thread. Hoạt động là các bản ghi của lớp mail.activity, có loại (mail.activity.type), tên, mô tả, thời gian đã lên lịch (trong số những loại khác). Các hoạt động đang chờ xử lý hiển thị phía trên lịch sử tin nhắn trong tiện ích trò chuyện.

Bạn có thể tích hợp các hoạt động bằng cách sử dụng lớp mail.activity.mixin trên đối tượng của mình và các tiện ích cụ thể để hiển thị chúng (thông qua trường activity_ids) trong chế độ xem biểu mẫu và chế độ xem kanban của hồ sơ của bạn (mail_activity `` ``kanban_activity tương ứng).

Example

Tổ chức một chuyến công tác là một quá trình tẻ nhạt và việc theo dõi các hoạt động cần thiết như đặt vé máy bay hoặc taxi đến sân bay có thể hữu ích. Để làm như vậy, chúng tôi sẽ thêm các hoạt động kết hợp vào mô hình của mình và hiển thị các hoạt động được lên kế hoạch tiếp theo trong lịch sử tin nhắn của chuyến đi của chúng tôi.

class BusinessTrip(models.Model):
    _name = 'business.trip'
    _inherit = ['mail.thread', 'mail.activity.mixin']
    _description = 'Business Trip'

    name = fields.Char()
    # [...]

Chúng tôi sửa đổi chế độ xem biểu mẫu của các chuyến đi để hiển thị các hoạt động tiếp theo của họ:

<record id="business_trip_form" model="ir.ui.view">
    <field name="name">business.trip.form</field>
    <field name="model">business.trip</field>
    <field name="arch" type="xml">
        <form string="Business Trip">
            <!-- Your usual form view goes here -->
            <div class="oe_chatter">
                <field name="message_follower_ids" widget="mail_followers"/>
                <field name="activity_ids" widget="mail_activity"/>
                <field name="message_ids" widget="mail_thread"/>
            </div>
        </form>
    </field>
</record>

Bạn có thể tìm thấy các ví dụ cụ thể về tích hợp trong các mô hình sau:

  • crm.lead trong Ứng dụng CRM (crm)

  • sale.order trong Ứng dụng Bán hàng (sale)

  • project.task trong Ứng dụng Project (project)

Tính năng trang web

Theo dõi khách truy cập

Lớp utm.mixin có thể được sử dụng để theo dõi các chiến dịch tiếp thị/truyền thông trực tuyến thông qua các đối số trong liên kết đến các tài nguyên được chỉ định. Mixin thêm 3 trường vào mô hình của bạn:

  • campaign_id: Many2one vào đối tượng utm.campaign (ví dụ: Christmas_special, Fall_Collection, v.v.)

  • source_id: Many2one tới đối tượng utm.source (tức là Công cụ tìm kiếm, danh sách gửi thư, v.v.)

  • medium_id: Many2one tới đối tượng utm.medium (ví dụ: Snail Mail, e-Mail, cập nhật mạng xã hội, v.v.)

Các mô hình này có một trường duy nhất tên (tức là chúng chỉ ở đó để phân biệt các chiến dịch nhưng không có bất kỳ hành vi cụ thể nào).

Khi khách hàng truy cập trang web của bạn với các thông số này được đặt trong url (tức là https://www.odoo.com/?campaign_id=mixin_talk&source_id=www.odoo.com&medium_id=website), ba cookie sẽ được đặt trong trang web của khách truy cập cho các thông số này . Khi một đối tượng kế thừa utm.mixin được tạo từ trang web (tức là biểu mẫu khách hàng tiềm năng, đơn xin việc, v.v.), mã utm.mixin sẽ bắt đầu hoạt động và tìm nạp các giá trị từ cookie để đặt chúng vào bản ghi mới. Khi việc này hoàn tất, bạn có thể sử dụng các trường chiến dịch/nguồn/phương tiện như bất kỳ trường nào khác khi xác định báo cáo và chế độ xem (nhóm theo, v.v.).

Để mở rộng hành vi này, chỉ cần thêm một trường quan hệ vào một mô hình đơn giản (mô hình đó phải hỗ trợ tạo nhanh (tức là gọi tới create() với một giá trị name duy nhất) và mở rộng hàm ` tracking_fields()`:

class UtmMyTrack(models.Model):
    _name = 'my_module.my_track'
    _description = 'My Tracking Object'

    name = fields.Char(string='Name', required=True)


class MyModel(models.Models):
    _name = 'my_module.my_model'
    _inherit = ['utm.mixin']
    _description = 'My Tracked Object'

    my_field = fields.Many2one('my_module.my_track', 'My Field')

    @api.model
    def tracking_fields(self):
        result = super(MyModel, self).tracking_fields()
        result.append([
        # ("URL_PARAMETER", "FIELD_NAME_MIXIN", "NAME_IN_COOKIES")
            ('my_field', 'my_field', 'odoo_utm_my_field')
        ])
        return result

Điều này sẽ yêu cầu hệ thống tạo một cookie có tên odoo_utm_my_field với giá trị được tìm thấy trong tham số url my_field; khi bản ghi mới của mô hình này được tạo bằng lệnh gọi từ biểu mẫu trang web, phần ghi đè chung của phương thức create() của utm.mixin sẽ tìm nạp các giá trị mặc định cho trường này từ cookie ( và bản ghi my_module.my_track sẽ được tạo nhanh chóng nếu nó chưa tồn tại).

Bạn có thể tìm thấy các ví dụ cụ thể về tích hợp trong các mô hình sau:

  • crm.lead trong Ứng dụng CRM (crm)

  • hr.applicant trong Quy trình tuyển dụng (hr_recruitment)

  • helpdesk.ticket trong Ứng dụng Helpdesk (helpdesk - chỉ dành cho SoOn Enterprise)

Khả năng hiển thị trang web

Bạn có thể dễ dàng thêm nút chuyển đổi khả năng hiển thị trang web trên bất kỳ hồ sơ nào của mình. Mặc dù mixin này khá dễ triển khai theo cách thủ công, nhưng nó được sử dụng thường xuyên nhất sau kế thừa mail.thread; một minh chứng cho sự hữu ích của nó. Trường hợp sử dụng điển hình cho mixin này là bất kỳ đối tượng nào có trang giao diện người dùng; khả năng kiểm soát khả năng hiển thị của trang cho phép bạn dành thời gian chỉnh sửa trang và chỉ xuất bản nó khi bạn hài lòng.

Để bao gồm chức năng, bạn chỉ cần kế thừa website.published.mixin:

class BlogPost(models.Model):
    _name = "blog.post"
    _description = "Blog Post"
    _inherit = ['website.published.mixin']

Mixin này thêm 2 trường trên mô hình của bạn:

  • website_published: Boolean đại diện cho trạng thái của ấn phẩm

  • Trường website_url: Char đại diện cho URL mà đối tượng được truy cập thông qua đó

Lưu ý rằng trường cuối cùng này là trường được tính toán và phải được triển khai cho lớp của bạn:

def _compute_website_url(self):
    for blog_post in self:
        blog_post.website_url = "/blog/%s" % (log_post.blog_id)

Khi cơ chế đã sẵn sàng, bạn chỉ cần điều chỉnh chế độ xem giao diện người dùng và phụ trợ của mình để có thể truy cập được. Trong phần phụ trợ, việc thêm một nút vào hộp nút thường là cách tốt nhất:

<button class="oe_stat_button" name="website_publish_button"
    type="object" icon="fa-globe">
    <field name="website_published" widget="website_button"/>
</button>

Ở giao diện người dùng, cần có một số kiểm tra bảo mật để tránh hiển thị nút 'Chỉnh sửa' cho khách truy cập trang web:

<div id="website_published_button" class="float-right"
     groups="base.group_website_publisher"> <!-- or any other meaningful group -->
    <t t-call="website.publish_management">
      <t t-set="object" t-value="blog_post"/>
      <t t-set="publish_edit" t-value="True"/>
      <t t-set="action" t-value="'blog.blog_post_action'"/>
    </t>
</div>

Lưu ý rằng bạn phải chuyển đối tượng của mình dưới dạng biến object vào mẫu; trong ví dụ này, bản ghi blog.post đã được chuyển dưới dạng biến blog_post sang công cụ kết xuất qweb, cần phải chỉ định điều này cho mẫu quản lý xuất bản. Biến publish_edit cho phép nút giao diện người dùng liên kết với phần phụ trợ (cho phép bạn chuyển từ giao diện người dùng sang phụ trợ và ngược lại một cách dễ dàng); nếu được đặt, bạn phải chỉ định id bên ngoài đầy đủ của hành động mà bạn muốn gọi trong phần phụ trợ trong biến action (lưu ý rằng Chế độ xem biểu mẫu phải tồn tại cho mô hình).

Hành động website_publish_button được xác định trong mixin và điều chỉnh hành vi của nó cho phù hợp với đối tượng của bạn: nếu lớp có hàm tính toán website_url hợp lệ, người dùng sẽ được chuyển hướng đến giao diện người dùng khi anh ta nhấp vào nút; sau đó người dùng có thể xuất bản trang trực tiếp từ giao diện người dùng. Điều này đảm bảo rằng không có ấn phẩm trực tuyến nào có thể xảy ra một cách tình cờ. Nếu không có chức năng tính toán, boolean website_published sẽ được kích hoạt đơn giản.

Siêu dữ liệu trang web

Mixin đơn giản này chỉ cho phép bạn dễ dàng đưa siêu dữ liệu vào các trang giao diện người dùng của mình.

class BlogPost(models.Model):
    _name = "blog.post"
    _description = "Blog Post"
    _inherit = ['website.seo.metadata', 'website.published.mixin']

Mixin này thêm 3 trường trên mô hình của bạn:

  • Trường website_meta_title: Char cho phép bạn đặt tiêu đề bổ sung cho trang của mình

  • Trường website_meta_description: Char chứa mô tả ngắn về trang (đôi khi được sử dụng trong kết quả của công cụ tìm kiếm)

  • Trường website_meta_keywords: Char chứa một số từ khóa giúp trang của bạn được các công cụ tìm kiếm phân loại chính xác hơn; Công cụ "Promote" sẽ giúp bạn lựa chọn từ khóa liên quan đến từ vựng một cách dễ dàng

Các trường này có thể chỉnh sửa được trong giao diện người dùng bằng công cụ "Quảng bá" từ thanh công cụ Trình chỉnh sửa. Việc đặt các trường này có thể giúp công cụ tìm kiếm lập chỉ mục các trang của bạn tốt hơn. Lưu ý rằng các công cụ tìm kiếm không chỉ đưa ra kết quả dựa trên những siêu dữ liệu này; cách thực hành SEO tốt nhất vẫn nên được tham khảo bởi các nguồn đáng tin cậy.

Người khác

Đánh giá của khách hàng

Mixin xếp hạng cho phép gửi email để yêu cầu xếp hạng của khách hàng, tự động chuyển đổi trong quy trình Kanban và tổng hợp số liệu thống kê về xếp hạng của bạn.

Thêm xếp hạng vào mô hình của bạn

Để thêm hỗ trợ xếp hạng, chỉ cần kế thừa mô hình `` rating.mixin``:

class MyModel(models.Models):
    _name = 'my_module.my_model'
    _inherit = ['rating.mixin', 'mail.thread']

    user_id = fields.Many2one('res.users', 'Responsible')
    partner_id = fields.Many2one('res.partner', 'Customer')

Hành vi của mixin thích ứng với mô hình của bạn:

  • Bản ghi `` rating. rating`` sẽ được liên kết với trường partner_id trong mô hình của bạn (nếu có trường này).

    • hành vi này có thể bị ghi đè bằng hàm `` rating_get_partner_id()`` nếu bạn sử dụng trường khác ngoài partner_id

  • Bản ghi `` rating. rating`` sẽ được liên kết với đối tác của trường user_id trong mô hình của bạn (nếu có trường này) (tức là đối tác được xếp hạng)

    • hành vi này có thể bị ghi đè bằng hàm `` rating_get_rated_partner_id()`` nếu bạn sử dụng trường khác ngoài user_id (lưu ý rằng hàm phải trả về res.partner, đối với user_id hệ thống tự động tìm nạp đối tác của người dùng)

  • Lịch sử trò chuyện sẽ hiển thị sự kiện xếp hạng (nếu mô hình của bạn kế thừa từ mail.thread)

Gửi yêu cầu xếp hạng qua e-mail

Nếu bạn muốn gửi email để yêu cầu xếp hạng, chỉ cần tạo một email có liên kết đến đối tượng xếp hạng. Một mẫu email rất cơ bản có thể trông như thế này:

<record id="rating_my_model_email_template" model="mail.template">
            <field name="name">My Model: Rating Request</field>
            <field name="email_from">${object.rating_get_rated_partner_id().email or '' | safe}</field>
            <field name="subject">Service Rating Request</field>
            <field name="model_id" ref="my_module.model_my_model"/>
            <field name="partner_to" >${object.rating_get_partner_id().id}</field>
            <field name="auto_delete" eval="True"/>
            <field name="body_html"><![CDATA[
% set access_token = object.rating_get_access_token()
<p>Hi,</p>
<p>How satsified are you?</p>
<ul>
    <li><a href="/rate/${access_token}/5">Satisfied</a></li>
    <li><a href="/rate/${access_token}/3">Okay</a></li>
    <li><a href="/rate/${access_token}/1">Dissatisfied</a></li>
</ul>
]]></field>
</record>

Sau đó, khách hàng của bạn sẽ nhận được e-mail có liên kết đến một trang web đơn giản cho phép họ cung cấp phản hồi về tương tác của họ với người dùng của bạn (bao gồm cả tin nhắn phản hồi bằng văn bản miễn phí).

Sau đó, bạn có thể dễ dàng tích hợp xếp hạng của mình với chế độ xem biểu mẫu bằng cách xác định hành động cho xếp hạng:

<record id="rating_rating_action_my_model" model="ir.actions.act_window">
    <field name="name">Customer Ratings</field>
    <field name="res_model">rating.rating</field>
    <field name="view_mode">kanban,pivot,graph</field>
    <field name="domain">[('res_model', '=', 'my_module.my_model'), ('res_id', '=', active_id), ('consumed', '=', True)]</field>
</record>

<record id="my_module_my_model_view_form_inherit_rating" model="ir.ui.view">
    <field name="name">my_module.my_model.view.form.inherit.rating</field>
    <field name="model">my_module.my_model</field>
    <field name="inherit_id" ref="my_module.my_model_view_form"/>
    <field name="arch" type="xml">
        <xpath expr="//div[@name='button_box']" position="inside">
            <button name="%(rating_rating_action_my_model)d" type="action"
                    class="oe_stat_button" icon="fa-smile-o">
                <field name="rating_count" string="Rating" widget="statinfo"/>
            </button>
        </xpath>
    </field>
</record>

Lưu ý rằng có các chế độ xem mặc định (kanban,pivot,biểu đồ) cho xếp hạng cho phép bạn xem nhanh xếp hạng của khách hàng.

Bạn có thể tìm thấy các ví dụ cụ thể về tích hợp trong các mô hình sau:

  • project.task trong Ứng dụng Dự án (rated_project)

  • helpdesk.ticket trong Ứng dụng Helpdesk (helpdesk - chỉ dành cho SoOn Enterprise)