Skip to content

Commit f9a8ac4

Browse files
committed
[IMP] super_portal: Implement Super Portal User access
Features: - Created a 'Super Portal User' group with extended portal access. - Introduced 'Edit Portal Access' for managing email and portal access. - Restricted 'Portal View' modifications to Sales Administrators. - Modified contact form: renamed 'Other Address' to 'Company Address,' ensured correct contact type. - Implemented transaction filtering by contact in the portal (Sales Orders, Invoices, POs, Helpdesk). - Established a super branch and branch hierarchy for super and sub branches. - Recomputing prices based on billing address pricelist.
1 parent 460af3f commit f9a8ac4

14 files changed

+632
-0
lines changed

super_portal/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from . import models
2+
from . import controllers

super_portal/__manifest__.py

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
'name': 'Super Portal User',
3+
'category': 'Portal',
4+
'summary': 'Portal access for multi-branch management',
5+
'depends': ['contacts', 'website_sale'],
6+
'data': [
7+
'security/portal_security.xml',
8+
'views/res_partner_views.xml',
9+
'views/portal_wizard_views.xml',
10+
'views/templates.xml',
11+
],
12+
'assets': {
13+
'web.assets_frontend': [
14+
'super_portal/static/src/js/website_sale.js',
15+
'super_portal/static/src/js/address_search.js'
16+
],
17+
},
18+
'licence': 'LGPL-3',
19+
'installable': True,
20+
}

super_portal/controllers/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from . import main
2+
from . import portal

super_portal/controllers/main.py

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
from odoo import http
2+
from odoo.http import request
3+
from odoo.addons.website_sale.controllers.main import WebsiteSale
4+
from werkzeug.exceptions import Forbidden
5+
6+
class WebsiteSalePortal(WebsiteSale):
7+
8+
#-------------------------------------------------------------------------------#
9+
# Arrange branches in order the display of address options available
10+
#-------------------------------------------------------------------------------#
11+
def checkout_values(self, order, **kw):
12+
order = order or request.website.sale_get_order(force_create=True)
13+
bill_partners = []
14+
ship_partners = []
15+
16+
if not order._is_public_order():
17+
Partner = order.partner_id.with_context(show_address=1).sudo()
18+
commercial_partner = order.partner_id.commercial_partner_id
19+
bill_partners = Partner.search([
20+
'|', ("type", "in", ["invoice", "other"]), ("id", "=", commercial_partner.id),
21+
("id", "child_of", commercial_partner.ids)
22+
], order='id asc, parent_id asc') | order.partner_id
23+
ship_partners = Partner.search([
24+
'|', ("type", "in", ["delivery", "other"]), ("id", "=", commercial_partner.id),
25+
("id", "child_of", commercial_partner.ids)
26+
], order='id asc, parent_id asc') | order.partner_id
27+
28+
if commercial_partner != order.partner_id:
29+
if not self._check_billing_partner_mandatory_fields(commercial_partner):
30+
bill_partners = bill_partners.filtered(lambda p: p.id != commercial_partner.id)
31+
if not self._check_shipping_partner_mandatory_fields(commercial_partner):
32+
ship_partners = ship_partners.filtered(lambda p: p.id != commercial_partner.id)
33+
34+
return {
35+
'order': order,
36+
'website_sale_order': order,
37+
'shippings': ship_partners,
38+
'billings': bill_partners,
39+
'only_services': order and order.only_services or False
40+
}
41+
42+
#----------------------------------------------------------------------------------------------#
43+
# Recompute the prices according to the price list associated with the selected billing address
44+
#----------------------------------------------------------------------------------------------#
45+
@http.route(
46+
'/shop/cart/update_address', type='http', auth='public',
47+
methods=['POST'], website=True, csrf=False
48+
)
49+
def update_cart_address(self, partner_id, mode='billing', **kw):
50+
response = super().update_cart_address(partner_id, mode, **kw)
51+
52+
order_sudo = request.website.sale_get_order()
53+
if not order_sudo:
54+
return response
55+
56+
partner_sudo = request.env['res.partner'].sudo().browse(int(partner_id)).exists()
57+
if not partner_sudo:
58+
raise Forbidden()
59+
60+
new_pricelist = partner_sudo.property_product_pricelist
61+
if new_pricelist and new_pricelist != order_sudo.pricelist_id:
62+
order_sudo.write({'pricelist_id': new_pricelist.id})
63+
64+
order_sudo._recompute_prices()
65+
order_sudo._compute_amounts()
66+
order_sudo.sudo().write({
67+
'amount_total': order_sudo.amount_total,
68+
'amount_tax': order_sudo.amount_tax,
69+
'amount_untaxed': order_sudo.amount_untaxed
70+
})
71+
72+
return response
73+
74+
@http.route(
75+
['/shop/cart/update_total'], type='json', auth='public',
76+
methods=['POST'], website=True, csrf=False
77+
)
78+
def cart_update_total(self):
79+
order_sudo = request.website.sale_get_order()
80+
if not order_sudo:
81+
return {"error": "No active order found"}
82+
83+
line_items = [
84+
{
85+
"unit_price": line.price_unit,
86+
"subtotal": line.price_subtotal,
87+
}
88+
for line in order_sudo.order_line
89+
]
90+
91+
return {
92+
"amount_untaxed": order_sudo.amount_untaxed,
93+
"amount_tax": order_sudo.amount_tax,
94+
"amount_total": order_sudo.amount_total,
95+
"cart_quantity": order_sudo.cart_quantity,
96+
"line_items": line_items,
97+
}
98+
99+
@http.route(['/shop/confirm_order'], type='http', auth="public", website=True, sitemap=False)
100+
def confirm_order(self, **post):
101+
order = request.website.sale_get_order()
102+
103+
redirection = self.checkout_redirection(order) or self.checkout_check_address(order)
104+
if redirection:
105+
return redirection
106+
107+
order.order_line._compute_tax_id()
108+
# Disable to update pricelist based on Website Pricelist
109+
110+
# request.website.sale_get_order(update_pricelist=True)
111+
extra_step = request.website.viewref('website_sale.extra_info')
112+
if extra_step.active:
113+
return request.redirect("/shop/extra_info")
114+
115+
return request.redirect("/shop/payment")

0 commit comments

Comments
 (0)