---
title: "Phân hệ Mua hàng của Odoo và bài toán trình ký theo hạn mức"
url: "https://bahub.vn/khoa-hoc/erp-cho-ba/purchase-odoo-phe-duyet-mua-hang"
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."
---

# Phân hệ Mua hàng của Odoo và bài toán trình ký theo hạn mức

> RFQ và PO thật ra là một bản ghi, đơn mua đi qua năm trạng thái, và cấu hình duyệt hai cấp của Odoo 19 chỉ có đúng một ngưỡng ở cấp công ty.

- Nguồn: https://bahub.vn/khoa-hoc/erp-cho-ba/purchase-odoo-phe-duyet-mua-hang
- 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: Phân hệ Odoo

Buổi demo phân hệ Mua hàng vừa xong. Luồng chuẩn chạy chưa tới năm phút, từ yêu cầu báo giá tới phiếu nhận hàng bên phân hệ Kho, không vấp một chỗ nào.

Rồi trưởng nhóm mua hàng mở ngăn kéo, lấy ra một tập tờ trình đã ký, mỗi tờ có ba ô chữ ký ở ba chỗ khác nhau, và hỏi hai câu: chỗ nào trên màn hình vừa rồi để trưởng phòng ký duyệt hả em, và cái gì ngăn một nhân viên tự xác nhận một đơn hai trăm triệu.

Phần demo vừa rồi không trả lời được câu nào.

> Người demo thường tin rằng trình ký chỉ là bật thêm một ô cấu hình, và chỗ sai nằm ngay trong cái màn hình vừa chạy mượt đó: bạn đang đăng nhập bằng tài khoản quản trị.

Khoảng cách giữa hai câu hỏi ấy với cái bạn vừa demo là nội dung của bài này, và nó phải bắt đầu từ quy trình mua thật chứ không phải từ màn hình. Toàn bộ phần cơ chế trong bài 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ớ.

## Quy trình mua thật ở phía khách hàng

Trước khi mở hệ thống, hãy nhìn quy trình khách đang chạy trên giấy.

Trong phần lớn doanh nghiệp tôi từng khảo sát, **việc mua một món hàng không bắt đầu ở bộ phận mua hàng mà ở bộ phận có nhu cầu**, dưới dạng một đề nghị mua viết tay hoặc gõ trên Excel đã có chữ ký của trưởng bộ phận. Sau đó mới tới phần việc của nhóm mua hàng, và gần như luôn gồm ba việc đi liền nhau:

1. xin báo giá của vài nhà cung cấp
2. lập bảng so sánh giá, thời gian giao và điều khoản thanh toán
3. rồi chọn nhà cung cấp để trình lên.

Số báo giá tối thiểu nằm trong quy chế nội bộ của từng doanh nghiệp chứ không phải chuẩn chung, nên bạn phải hỏi chứ đừng đoán.

Tiếp theo là bước trình ký, và đây là chỗ không doanh nghiệp nào giống doanh nghiệp nào. Có nơi chia theo giá trị đơn, dưới một mức thì trưởng phòng duyệt là xong, trên mức đó phải lên giám đốc; có nơi vừa chia theo giá trị vừa chia theo phòng ban đề nghị, tức cùng một số tiền nhưng phòng này duyệt tại chỗ còn phòng kia thì không.

Cần lưu ý rằng chuỗi này chạy trên giấy, nên nó có hai đặc tính mà bạn phải mang theo khi thiết kế. **Nó không chặn được ai**, vì một người vẫn có thể gọi điện đặt hàng trước rồi hợp thức hóa giấy tờ sau; và **nó không tra cứu được**, vì tìm lại ai đã duyệt cái gì vào ngày nào là cả một buổi lục hồ sơ.

## Một bản ghi mang hai cái tên

Chỗ hiểu lầm đầu tiên khi ánh xạ quy trình trên vào Odoo nằm ở hai cái tên.

Trong đầu khách hàng, yêu cầu báo giá và đơn đặt hàng là hai văn bản, mỗi thứ có mẫu riêng và số hiệu riêng. Trên Odoo 19 thì không phải vậy: **RFQ và Purchase Order là cùng một bản ghi trên cùng một đối tượng dữ liệu**, chỉ khác nhau ở giá trị của trường trạng thái, và bản ghi đó được cấp số hiệu ngay từ lúc tạo chứ không chờ tới lúc thành đơn chính thức.

Trường trạng thái có đúng năm giá trị, và nhãn của chúng kể gần hết câu chuyện:

1. lúc mới tạo là RFQ
2. kế tiếp là RFQ Sent tức đã gửi yêu cầu báo giá
3. rồi To Approve tức chờ phê duyệt
4. rồi Purchase Order
5. và cuối cùng là Cancelled.

Thanh trạng thái trên form bình thường chỉ hiện ba nấc RFQ, RFQ Sent và Purchase Order, còn nấc chờ phê duyệt, trên giao diện tiếng Việt là Cần phê duyệt, chỉ hiện ra khi đơn thật sự rơi vào đó.

Do đó khi nói với khách rằng hệ thống có quản lý yêu cầu báo giá, hãy nói kèm hệ quả: **cùng một mã số đi suốt từ yêu cầu báo giá tới đơn đặt hàng**, nên nếu quy chế bắt đơn đặt hàng phải mang dãy số riêng thì đó là khoảng trống phải ghi nhận ngay từ buổi khảo sát.

![Yêu cầu báo giá và đơn đặt hàng là cùng một bản ghi, cùng một số hiệu](https://bahub.vn/uploads/2026/11/1793631354259-buw5d5-purchase-odoo-phe-duyet-mua-hang-1.webp "Yêu cầu báo giá và đơn đặt hàng là cùng một bản ghi, cùng một số hiệu")

Bên cạnh đó, **việc chuyển từ RFQ sang RFQ Sent không đi qua nút duyệt nào cả**. Nó xảy ra như một hệ quả khi người dùng gửi yêu cầu báo giá qua email bằng nút Send RFQ, hoặc khi bấm in yêu cầu báo giá, tức trạng thái này ghi lại một hành động giao tiếp với bên ngoài chứ không phải một bước duyệt nội bộ. Chi tiết này đáng nói với khách, bởi nhiều người nhìn hai trạng thái đầu rồi tưởng đó là duyệt hai bước.

## Những gì mỗi lần đổi trạng thái kéo theo

Trạng thái trong Odoo không phải nhãn dán, bởi mỗi lần chuyển đều kéo theo dữ liệu được sinh ra hoặc bị khóa lại.

Điểm đáng chú ý nhất là **phiếu nhận hàng chỉ được sinh ra khi đơn thật sự sang Purchase Order**, tức ở bước phê duyệt chứ không phải ở cú bấm Confirm Order. Với đơn không cần duyệt thì hai việc xảy ra liền nhau nên không ai để ý. Đồng thời phiếu chỉ được sinh ra khi đơn có ít nhất một dòng là sản phẩm loại Goods.

Từ đó rút ra hai hệ quả: đơn mua toàn dịch vụ không sinh phiếu kho nào, và đơn đang chờ phê duyệt thì bên kho chưa nhìn thấy gì cả. Khi khách hỏi vì sao thủ kho không thấy phiếu nhập dù người mua nói đã đặt hàng, chỗ đầu tiên cần mở ra xem là trạng thái của đơn.

Ở chiều ngược lại, nút Cancel bị chặn khi đơn đang khóa hoặc đã có hóa đơn nhà cung cấp ở trạng thái khác nháp và khác hủy. Chưa vướng hai điều kiện đó thì đơn hủy được, và từ trạng thái Cancelled hệ thống cho đưa bản ghi về nháp bằng nút Set to Draft.

Đây là đường người dùng thật sự đi khi nhà cung cấp báo lại giá sau khi đơn đã chốt, và nó có một hệ quả mà tôi sẽ quay lại ở cuối bài, đó là đơn đi lại từ nháp thì phải qua lại bước xác nhận.

Ngoài ra còn một cấu hình hay bị bỏ qua, đó là tùy chọn **Lock Confirmed Orders**. Bật lên thì đơn vừa được duyệt sẽ tự khóa, và chỉ người thuộc nhóm Administrator của phân hệ Mua hàng mới thấy nút mở khóa; để mặc định thì đơn vẫn sửa được sau khi duyệt.

> Lựa chọn này ảnh hưởng trực tiếp tới giá trị của bước duyệt, bởi đơn vẫn sửa được sau khi duyệt thì dấu vết phê duyệt chỉ chứng minh đơn từng được duyệt, chứ không chứng minh cái đang nằm trên màn hình bây giờ chính là cái đã được duyệt.

## Trường Vendor Reference

Chỗ hiểu sai kinh điển nhất trên form đơn mua nằm ở một trường nhỏ, và nó sai theo cùng một kiểu ở gần như mọi dự án.

Trường này có nhãn tiếng Anh là Vendor Reference, còn trên giao diện tiếng Việt của Odoo 19 nó hiện thành Mã nhà cung cấp. Nhìn cái nhãn đó, phần lớn người dùng tưởng đây là mã định danh của nhà cung cấp trong hệ thống rồi đem mã đó điền vào. Thực tế mã nhà cung cấp nằm trong hồ sơ liên hệ của chính họ, còn **trường này giữ mã đơn hàng do phía nhà cung cấp phát hành**, tức số hiệu đơn bán bên họ hoặc bản chào giá họ gửi sang.

Phần mô tả của trường nói rõ mục đích: mã này dùng để đối chiếu khi nhận hàng, bởi nó thường được in trên phiếu giao hàng mà nhà cung cấp mang tới. Do đó hãy giải thích trường này bằng đúng tình huống kho nhận hàng chứ đừng giải thích bằng định nghĩa, vì **người mua chỉ chịu điền khi thấy có người khác cần tới nó**, và nếu dự án có chỉnh bản dịch thì đây là nhãn đáng sửa đầu tiên.

![Mã đơn của nhà cung cấp là thứ kho dùng để đối chiếu khi nhận hàng](https://bahub.vn/uploads/2026/11/1793631355971-0vhop9-purchase-odoo-phe-duyet-mua-hang-2.webp "Mã đơn của nhà cung cấp là thứ kho dùng để đối chiếu khi nhận hàng")

## Cấu hình phê duyệt hai cấp trong phân hệ Mua hàng

Quay lại hai câu hỏi ở đầu bài, Odoo có sẵn cơ chế cho chuyện này, và nó nằm ngay trong phần cấu hình của phân hệ Mua hàng chứ không ở một phân hệ riêng.

Tùy chọn bạn bật lên mang nhãn Purchase Order Approval, và bật nó thực chất là **chuyển cấu hình số cấp duyệt của công ty từ một bước sang hai bước**. Đi kèm là một trường số tiền mang nhãn Minimum Amount, lưu ở cấp công ty: từ số tiền đó trở lên thì đơn bắt buộc phải qua một người duyệt.

Hành vi khi bấm Confirm Order do một phép kiểm tra ba vế quyết định, và chỉ cần một vế đúng là đơn được duyệt luôn.

* **Vế thứ nhất là công ty đang để chế độ một bước**, khi đó đơn đi thẳng sang Purchase Order.
* **Vế thứ hai là chế độ hai bước nhưng tổng giá trị đơn nhỏ hơn ngưỡng**, và ở vế này có ba chi tiết phải nói rõ với khách: con số đem so là tổng đã gồm thuế chứ không phải tổng trước thuế; phép so là nhỏ hơn nghiêm ngặt, nên một đơn bằng đúng ngưỡng vẫn phải qua duyệt; còn ngưỡng thì được quy đổi từ đồng tiền công ty sang đồng tiền của đơn theo ngày đặt hàng, nên với đơn ngoại tệ thì kết quả phụ thuộc tỷ giá của đúng ngày đó.
* **Vế thứ ba trả lời tình huống ở đầu bài**: người bấm thuộc nhóm Administrator của phân hệ Mua hàng thì đơn được duyệt luôn bất kể giá trị bao nhiêu, mà tài khoản quản trị mặc định lại nằm sẵn trong nhóm này, nên trên màn hình demo của chính bạn trạng thái chờ duyệt không bao giờ xuất hiện.

Khi cả ba vế đều không thỏa thì đơn sang To Approve, và phải có một người thuộc nhóm Administrator bấm Approve Order thì bản ghi mới sang Purchase Order; lúc đó hệ thống ghi lại thời điểm phê duyệt và sinh phiếu nhận hàng như đã nói ở trên.

Vì vậy khi dựng thử tính năng này, **bạn bắt buộc phải tạo một tài khoản chỉ có quyền User của phân hệ Mua hàng** và đăng nhập song song ở một trình duyệt khác. Bỏ qua bước đó thì bạn sẽ dò lại cấu hình cả buổi mà không hiểu vì sao.

## Ba chỗ khiến cấu hình sẵn có không khớp quy chế của khách

Tới đây phần dễ đã xong, phần còn lại là chỗ bạn phải nói thật với khách.

* **Chỗ chênh thứ nhất là số cấp**, và khách nhìn ra ngay: cấu hình sẵn có chỉ cho bạn hai lựa chọn, hoặc duyệt thẳng hoặc qua một người duyệt, trong khi tập tờ trình trong ngăn kéo có ba ô chữ ký.
* **Chỗ chênh thứ hai là phạm vi của ngưỡng**, cũng chính là ví dụ mà bài về ba tầng tài liệu đã dùng: số tiền đó lưu ở cấp công ty, nghĩa là cả công ty dùng chung một ngưỡng, còn quy chế doanh nghiệp thì thường đặt hạn mức khác nhau cho từng chức danh hoặc từng phòng ban.
* **Chỗ chênh thứ ba là bản chất của người duyệt**, và đây là chỗ đắt nhất. Hệ thống xác định người duyệt bằng nhóm quyền chứ không bằng vị trí trong sơ đồ tổ chức, nên mọi người trong nhóm Administrator đều duyệt được mọi đơn, chính họ cũng tự xác nhận đơn của mình mà không qua ai, và khái niệm cấp trên trực tiếp của người tạo đơn không tồn tại trong cấu hình mặc định.

Ba chỗ chênh trên đều là khoảng trống thật. Cách viết một dòng yêu cầu cho bài toán này ở ba tầng tài liệu thì bài về [BRD, FRD và SRS](https://bahub.vn/khoa-hoc/erp-cho-ba/brd-frd-srs-du-an-erp) đã làm mẫu, nên ở đây tôi chỉ nói hướng xử lý. Trước khi kết luận phải lập trình, hãy đi lại thang tìm phương án ở bài về [một dòng GAP tới giải pháp](https://bahub.vn/khoa-hoc/erp-cho-ba/tu-gap-toi-giai-phap-khach-chot). [Ranh giới giữa cấu hình và customize](https://bahub.vn/khoa-hoc/erp-cho-ba/cau-hinh-hay-customize-erp) thuộc về một bài riêng, còn ở đây chỉ cần nhớ rằng **ngưỡng chung cấp công ty là cấu hình, còn hạn mức riêng theo từng người thì không**.

![Tờ trình có ba ô chữ ký, cấu hình sẵn có chỉ có hai bước](https://bahub.vn/uploads/2026/11/1793631359039-qqwueq-purchase-odoo-phe-duyet-mua-hang-3.webp "Tờ trình có ba ô chữ ký, cấu hình sẵn có chỉ có hai bước")

Nếu khách chạy bản Enterprise thì thang đó có thêm một nấc không cần code, là approval rule của Studio gắn lên chính nút Confirm Order. Theo tài liệu chính thức của Odoo 19, một nút có thể mang nhiều bước duyệt, mỗi bước có điều kiện riêng, người duyệt khai theo từng người dùng hoặc theo nhóm, và có thể ủy quyền cho người khác.

Nấc này giải được một phần chỗ chênh thứ nhất và thứ hai, nhưng **người duyệt vẫn không phải là cấp trên của người tạo đơn**, và cái giá của nó là Studio cùng gói license đi kèm như bài về [có tính năng và đáp ứng yêu cầu](https://bahub.vn/khoa-hoc/erp-cho-ba/co-tinh-nang-khong-dong-nghia-dap-ung) đã phân tích.

Đồng thời có một giới hạn phải ghi nhận thẳng. Odoo còn có app Approvals dùng chung cho nhiều loại yêu cầu, nhưng app này không có trong bản Community. Tôi chưa dựng lại trên Odoo 19 Enterprise để xác nhận nó có chặn được thao tác xác nhận đơn mua hay không, nên bài này không đưa nó vào như một phương án; với đơn bán thì yêu cầu duyệt đứng riêng không tự chặn nút xác nhận, và bạn nên mặc định nghi ngờ điều tương tự ở đơn mua cho tới khi tự dựng được.

## Câu hỏi phải hỏi khách trước khi chốt phương án phê duyệt

> Phần lớn thời gian bạn tốn cho bài toán này về sau đến từ những câu đã không hỏi trong khảo sát.

**Đầu tiên là nhóm câu về ngưỡng**: hạn mức tính trên giá trị trước thuế hay sau thuế, tính trên từng đơn hay trên tổng giá trị đặt cho một nhà cung cấp trong một kỳ, và với đơn ngoại tệ thì quy đổi theo tỷ giá ngày nào. Hệ thống so trên tổng đã gồm thuế của đúng một đơn theo tỷ giá ngày đặt hàng, nên quy chế nào tính trên giá trị trước thuế là đã có ngay một khoảng trống.

**Tiếp theo là nhóm câu về người duyệt**: ai duyệt được đơn của ai, người duyệt vắng mặt thì ai thay và việc ủy quyền có để lại dấu vết không, và người duyệt được sửa đơn trong lúc duyệt hay chỉ được duyệt và trả lại.

Đặc biệt đừng quên câu về việc trả đơn về, bởi trong quy trình giấy thì chuyện sếp gạch một dòng rồi bảo thương lượng lại là chuyện thường ngày, và nó cần một chỗ ghi lý do trên hệ thống chứ không thể chỉ là một cuộc gọi.

**Sau đó là nhóm câu về phạm vi áp dụng**: có loại chi nào được miễn duyệt không, và đơn giá trị nhỏ phát sinh hằng ngày có chạy cùng luồng với đơn mua tài sản không. Khách hay trả lời là như nhau, nên hãy hỏi lại bằng tình huống cụ thể.

**Cuối cùng là câu ít người hỏi nhất nhưng quyết định khối lượng công việc nhiều nhất**: đơn đã duyệt mà giá thay đổi thì quy chế xử lý thế nào.

Trên Odoo 19, **phép so với ngưỡng chỉ chạy khi bấm Confirm Order trên một đơn còn ở RFQ hoặc RFQ Sent**, nghĩa là đơn đã duyệt mà vẫn để sửa được thì có sửa giá trị lên cao hơn ngưỡng cũng không tự quay lại bước duyệt; chỉ khi đơn bị hủy, đưa về nháp rồi xác nhận lại thì phép so mới chạy lại.

Bật Lock Confirmed Orders thì mọi lần sửa phải qua tay người có quyền mở khóa, tức thu hẹp khoảng trống chứ không lấp được, nên nếu quy chế bắt duyệt lại trong tình huống đó thì bạn đang đứng trước một khoảng trống nữa.

Trước khi chốt phương án, hãy chạy qua những việc sau:

* Chốt hạn mức tính trên giá trị trước thuế hay sau thuế
* Chốt đơn ngoại tệ quy đổi theo tỷ giá ngày nào
* Chốt người thay khi người duyệt vắng mặt và cách để lại dấu vết ủy quyền
* Hỏi lại bằng tình huống mua văn phòng phẩm vài trăm nghìn có phải trình ký không
* Dựng thử bằng một tài khoản chỉ có quyền User của phân hệ Mua hàng
* Ghi nhận GAP nếu quy chế đòi duyệt lại khi giá đổi sau duyệt

Khi bước duyệt đã chốt và đơn sang Purchase Order, phiếu nhận hàng được sinh ra và mọi thứ đi sang phân hệ Kho, nơi mọi biến động đều được mô hình hóa thành một lần dịch chuyển giữa hai vị trí.

---

Nguồn: https://bahub.vn/khoa-hoc/erp-cho-ba/purchase-odoo-phe-duyet-mua-hang — Đượ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.
