---
title: "Việt hóa Odoo: một chuỗi dịch, nhiều màn hình"
url: "https://bahub.vn/khoa-hoc/erp-cho-ba/viet-hoa-odoo-mot-key-nhieu-noi"
author: "Võ Văn Trí"
published: "2026-09-10"
updated: "2026-11-02"
source: "bahub.vn"
license: "Được dùng lại, trích dẫn và đưa cho AI đọc, với điều kiện ghi rõ nguồn bahub.vn kèm link bài gốc."
---

# Việt hóa Odoo: một chuỗi dịch, nhiều màn hình

> Khách đòi đổi một chữ trên màn hình, nghe như việc năm phút. Nhưng Odoo dịch theo chuỗi gốc chứ không theo màn hình, nên sửa một chỗ đổi cả nơi không ngờ.

- Nguồn: https://bahub.vn/khoa-hoc/erp-cho-ba/viet-hoa-odoo-mot-key-nhieu-noi
- Tác giả: Võ Văn Trí
- Khoá học: ERP cho Business Analyst (mục lục: https://bahub.vn/khoa-hoc/erp-cho-ba.md)
- Chương: Tùy biến và phân quyền

Buổi UAT ở một công ty phân phối thiết bị điện. Trưởng phòng kinh doanh dừng lại ở form cơ hội, chỉ vào ô đang ghi Nhân viên sales và nói rằng bên chị mọi người vẫn gọi là nhân viên kinh doanh, đổi giúp chị chữ này, chắc mất năm phút.

Bạn ghi vào biên bản như một yêu cầu nhỏ. Chiều đó bạn xuất bản dịch ra, tìm đúng chuỗi, sửa, nhập lại rồi tải lại màn hình và thấy chữ mới hiện lên, tổng cộng hai mươi phút. Hai ngày sau, người phụ trách công nợ hỏi vì sao trên form liên hệ, cái ô mà chị vẫn gọi là người phụ trách khách hàng, giờ cũng ghi nhân viên kinh doanh, và mở đơn bán hàng ra thì cũng thấy y như vậy.

> Không ai thao tác sai ở đây. Ba ô đó là ba trường riêng biệt nằm trên ba đối tượng dữ liệu khác nhau, nhưng trên Odoo 19 cả ba đều mang nhãn gốc tiếng Anh là Salesperson, tức chúng chỉ trùng nhau đúng ở chuỗi tiếng Anh, và cơ chế dịch của Odoo làm việc trên chuỗi gốc chứ không làm việc trên màn hình.

Hiểu sai chỗ này thì mọi ước lượng về công việc Việt hóa đều lệch theo hướng hứa nhiều hơn khả năng.

Toàn bộ phần cơ chế trong bài này tôi mô tả trên Odoo 19, và đây là loại nội dung bạn phải dựng lại trên đúng bản mình đang chạy chứ không nên tin theo trí nhớ. Tên menu trong bài là tên tiếng Anh gốc, nên trên database đã Việt hóa thì chữ hiển thị sẽ khác.

## Nơi bản dịch thực sự nằm

**Ngôn ngữ gốc của Odoo là tiếng Anh.** Mọi bản dịch đều xuất phát từ một chuỗi tiếng Anh làm khóa, và khi người dùng chọn ngôn ngữ thì hệ thống tra bản dịch tương ứng của khóa đó rồi hiển thị. Điều đáng nắm hơn là bản dịch không nằm chung một chỗ mà chia làm hai loại, với hai số phận khác hẳn nhau.

**Loại thứ nhất là chuỗi nằm trong mã nguồn**, tức các câu thông báo, cảnh báo và nhãn do lập trình viên viết thẳng trong code. Chúng được nạp từ file `.po` trong thư mục `i18n` của từng module theo từng ngôn ngữ, và sống trong bộ nhớ của server chứ không nằm trong cơ sở dữ liệu.

**Loại thứ hai là bản dịch của các bản ghi trong chính database**, gồm:

* nhãn trường cùng phần trợ giúp của nó
* tên menu
* các chuỗi trong định nghĩa màn hình
* mẫu email
* mẫu in
* và giá trị của những trường được khai báo là dịch được

Loại này nằm ngay trong cột của bảng chứa bản ghi, dưới dạng một cấu trúc `jsonb` lấy mã ngôn ngữ làm khóa, nên bản tiếng Anh và bản tiếng Việt của một nhãn trường nằm cạnh nhau trong cùng một ô dữ liệu. Cách lưu này có từ Odoo 16; tới Odoo 15 bản dịch còn nằm ở một bảng riêng tên là `ir.translation`, nên **những bài viết trên mạng hướng dẫn tra hay sửa cái bảng đó đều đã lạc hậu**.

Sự phân đôi này không phải kiến thức để biết cho vui, vì hai loại có hai đường sửa khác nhau, và **một trong hai loại thì công cụ nhập bản dịch trên giao diện không đụng tới được**.

![Bản dịch nằm ở hai nơi, một nơi sửa được trên giao diện, một nơi phải nhờ developer](https://bahub.vn/uploads/2026/11/1793631642344-qsm9m7-viet-hoa-odoo-mot-key-nhieu-noi-1.webp "Bản dịch nằm ở hai nơi, một nơi sửa được trên giao diện, một nơi phải nhờ developer")

## Cơ chế gom bản dịch theo chuỗi gốc

Muốn hiểu vì sao sửa một chữ lại đổi ba nơi, cần nhìn vào cách file bản dịch được ghi ra.

Đường lấy bản dịch ra là Settings, Translations, Import / Export, rồi chọn Export Translation. Menu này chỉ hiện khi đã bật [chế độ nhà phát triển](https://bahub.vn/khoa-hoc/erp-cho-ba/developer-mode-cong-cu-cua-ba), một công cụ đã có bài riêng, nên ở đây chỉ cần nhớ quên bật thì không tìm thấy phần dịch thuật ở đâu cả. Màn hình xuất có ba tham số:

* ngôn ngữ đích
* định dạng file gồm CSV, PO và TGZ
* và kiểu xuất theo phân hệ hay theo mô hình

Xuất theo phân hệ mà để trống danh sách phân hệ thì lấy trọn hệ thống, còn xuất theo mô hình thì mỗi lần chỉ chọn được một mô hình.

Điểm mấu chốt nằm ở chỗ **file PO gom các dòng theo chuỗi gốc, và mỗi chuỗi gốc chỉ mang đúng một bản dịch**. Do đó mọi vị trí đang dùng chữ Salesperson rơi vào cùng một cụm gồm chuỗi gốc, phần dịch, và phía trên là các dòng tham chiếu liệt kê từng vị trí; nhập lại file thì bản dịch của cụm đó được ghi vào tất cả các vị trí ấy.

Từ đó ra một thao tác ước lượng rất rẻ mà phần lớn người mới bỏ qua:

1. mở file bản dịch
2. tìm chuỗi gốc
3. đếm số dòng tham chiếu, ba dòng nghĩa là ba chỗ sẽ đổi theo.

Bạn có câu trả lời cho khách ngay trong buổi họp, thay vì hai ngày sau khi kế toán phát hiện ra.

Dạng của dòng tham chiếu cũng đáng học thuộc.

* Dòng bắt đầu bằng `model:ir.model.fields,field_description` là nhãn của một trường, tức chữ này gắn với trường chứ không gắn với màn hình
* dòng `model_terms:ir.ui.view,arch_db` là chuỗi nằm trong định nghĩa của đúng một màn hình
* còn dòng bắt đầu bằng `code` là chuỗi trong mã nguồn, loại phiền nhất.

## Hai đường sửa và hai phạm vi ảnh hưởng

Bên cạnh việc xuất file ra sửa hàng loạt, Odoo còn một đường sửa thứ hai ngay trên form.

Với một trường dịch được, cạnh ô nhập có một nút nhỏ hiện mã ngôn ngữ viết hoa của người dùng, chẳng hạn VI, và nút này chỉ xuất hiện khi hệ thống bật từ hai ngôn ngữ trở lên. Bấm vào thì mở hộp thoại liệt kê từng ngôn ngữ để nhập giá trị cho từng thứ tiếng.

Khác biệt nằm ở phạm vi: **sửa qua hộp thoại chỉ đụng đúng một bản ghi, còn sửa qua file bản dịch thì đụng vào mọi vị trí dùng chung chuỗi gốc**. Tên sản phẩm là ví dụ rõ nhất cho đường thứ nhất, bởi trên Odoo 19 trường tên của sản phẩm cùng ba ô mô tả của nó đều là trường dịch được, nghĩa là mỗi sản phẩm mang bản dịch riêng chứ không có chuyện dịch một lần xong cả danh mục.

Sự phân biệt này phải làm ngay trong buổi khảo sát, bởi hai loại yêu cầu nghe giống nhau nhưng khối lượng chênh rất xa.

Câu đổi chữ trên màn hình cho nhân viên dễ nhìn là **dịch chuỗi giao diện, làm một lần là xong**. Còn câu khách nước ngoài phải nhận báo giá kèm tên hàng bằng tiếng của họ là **dịch nội dung từng bản ghi, khối lượng đi theo số lượng sản phẩm**, và còn cần đặt ngôn ngữ trên form liên hệ của khách, vì chính trường đó quyết định thứ tiếng của email và chứng từ gửi ra.

![Đổi chữ trên màn hình làm một lần là xong, dịch tên hàng thì theo số sản phẩm](https://bahub.vn/uploads/2026/11/1793631643254-wuuko1-viet-hoa-odoo-mot-key-nhieu-noi-2.webp "Đổi chữ trên màn hình làm một lần là xong, dịch tên hàng thì theo số sản phẩm")

## Chỗ sửa được bằng dịch và chỗ phải đổi nhãn trường

Có bốn tình huống, và mỗi tình huống dẫn tới một loại công việc khác nhau.

**Tình huống thứ nhất** là khách muốn một chữ đổi ở mọi nơi và chỉ đổi trong tiếng Việt. Đây đúng là việc của dịch thuật, sửa một cụm trong file là xong.

**Tình huống thứ hai** là khách muốn chữ đó chỉ đổi trên một màn hình còn các màn hình khác giữ nguyên, và dịch thuật không giải được. Bạn phải đặt một nhãn riêng ngay trên chính màn hình đó rồi dịch chuỗi mới sinh ra; nhãn đặt trong định nghĩa màn hình cũng là chuỗi dịch được, và dòng tham chiếu của nó là loại `model_terms` gắn với đúng màn hình đó, nên phạm vi lan dừng lại ở màn hình đó.

**Tình huống thứ ba** là khách muốn đổi cả khi mở hệ thống bằng tiếng Anh, chẳng hạn công ty có chuyên gia nước ngoài. Lúc này phải đổi chính nhãn của trường chứ không phải dịch, và bạn cần nói rõ hai việc đó khác nhau để khách không nghĩ bạn làm nửa vời.

**Tình huống thứ tư** là chỗ phải nói thẳng giới hạn. Nếu chuỗi khách muốn đổi chỉ có dòng tham chiếu loại code thì trên Odoo 19, lúc nhập bản dịch hệ thống bỏ qua toàn bộ các dòng loại này, nghĩa là bạn sửa phần dịch trong file rồi nhập lại vẫn không thấy gì đổi.

Điều khó chịu nhất là **nó bỏ qua trong im lặng**: hệ thống vẫn báo đã nạp bản dịch thành công, không một dòng cảnh báo nào, chỉ có chữ trên màn hình là đứng yên, bởi nhóm chuỗi đó vẫn được đọc thẳng từ file bản dịch nằm trong thư mục module trên đĩa chứ không đọc từ cơ sở dữ liệu.

Muốn đổi thật thì phải sửa file `.po` trong mã nguồn module rồi triển khai lại; việc này cần developer và cần quyền trên hạ tầng, nên nó phải được ghi thành một dòng có chi phí trong tài liệu Fit-Gap chứ không được hứa như một việc cấu hình.

## Bật thêm một ngôn ngữ và những thứ đi kèm

Danh sách ngôn ngữ nằm ở Settings, Translations, Languages, với ba nút Activate, Update và Disable.

Dữ liệu nền của Odoo 19 khai báo sẵn chín mươi ba bản ghi ngôn ngữ, nên thêm một thứ tiếng thường là kích hoạt cái đã có chứ không phải tạo mới.

Một bản ghi ngôn ngữ mang theo nhiều thứ hơn chữ nghĩa, **nó kéo theo cả cách viết số và cách viết ngày**. Bản ghi tiếng Việt dùng dấu phẩy để phân cách phần thập phân, dấu chấm để phân cách hàng nghìn và ngày viết theo thứ tự ngày, tháng, năm, nên sau khi bật tiếng Việt thì báo cáo đổi luôn cách hiển thị con số, và đây là phần ít người để ý nhất.

Ngoài ra ngôn ngữ còn được đặt ở hai cấp độc lập nhau: cấp người dùng quyết định giao diện của riêng người đó, còn cấp liên hệ quyết định thứ tiếng của chứng từ gửi ra ngoài.

## Khối lượng thật của việc Việt hóa trong một dự án

Sai lầm hay gặp khi lập kế hoạch là ghi vào phạm vi công việc một dòng Việt hóa hệ thống rồi coi như xong.

Thực tế **bản dịch mặc định của Odoo chưa hoàn thiện**, và mọi thứ đội dự án thêm vào bằng Studio của bản Enterprise hay bằng code đều chưa có bản dịch nào. Checklist để ước lượng cho đỡ lệch:

* Xuất một bản dịch toàn hệ thống ngay sau khi chốt danh sách phân hệ
* Lọc ra các màn hình người dùng thật sự chạm vào theo tài liệu đặc tả
* Đếm số chuỗi cần đổi so với phần đã có bản dịch sẵn
* Tách riêng những chuỗi chỉ có dòng tham chiếu loại code
* Cộng thêm một lượt dịch sau mỗi đợt tùy biến

Về cách xuất, một người triển khai Odoo lâu năm khuyên nên xuất theo phân hệ và để trống danh sách để lấy trọn hệ thống trong một lượt cho dễ quản lý, đổi lại thời gian xuất lâu hơn hẳn.

![Ước lượng Việt hóa bằng cách đếm chuỗi cần đổi và tách riêng phần phải nhờ developer](https://bahub.vn/uploads/2026/11/1793631647346-th0g7t-viet-hoa-odoo-mot-key-nhieu-noi-3.webp "Ước lượng Việt hóa bằng cách đếm chuỗi cần đổi và tách riêng phần phải nhờ developer")

Cần chú ý thêm một quy tắc nhỏ mà hậu quả không nhỏ. Khi tạo bản ghi mới trong phiên làm việc ở tiếng Việt, hệ thống ghi luôn giá trị đó vào cả khóa tiếng Anh, nên ai đặt thẳng nhãn tiếng Việt cho một trường mới thì chuỗi gốc của trường đó là tiếng Việt, và sau này mở chi nhánh nước ngoài sẽ không còn chuỗi tiếng Anh để dịch sang thứ tiếng thứ ba. Vì vậy **nguyên tắc là đặt nhãn tiếng Anh trước, dịch tiếng Việt sau**.

Việc dịch còn lặp lại về sau, bởi mỗi lần cài hoặc nâng cấp một module, hệ thống nạp file bản dịch của module đó cho mọi ngôn ngữ đang bật, mà bản dịch chính thức thì chưa đầy đủ nên màn hình mới lẫn tiếng Anh với tiếng Việt và người dùng báo lại như một lỗi. Đặc biệt, **không có nhắc nhở nào khi một trường mới chưa có bản dịch**, nên dịch thuật phải nằm trong checklist đóng gói sau mỗi đợt tùy biến.

## Kiểm soát khi nhiều người cùng sửa bản dịch

> Rủi ro lớn nhất ở đây không phải dịch sai chữ mà là mất công của người khác.

Nút Update trên một ngôn ngữ mở ra hộp thoại có ô Overwrite Existing Terms. **Trên Odoo 19 ô này mặc định được tick**, và phần trợ giúp của nó nói thẳng rằng bản dịch tùy chỉnh sẽ bị thay bằng bản chính thức, nên một cú bấm cho gọn tay có thể xóa sạch công của cả tuần mà không có bản lưu nào để hoàn tác.

**Rủi ro thứ hai** đến từ chính cơ chế gom theo chuỗi gốc. Ô ghi đè trên màn hình Import Translation cũng mặc định được tick, mà mỗi chuỗi gốc chỉ mang được một bản dịch trong file, nên nếu hai người đã tạo ra hai cách dịch khác nhau cho cùng một chữ ở hai chỗ, một lượt xuất ra rồi nhập lại sẽ kéo cả hai chỗ về cùng một chữ, và người phát hiện ra thường là người dùng cuối chứ không phải bạn.

Do đó cách làm an toàn là:

* chốt bảng thuật ngữ với khách trước khi dịch dòng đầu tiên
* giao cho đúng một người giữ file bản dịch và nhập lên hệ thống
* đặt tên file kèm ngày xuất để biết bản nào mới hơn
* và ghi lại mỗi lần nhập vào nhật ký triển khai.

Đi kèm là cách viết một dòng yêu cầu Việt hóa cho đủ dùng, gồm:

* chuỗi gốc tiếng Anh
* tên kỹ thuật của trường
* danh sách vị trí bị ảnh hưởng
* quyết định của khách cho từng vị trí
* ngôn ngữ đích
* và tên người duyệt từ ngữ

## Những chỗ cơ chế này không đỡ được

**Dịch thuật là vùng an toàn nhất trong nhóm việc cấu hình**, bởi nó không đụng vào dữ liệu và không đụng vào logic.

Tuy nhiên nó có ba giới hạn cứng.

* Bản dịch mặc định chưa hoàn thiện, nên đừng hứa hệ thống sẽ thuần Việt sau một lượt làm.
* Chuỗi nằm trong mã nguồn không sửa được bằng công cụ trên giao diện của Odoo 19.
* Và mọi phần làm thêm đều kéo theo một lượt dịch nữa.

Ngôn ngữ mới chỉ là lớp ngoài cùng của việc đưa Odoo về Việt Nam. Lớp bên dưới gồm hệ thống tài khoản kế toán, thuế suất, mẫu chứng từ và các quy định phải tuân theo thì nằm ở gói địa phương hóa, và chính lớp đó mới quyết định hệ thống có dùng được cho một pháp nhân Việt Nam hay không.

---

Nguồn: https://bahub.vn/khoa-hoc/erp-cho-ba/viet-hoa-odoo-mot-key-nhieu-noi — Được dùng lại, trích dẫn và đưa cho AI đọc, với điều kiện ghi rõ nguồn bahub.vn kèm link bài gốc.
