Browse Source

first working version

davidmscholz 2 days ago
parent
commit
45566df814

+ 6 - 6
__manifest__.py

@@ -1,12 +1,11 @@
 # -*- coding: utf-8 -*-
 {
-    'name': "set_customer_groups",
+    'name': "product_page_access",
 
     'summary': "Add users to groups based on their purchases.",
 
     'description': """
-    When a user makes a purchase through the eCommerce store add the user to one or multiple groups as defined in 
-    a mapping.
+        Restrict page access based on product purchases
     """,
 
     'author': "dmsc.dev",
@@ -15,15 +14,16 @@
     # Categories can be used to filter modules in modules listing
     # Check https://github.com/odoo/odoo/blob/15.0/odoo/addons/base/data/ir_module_category_data.xml
     # for the full list
-    'category': 'Technical',
+    'category': 'Website',
     'version': '0.1',
 
     # any module necessary for this one to work correctly
-    'depends': ['base', 'website_sale'],
+    'depends': ['base', 'website', 'website_sale', 'sale'],
 
     # always loaded
     'data': [
-        # 'security/ir.model.access.csv',
+        'security/product_page_access_security.xml',
+        'security/ir.model.access.csv',
         'views/views.xml',
         'views/templates.xml',
     ],

BIN
controllers/__pycache__/controllers.cpython-312.pyc


+ 57 - 16
controllers/controllers.py

@@ -1,22 +1,63 @@
 # -*- coding: utf-8 -*-
-# from odoo import http
+import logging
+from odoo import exceptions, http, models
+from odoo.http import request
 
+_logger = logging.getLogger(__name__)
 
-# class SetCustomerGroups(http.Controller):
-#     @http.route('/set_customer_groups/set_customer_groups', auth='public')
-#     def index(self, **kw):
-#         return "Hello, world"
+class RestrictedPageController(http.Controller):
+    @http.route(
+        '/restricted-content/<string:slug>',
+        type='http',
+        auth='user',
+        website=True,
+        sitemap=False,
+        priority=99
+    )    
 
-#     @http.route('/set_customer_groups/set_customer_groups/objects', auth='public')
-#     def list(self, **kw):
-#         return http.request.render('set_customer_groups.listing', {
-#             'root': '/set_customer_groups/set_customer_groups',
-#             'objects': http.request.env['set_customer_groups.set_customer_groups'].search([]),
-#         })
+    def restricted_page(self, slug, **kw):
+        # Find the website.page that matches the slug
+        _logger.debug("restricted_page: slug=%s | user=%s (%s)",
+                    slug, request.env.user.login, request.env.user.id)
+        page = request.env['website.page'].sudo().search([
+            ('url', '=', '/restricted-content/%s' % slug)
+        ], limit=1)
+        if not page:
+            return request.not_found()
 
-#     @http.route('/set_customer_groups/set_customer_groups/objects/<model("set_customer_groups.set_customer_groups"):obj>', auth='public')
-#     def object(self, obj, **kw):
-#         return http.request.render('set_customer_groups.object', {
-#             'object': obj
-#         })
+        # Load the product_page_access mapping for this page
+        mapping = request.env['product_page_access.page_product_mapping'].sudo().search([
+            ('page', '=', page.id)
+        ], limit=1)
+        if not mapping:
+            # no allowlist defined → redirect to shop
+            _logger.debug("restricted_page: no mapping for page_id=%s, redirecting", page.id)
+            return request.redirect('/')
 
+        _logger.debug("restricted_page: allowed_product=%s", mapping.products.ids)
+
+        if not mapping.products:
+            # empty list → redirect
+            _logger.debug("restricted_page: empty product for page_id=%s, redirecting",
+                          page.id)
+            return request.redirect('/')
+
+        # Check if the user ever bought at least one of them
+        user = request.env.user
+        has_access = request.env['sale.order.line'].sudo().search_count([
+            ('order_id.partner_id', 'child_of', user.partner_id.id),
+            ('order_id.state', 'in', ('sale', 'done')),
+            ('product_id', 'in', mapping.products.ids),
+        ], limit=1)
+
+        _logger.debug("restricted_page: user_id=%s has_access=%s", user.id, has_access)
+
+        if not has_access:
+            # Redirect to the shop so the user can buy
+            _logger.debug("restricted_page: user_id=%s has_access=%s", user.id, has_access)
+
+            return request.redirect(mapping.link_out_product.website_url)
+
+        # 5. Everything fine – render the page
+        _logger.debug("restricted_page: rendering page.key=%s", page.key)
+        return request.render(page.key, {})

BIN
models/__pycache__/models.cpython-312.pyc


+ 12 - 7
models/models.py

@@ -1,13 +1,18 @@
 # -*- coding: utf-8 -*-
 
-from odoo import models, fields
+from odoo import api, models, fields, Command
 
 
-class CustomerGroupMapping(models.Model):
-    _name = 'set_customer_groups.set_customer_groups'
-    _description = 'set_customer_groups.set_customer_groups'
+class PageProductMapping(models.Model):
+    _name = 'product_page_access.page_product_mapping'
+    _description = 'Page Product Mapping'
 
-    page = fields.Many2one('website.page', ondelete = 'cascade')
-    group = fields.Many2many('res.groups')
-    product = fields.Many2one('product.product')
+    # for each page there is one list of products that grant access to it
+    page = fields.Many2one('website.page', ondelete = 'cascade', string='Page')
+    
+    # the product directly associated with the page
+    link_out_product = fields.Many2one('product.product', string='Product') 
+
+    # products that grant access to the page
+    products = fields.Many2many('product.product', string='Acessing Products')
 

+ 2 - 1
security/ir.model.access.csv

@@ -1,2 +1,3 @@
 id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_set_customer_groups_set_customer_groups,set_customer_groups.set_customer_groups,model_set_customer_groups_set_customer_groups,base.group_user,1,1,1,1
+product_page_mapping_manager_id,product_page_access.manager,model_product_page_access_page_product_mapping,group_product_page_access_manager,1,1,1,1
+product_page_mapping_user_id,product_page_access.user,model_product_page_access_page_product_mapping,group_product_page_access_user,1,0,0,0

+ 17 - 0
security/product_page_access_security.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+    <record id="module_category_product_page_access" model="ir.module.category">
+        <field name="name">Product Page Access Management</field>
+        <field name="sequence">31</field>
+    </record>
+    <record id="group_product_page_access_manager" model="res.groups">
+        <field name="name">Product Page Access Manager</field>
+        <field name="category_id" ref="module_category_product_page_access"/>
+        <field name="users"
+            eval="[(4, ref('base.user_root')),(4, ref('base.user_admin'))]"/>
+    </record>
+    <record id="group_product_page_access_user" model="res.groups">
+        <field name="name">Product Page Access User</field>
+        <field name="category_id" ref="module_category_product_page_access"/>
+    </record>
+</odoo>

+ 16 - 46
views/views.xml

@@ -1,60 +1,30 @@
 <odoo>
   <data>
     <!-- explicit list view definition -->
-<!--
-    <record model="ir.ui.view" id="set_customer_groups.list">
-      <field name="name">set_customer_groups list</field>
-      <field name="model">set_customer_groups.set_customer_groups</field>
+    <record model="ir.ui.view" id="product_page_access.list">
+      <field name="name">product_page_access list</field>
+      <field name="model">product_page_access.page_product_mapping</field>
       <field name="arch" type="xml">
         <list>
-          <field name="name"/>
-          <field name="value"/>
-          <field name="value2"/>
+          <field name="page"/>
+          <field name="link_out_product"/>
+          <field name="products"/>
         </list>
       </field>
     </record>
--->
 
     <!-- actions opening views on models -->
-<!--
-    <record model="ir.actions.act_window" id="set_customer_groups.action_window">
-      <field name="name">set_customer_groups window</field>
-      <field name="res_model">set_customer_groups.set_customer_groups</field>
+    <record model="ir.actions.act_window" id="product_page_access.action_window">
+      <field name="name">product_page_access window</field>
+      <field name="res_model">product_page_access.page_product_mapping</field>
       <field name="view_mode">list,form</field>
     </record>
--->
 
-    <!-- server action to the one above -->
-<!--
-    <record model="ir.actions.server" id="set_customer_groups.action_server">
-      <field name="name">set_customer_groups server</field>
-      <field name="model_id" ref="model_set_customer_groups_set_customer_groups"/>
-      <field name="state">code</field>
-      <field name="code">
-        action = {
-          "type": "ir.actions.act_window",
-          "view_mode": "list,form",
-          "res_model": model._name,
-        }
-      </field>
-    </record>
--->
-
-    <!-- Top menu item -->
-<!--
-    <menuitem name="set_customer_groups" id="set_customer_groups.menu_root"/>
--->
-    <!-- menu categories -->
-<!--
-    <menuitem name="Menu 1" id="set_customer_groups.menu_1" parent="set_customer_groups.menu_root"/>
-    <menuitem name="Menu 2" id="set_customer_groups.menu_2" parent="set_customer_groups.menu_root"/>
--->
-    <!-- actions -->
-<!--
-    <menuitem name="List" id="set_customer_groups.menu_1_list" parent="set_customer_groups.menu_1"
-              action="set_customer_groups.action_window"/>
-    <menuitem name="Server to list" id="set_customer_groups" parent="set_customer_groups.menu_2"
-              action="set_customer_groups.action_server"/>
--->
+    <menuitem 
+        name="Product Page Mappings" 
+        id="product_page_access_menu_root" 
+        parent="website_sale.menu_ecommerce"
+        action="product_page_access.action_window"
+        sequence="10"/>
   </data>
-</odoo>
+</odoo>