Skip to content

Odoo 18 ecommerce controller

  • Odoo
Odoo 18 ecommerce controller

Partner-Based Product Restriction

Odoo 18 ecommerce controller lets you limit storefront products per customer effortlessly. First, you will set up a custom module. Next, you will add partner fields and override the /shop route. Then, you will update QWeb templates to reflect filtered products. Moreover, you will test user flows and handle errors. Finally, you will follow best practices to maintain your code.


Understanding Odoo 18 ecommerce controller

First, Odoo processes web requests through controllers. Consequently, you can intercept and modify default behavior. In ecommerce, the website_sale module uses a controller to render product listings. Therefore, you override that controller to filter products by partner.

What Is an Ecommerce Controller?

An ecommerce controller is a Python class under controllers/ that defines routes (URLs). For instance, /shop maps to the product catalog. Moreover, the controller handles request context, user session, and rendering QWeb templates.

Why Override the Shop Controller?

By default, Odoo shows all products on /shop. However, you may need to show only specific products to certain customers. For example, wholesalers may see B2B-only items. Therefore, you override the shop controller to apply partner-based filters before rendering.


Prerequisites

Before you begin, ensure you have:

  1. Odoo 18 CE/EE installed and running.
  2. Developer Mode enabled (Settings → General Settings → Activate the developer mode).
  3. The website_sale module installed for ecommerce.
  4. A user account with Technical Features and Website access.
  5. Access to the file system and ability to restart the Odoo service.

Module Structure

First, create a new custom module directory under your addons path:

custom_addons/odoo18_ecommerce_controller/
├── init.py
├── manifest.py
├── controllers/
│ └── main.py
├── models/
│ └── partner.py
└── views/
└── ecommerce_templates.xml
  • controllers/main.py Defines your custom route logic.
  • models/partner.py Adds a Many2many field allowed_product_ids on res.partner.
  • views/ecommerce_templates.xml Overrides QWeb templates to use filtered products.

Defining the Manifest

Next, open __manifest__.py and configure your module:



```python
{
    'name': 'Ecommerce Controller Restrict Products',
    'version': '1.0',
    'summary': 'Odoo 18 ecommerce controller for partner-based product restriction',
    'category': 'Website',
    'author': 'Your Name',
    'depends': ['website_sale'],
    'data': [
        'views/ecommerce_templates.xml',
    ],
    'installable': True,
    'application': False,
}

First, you set depends to website_sale. Then, you list your QWeb template file under data. Finally, you mark the module installable.


Extending the Partner Model

Then, add a new field to res.partner so you can assign allowed products:

models/partner.py

from odoo import fields, models

class ResPartner(models.Model):
    _inherit = 'res.partner'

    allowed_product_ids = fields.Many2many(
        comodel_name='product.product',
        string='Allowed Products',
        help='Select products that this partner can view in the shop'
    )

First, you inherit res.partner. Next, you declare allowed_product_ids as a Many2many to product.product. Then, you provide a label and help text for clarity.


Implementing the Ecommerce Controller

Now, override the shop controller to filter products before rendering:

controllers/main.py

from odoo import http
from odoo.http import request

class EcommerceRestrictController(http.Controller):
    @http.route(['/shop'], type='http', auth='public', website=True)
    def shop(self, **kwargs):
        # Get the current user’s partner record
        partner = request.env.user.partner_id

        # Fetch all saleable products
        Product = request.env['product.product'].sudo()
        products = Product.search([('sale_ok', '=', True)])

        # Filter by allowed_product_ids if set
        allowed = partner.allowed_product_ids
        if allowed:
            products = products.filtered(lambda p: p in allowed)

        # Prepare rendering context
        values = {
            'products': products,
            'category': False,
            'search': kwargs.get('search', False),
        }

        # Render the standard webshop template with filtered products
        return request.render('website_sale.products', values)
  1. You define a route for /shop with auth='public' and website=True.
  2. You obtain the partner via request.env.user.partner_id.
  3. You search for products with sale_ok=True.
  4. If the partner has allowed_product_ids, you filter products.
  5. Finally, you call request.render on the website_sale.products template with your filtered list.

Overriding the QWeb Template

After overriding the controller, ensure your templates use the passed products:

views/ecommerce_templates.xml

<odoo>
  <template id="products_inherit" inherit_id="website_sale.products">
    <xpath expr="//t[@t-call='website_sale.products_list']" position="replace">
      <!-- Use the filtered 'products' from our controller -->
      <t t-call="website_sale.products_list"/>
    </xpath>
  </template>
</odoo>

First, you inherit the website_sale.products template. Then, you replace the call to website_sale.products_list with itself—this step ensures Odoo uses your products variable from the controller context.


Testing the Module

Now, install and test your module:

  1. Restart your Odoo server and update apps (-u all or via UI).
  2. Install “Ecommerce Controller Restrict Products” from the Apps menu.
  3. Navigate to Website → Configuration → Contacts.
  4. Edit a partner record and choose several Allowed Products.
  5. Log in as that partner (or create a portal user linked to the partner).
  6. Visit /shop and confirm you see only the allowed products.
  7. Test an unlisted partner to ensure they see the full catalog or no products.

Adding an Outgoing Link

Moreover, for advanced customization and best practices, refer to the official Odoo documentation on controllers and website development:
https://www.odoo.com/documentation/18.0/developer/howtos/website.html


Common Pitfalls & Troubleshooting

Controller Not Invoked

  • Ensure no other module overrides /shop.
  • Check that your controller file is under controllers/ and Python syntax is correct.

Products Still Show All Items

  • Verify sale_ok=True filter and allowed_product_ids assignment.
  • Clear Odoo cache: restart server and run with --dev=reload or clear web.assets_backend.

Access Rights Issues

  • Ensure your portal users have group Website / Portal and no conflicting record rules.
  • Test with a freshly created portal user linked to your partner.

Best Practices

  1. Use sudo() when reading product.product in public routes to avoid access errors.
  2. Cache filtered product lists if performance suffers under high traffic.
  3. Modularize by moving filter logic into a service class or method for reuse.
  4. Document each override clearly for future maintainers.

Conclusion

In this tutorial, you mastered how to use an Odoo 18 ecommerce controller to restrict products by partner. First, you set up the module and manifest. Next, you extended res.partner with a new field. Then, you overrode the /shop route and updated QWeb templates. Moreover, you tested user flows and handled common errors. Finally, you reviewed best practices and linked to the official Odoo docs.

With this implementation, you can tailor your e-commerce catalog per customer, boost B2B workflows, and maintain a clean codebase. Happy coding!


Discover more from teguhteja.id

Subscribe to get the latest posts sent to your email.

Leave a Reply

WP Twitter Auto Publish Powered By : XYZScripts.com