States vs. Stages: 2 cách tiếp cận để phản ánh các giai đoạn của quy trình

Hiểu đúng bản chất giúp bạn có lựa chọn phù hợp

Trobz, Chien Nguyen Minh

Odoo có xu hướng xây dựng các đối tượng tuân thủ theo những vòng đời phát triển nhất định. Lấy Sales orders làm ví dụ. Khi đơn hàng mới vừa được tạo, nó sẽ có trạng thái là "Quotation". Sau khi gửi báo giá đến khách hàng, chúng ta chuyển đơn hàng qua trạng thái "Quotation Sent". Khi đạt được thỏa thuận mua - bán giữa 2 bên, đơn hàng sẽ được chuyển qua trạng thái "Sale order". Và cứ như thế cho đến khi đơn hàng kết thúc ở trạng thái "Locked" hoặc "Cancelled".

Chúng ta có 2 cách tiếp cận để có thể xây dựng vòng đời phát triển áp đặt cho các đối tượng, đó là StatesStages. Trong nội dung bài Blog này, tôi sẽ mô tả các đặc tính, những ưu khuyết điểm, và gợi ý giúp bạn có lựa chọn phù hợp với đối tượng bạn đang xây dựng.

States - Tương lai được biết trước

Từ ví dụ về vòng đời của Sales order ở trên, chúng ta có thể thấy rằng, các đơn hàng dù được tạo trong hôm nay hay là vào ngày mai, đều đi qua các trạng thái chuẩn mực: từ Quotation -> Quotation sent -> Sale orders -> Locked. Thực tế vẫn có đơn hàng bỏ qua giai đoạnQuotation sent, hoặc nhảy cóc qua Cancelled. Nhưng khi xét trạng thái của bất kì đơn hàng nào, tại bất kỳ thời điểm nào, thì chúng luôn luôn phải nằm trong các giá trị Quotation, Quotation sent, Sale orders, Locked, hoặc Cancelled.

Odoo • Hình ảnh với chú thích
Trạng thái của đơn hàng Sales order

Tạo States trong Odoo

States được khai báo là 1 trường (field) thuộc loại Selection. Ví dụ, State của Sales order được khai báo như sau:

Odoo • Văn bản và hình ảnh

Ưu và khuyết điểm của States

Vì các giá trị của States được khai báo cố định, nên nó là cách tiếp cận rất đáng tin cậy. Bạn có thể viết các đoạn code tìm kiếm đơn hàng theo State và tự tin rằng đoạn code đó sẽ luôn trả về kết quả đúng trong mọi trường hợp. Ngoài ra, Odoo có sự hỗ trợ đặc biệt dành cho trường state, trên các màn hình view, chúng ta có thể khai báo để ẩn / hiện bất kì trường (hoặc button)  nào đó theo từng trạng thái riêng biệt, bằng cách thêm thuộc tính states.

Odoo • Văn bản và hình ảnh

Tuy nhiên, States có một hạn chế là nó không hỗ trợ được cho các đối tượng có quy trình đa dạng, thay đổi theo từng bản ghi hoặc thay đổi theo thời gian. Do đó, chúng ta có cách tiếp cận khác là Stages.

Đa dạng hóa quy trình với Stages

Ví dụ điển hình nhất cho việc dùng Stages đó chính là đối tượng Tasks (của module Project). Tùy vào từng dự án mà Task có thể đi qua nhiều giai đoạn thực hiện và kiểm duyệt hoàn toàn khác nhau. Bạn xem hình minh họa bên dưới

Odoo • Hình ảnh với chú thích
Minh họa về Task và các giai đoạn của Task  .

Tạo Stages trong Odoo

Stages được khai báo là 1 trường (field) thuộc loại Many2one, liên kết đến đối tượng khác. Cùng xem lại cách khai báo Stage của Project Task:

Odoo • Văn bản và hình ảnh

stage_id liên kết đến đối tượng project.task.type. Việc thêm mới stage được thực hiện đơn giản bằng cách thêm mới 1 bản ghi trong bảng project_task_type.

Còn đây là màn hình thêm mới một Stage của Task. Các giai đoạn được sắp xếp thứ tự trước sau dựa vào Sequence.

Odoo • Văn bản và hình ảnh

Ưu và khuyết điểm của Stages

Sự thuận tiện và tính tùy biến là những ưu điểm nổi bậc nhất của Stage. Tuy nhiên nó không đáng tin cậy vì thông tin quá dễ để bị thay đổi. Do đó, cách tốt nhất là chúng ta sử dụng kết hợp cả State và Stages.

Kinh nghiệm từ thực tiễn

Kết hợp State và Stage giúp chúng ta vận dụng được toàn bộ các ưu điểm, và che lấp đi các khuyết điểm của cả State và Stage. Các đối tượng được sắp xếp và quản lý bởi các quy trình có thể cấu hình động, nhưng lại vừa liên kết đến các trạng thái tĩnh thông qua các mã trạng thái không bao giờ bị thay đổi.

Quay lại với đối tượng project.task.type, chúng ta cần thêm trường state để khai báo các mã cố định phản ánh các trạng thái. ví dụ như:

Odoo • Văn bản và hình ảnh

Sau đó, chúng ta thêm trường state trong đối tượng project.task
Odoo • Văn bản và hình ảnh

Từ đây, đối với các trường hợp tìm kiếm hoặc kiểm tra ràng buộc dữ liệu (như record rule chẳng hạn), chúng ta sẽ sử dụng trường State. Để cấu hình động các giai đoạn của Task, chúng ta sử dụng Stage.