First, you learn how to set up the Odoo 17 purchase request feature. Next, you streamline both procurement and internal stock transfers. Then, you follow clear steps and code examples. Also, you see outgoing links to official resources. Finally, you master the entire workflow.
Prerequisites for Odoo 17 Purchase Request
First, you prepare your environment. Then, you ensure you have:
- Odoo 17 installed and running.
- PostgreSQL database ready.
- Access to the OCA repositories.
- Administrative rights in Odoo.
- Basic knowledge of Odoo modules.
Next, you clone the required OCA modules:
# Clone stock request module
git clone https://github.com/OCA/stock-request.git addons/stock_request
# Clone purchase request module
git clone https://github.com/OCA/purchase-request.git addons/purchase_request
Then, you update the Odoo configuration. You add these paths:
[options]
addons_path = /path/to/odoo/addons,/path/to/stock_request,/path/to/purchase_request
Finally, you restart Odoo to load new modules.
Install OCA Purchase Request and Stock Request Modules
Next, you install modules via the Odoo interface:
- Log in as Admin.
- Go to Apps.
- Click Update App List.
- Search for Purchase Request.
- Click Install.
- Then, search for Stock Request and install.
Alternatively, you run a command:
./odoo-bin -d mydb -i purchase_request,stock_request --stop-after-init
You confirm that Odoo installs both modules without errors.
Configure User Access for Purchase Request
Then, you grant rights to users. First, you create two user roles:
- Purchase Request Manager
- Stock Request Officer
Next, you assign these roles proper access:
<record id="group_purchase_request_user" model="res.groups">
<field name="name">Purchase Request User</field>
<field name="category_id" ref="base.module_category_purchase"/>
</record>
<record id="group_purchase_request_manager" model="res.groups">
<field name="name">Purchase Request Manager</field>
<field name="implied_ids" eval="[(4, ref('group_purchase_request_user'))]"/>
</record>
After that, you add rules:
<record id="access_purchase_request_user" model="ir.model.access.csv">
group_id,model_id:id,perm_read,perm_write,perm_create,perm_unlink
group_purchase_request_user,model_purchase_request,1,1,1,0
</record>
Then, you assign users:
- Go to Settings ▶ Users & Companies ▶ Users.
- Edit a user.
- Check Purchase Request User or Purchase Request Manager.
- Save.
Define Internal Stock Request Workflow
First, you set up a route for internal stock requests. Then, you configure operations:
<!-- Define Internal Stock Request Route -->
<record id="route_stock_request" model="stock.location.route">
<field name="name">Internal Stock Request</field>
<field name="route_specs" eval="[(0,0, {
'action': 'pull',
'sequence': 10,
'location_src_id': ref('stock.stock_location_stock'),
'location_id': ref('stock.stock_location_suppliers'),
})]"/>
</record>
Next, you create operations:
<record id="stock_rule_request" model="stock.rule">
<field name="name">Stock Request Rule</field>
<field name="route_id" ref="route_stock_request"/>
<field name="action">pull</field>
<field name="procure_method">make_to_stock</field>
</record>
After that, you enable “Allow to request internal stock” on products:
- Go to Inventory ▶ Products ▶ Products.
- Open a product.
- On Inventory tab, check Allow Internal Stock Request.
- Save.
Create Purchase Request in Odoo 17
Next, you start a new purchase request:
- Go to Purchase ▶ Purchase Requests.
- Click New.
- Enter a title.
- Select the vendor.
- Add line items:
- Product
- Quantity
- Required date
- Choose Internal or RFQ route.
- Save.
Then, you see two tabs: Draft and Confirmed. You confirm the request:
- Click Confirm.
- Odoo creates an RFQ or internal transfer automatically.
- You find linked RFQ under Requests tab.
Configure Approval and Alerts
After that, you set approval workflows:
<record id="purchase_request_approval" model="purchase.request.config.settings">
<field name="approval_group_id" ref="group_purchase_request_manager"/>
</record>
Then, you add email alerts:
<record id="email_template_request_confirm" model="mail.template">
<field name="name">Purchase Request Confirmed</field>
<field name="model_id" ref="model_purchase_request"/>
<field name="email_from">${object.company_id.email or ''}</field>
<field name="subject">Request ${object.name} Confirmed</field>
<field name="body_html">
<![CDATA[
<p>Hello ${object.requester_id.name},</p>
<p>Your request <strong>${object.name}</strong> is confirmed.</p>
]]>
</field>
<field name="partner_to" eval="[(4, ref('base.partner_admin'))]"/>
</record>
You link this template to the action.
Automate Purchase Order Creation
Then, you let Odoo generate a purchase order. You check “Generate Purchase on Confirm”:
- In Settings, enable Auto Create Purchase Order.
- Save.
Next, you test:
# Create a test request
curl -X POST http://localhost:8069/jsonrpc \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"method": "call",
"params": {
"service": "object",
"method": "execute_kw",
"args": ["mydb", 1, "admin", "purchase.request", "create", [{
"name": "Test PR",
"line_ids": [[0, 0, {"product_id": 1, "product_qty": 5}]]
}]]
},
"id": 1
}'
You verify that Odoo creates a linked Purchase Order record.
Test the Complete Process
First, you create both a purchase request and an internal stock request:
- Use product A for internal stock.
- Use product B for purchase.
- Confirm both.
Next, you check Inventory:
- Go to Inventory ▶ Operations ▶ Transfers.
- You see an internal transfer for product A.
- You see a purchase order for product B.
Then, you receive goods:
- Click Receive on transfer.
- Click Validate on purchase order.
- Verify updated stock.
Troubleshooting Tips
First, you clear cache:
./odoo-bin -c /etc/odoo.conf --dev=reload
Next, you check logs:
tail -f /var/log/odoo/odoo-server.log
Then, you ensure that dependencies load correctly. Also, you run:
./odoo-bin -d mydb -u all --stop-after-init
If errors persist, you review your module paths and permissions.
Conclusion
Finally, you complete the Odoo 17 purchase request tutorial. Also, you link to OCA modules for more details:
- OCA Stock Request: https://github.com/OCA/stock-request
- OCA Purchase Request: https://github.com/OCA/purchase-request
You now streamline procurement and internal stock flows. Moreover, you scale this process across your company. Thank you for reading!
Best Practices for Managing Purchase and Stock Requests
First, define clear naming conventions for request records. Next, standardize dates and times across all users. Also, enable automated reminders for pending approvals. Then, archive old requests every quarter. In addition, train staff on how to comment directly in each request to reduce email back‑and‑forth. Finally, review your approval groups biannually to keep them up to date with organizational changes.
Advanced Customizations with OCA Modules
Similarly, you can override core models to add new fields. For example, extend
<record id="purchase_request_view_form" model="ir.ui.view">
<field name="model">purchase.request</field>
<field name="inherit_id" ref="purchase_request.view_purchase_request_form"/>
<field name="arch" type="xml">
<xpath expr="//sheet" position="inside">
<group>
<field name="x_custom_field"/>
</group>
</xpath>
</field>
</record>
Then, inject server‑side logic in Python by overriding create() or write(). Also, register new cron jobs to trigger monthly reports. Lastly, bundle your changes into a new OCA‑compatible addon for easy reuse.
Reporting and Analytics for Requests
Next, leverage Odoo’s built‑in pivot and graph views. First, create a custom report action:
<record id="action_report_purchase_requests" model="ir.actions.act_window">
<field name="name">Purchase Request Report</field>
<field name="res_model">purchase.request</field>
<field name="view_mode">pivot,graph,list</field>
</record>
Then, design a dashboard to show open vs. closed requests, average approval time, and top requesting users. Also, integrate with sale.report or stock.quant to correlate purchase activity with inventory levels.
Security and Access Control
First, audit existing groups with
./odoo-bin shell -d mydb
>>> env['res.groups'].search([]).mapped('name')
Next, add record rules to limit a purchase request to its requester:
<record id="rule_request_owner" model="ir.rule">
<field name="name">Purchase Request: own only</field>
<field name="model_id" ref="model_purchase_request"/>
<field name="domain_force">[('requester_id','=',user.id)]</field>
</record>
Also, disable debug rights for non‑admins. Finally, review ACLs whenever you upgrade Odoo to prevent unauthorized data access.
Real‑World Scenarios and Use Cases
For multi‑company setups, enable inter‑company rules so you can request stock from sister locations. Then, route internal transfers automatically to the correct source warehouse. Also, in drop‑ship scenarios, configure the purchase request to generate a vendor drop‑ship order. Moreover, in manufacturing plants, link purchase requests to MOs (Manufacturing Orders) for raw materials. As a result, you maintain a single workflow for both procurement and production.
Performance Optimization Tips
First, run Odoo with workers in production:
[options]
workers = 4
max_cron_threads = 1
Next, enable ir.logging only at warning level. Then, set PostgreSQL parameters (e.g. shared_buffers, work_mem) according to your RAM. Also, periodically vacuum your database with
VACUUM ANALYZE;
Finally, monitor slow queries via pg_stat_statements and add indexes on frequently searched fields like state and date_deadline.
Frequently Asked Questions (FAQs)
Q1: Can I auto‑approve small requests?
Yes. You can add a server action that checks total cost and auto‑confirms if it falls below a threshold.
Q2: How do I notify managers?
Use an email template triggered by an automated action on status change.
Q3: Can I customize the approval flow?
Absolutely. Leverage OCA’s workflow engine or write custom Python hooks in purchase.request.
Q4: How do I revert a request?
Mark it “Cancelled” and configure a button that resets related stock moves or RFQs.
Q5: Is multi‑currency supported?
Yes, Odoo handles multi‑currency. Set currencies on companies, then the module will convert automatically.
Integrating with External Systems
Also, you can link purchase requests to external e‑procurement platforms via REST APIs. First, define a scheduled job that reads pending requests and pushes JSON payloads to the partner’s endpoint. Next, handle callbacks to update request status. Then, map vendor codes between Odoo and the external system using a translation table. Moreover, secure each call with OAuth2 or API keys. Finally, log all exchanges in a custom model for audit trails.
Future Roadmap and Upgrades
Finally, plan your upgrade to Odoo 18 by reviewing OCA’s purchase-request branch for compatibility notes. Then, test your customizations in a staging environment. Also, track any deprecations in the Odoo core. Moreover, contribute your enhancements back to OCA to benefit the community. Therefore, you stay ahead of feature releases and minimize migration costs.
Discover more from teguhteja.id
Subscribe to get the latest posts sent to your email.


Pingback: Odoo Purchase Report Wizard Hacks : 5 Epic