Skip to content

Commit 2b2feea

Browse files
authored
Merge pull request #829 from OpenSPP/feat/spp_branding_kit
feat: add spp_branding_kit module for OpenSPP custom branding
2 parents 6cbbdbf + a3ed5db commit 2b2feea

36 files changed

+1587
-1
lines changed

.github/workflows/test.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ jobs:
121121
rm -rf openg2p-program/g2p_payment_files
122122
rm -rf openg2p-program/g2p_payment_g2p_connect
123123
rm -rf openg2p-program/g2p_program_documents
124+
rm -rf openg2p-program/g2p_theme
125+
rm -rf openg2p_registry/g2p_service_provider_portal_base
124126
rm -rf mukit-modules/muk_web_enterprise_theme
125127
cp -r openg2p-registry/* ${ADDONS_DIR}/
126128
cat test-requirements.txt >> spp-test-requirements.txt

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,5 @@ docs/_build/
7777
.ruff_cache
7878
.aider*
7979

80-
.release
80+
# Local release planning files (ignored)
81+
.release/

spp_branding_kit/__init__.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
from . import models
2+
from . import controllers
3+
4+
import logging
5+
6+
_logger = logging.getLogger(__name__)
7+
8+
9+
def post_init_hook(env):
10+
"""
11+
Post-installation hook to perform initial branding setup
12+
"""
13+
_logger.info("OpenSPP Branding Kit: Running post-installation setup...")
14+
15+
# No default parameters for app filtering; UI handles Apps filters now
16+
17+
# Disable Odoo branding elements
18+
try:
19+
# Deactivate brand promotion view
20+
brand_promotion = env.ref("web.brand_promotion_message", raise_if_not_found=False)
21+
if brand_promotion:
22+
brand_promotion.active = False
23+
_logger.info("Disabled Odoo brand promotion message")
24+
25+
# Disable specific Odoo update notification cron (if present)
26+
crons_to_disable = [
27+
"mail.ir_cron_module_update_notification", # Module update notification
28+
]
29+
30+
for cron_xml_id in crons_to_disable:
31+
try:
32+
cron = env.ref(cron_xml_id, raise_if_not_found=False)
33+
if cron and cron.active:
34+
cron.active = False
35+
_logger.info(f"Disabled cron job: {cron.name} ({cron_xml_id})")
36+
except Exception as e:
37+
_logger.debug(f"Could not disable cron {cron_xml_id}: {e}")
38+
39+
# Disable theme store menu if it exists
40+
theme_menu = env["ir.ui.menu"].sudo().search([("name", "ilike", "Theme Store")], limit=1)
41+
if theme_menu and theme_menu.active:
42+
theme_menu.active = False
43+
_logger.info("Disabled Theme Store menu")
44+
45+
except Exception as e:
46+
_logger.warning(f"Error during branding setup: {e}")
47+
48+
# Update company information for all companies
49+
try:
50+
Company = env["res.company"].sudo()
51+
companies = Company.search([])
52+
for company in companies:
53+
company.write(
54+
{
55+
"report_header": "OpenSPP Platform",
56+
"report_footer": "OpenSPP - Open Source Social Protection Platform",
57+
"website": "https://openspp.org",
58+
}
59+
)
60+
_logger.info(f"Updated branding for {len(companies)} companies")
61+
except Exception as e:
62+
_logger.warning(f"Error updating company data: {e}")
63+
64+
_logger.info("OpenSPP Branding Kit: Post-installation setup completed")
65+
66+
67+
def uninstall_hook(env):
68+
"""
69+
Uninstall hook to clean up configuration parameters
70+
"""
71+
_logger.info("OpenSPP Branding Kit: Running uninstall cleanup...")
72+
73+
# Remove all openspp.* configuration parameters
74+
try:
75+
IrConfigParam = env["ir.config_parameter"].sudo()
76+
params = IrConfigParam.search([("key", "=like", "openspp.%")])
77+
if params:
78+
param_count = len(params)
79+
params.unlink()
80+
_logger.info(f"Removed {param_count} OpenSPP configuration parameters")
81+
except Exception as e:
82+
_logger.warning(f"Error removing configuration parameters: {e}")
83+
84+
# Optionally re-enable Odoo branding elements
85+
# This is commented out by default to maintain debranding even after uninstall
86+
# Uncomment if you want to restore Odoo branding on module removal
87+
88+
# try:
89+
# brand_promotion = env.ref('web.brand_promotion_message', raise_if_not_found=False)
90+
# if brand_promotion:
91+
# brand_promotion.active = True
92+
# except Exception as e:
93+
# _logger.warning(f"Error during uninstall cleanup: {e}")
94+
95+
_logger.info("OpenSPP Branding Kit: Uninstall cleanup completed")

spp_branding_kit/__manifest__.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"name": "OpenSPP Branding Kit",
3+
"version": "17.0.1.0.0",
4+
"summary": "Branding customization and telemetry management for OpenSPP",
5+
"description": """
6+
OpenSPP Branding Kit
7+
====================
8+
9+
This module provides comprehensive branding customization for OpenSPP:
10+
11+
Features:
12+
- Customizes system branding across all interfaces
13+
- Redirects telemetry to OpenSPP servers (configurable)
14+
- Option to completely disable telemetry
15+
- Removes enterprise promotion elements
16+
- Customizes system messages with OpenSPP branding
17+
18+
Technical Features:
19+
- Works with theme_openspp_muk for visual styling
20+
- Configurable telemetry endpoint
21+
- Privacy-focused with opt-out options
22+
""",
23+
"author": "OpenSPP Project",
24+
"website": "https://github.com/OpenSPP/openspp-modules",
25+
"license": "LGPL-3",
26+
"category": "Theme/Backend",
27+
"depends": [
28+
"base",
29+
"web",
30+
"base_setup",
31+
"theme_openspp_muk", # Required for OpenSPP styling
32+
],
33+
"data": [
34+
# Default configuration data (order matters)
35+
"data/res_company_data.xml",
36+
"data/ir_config_parameter.xml",
37+
"data/debranding_data.xml",
38+
# Views - UI customizations
39+
"views/webclient_templates.xml",
40+
"views/login_templates.xml",
41+
"views/report_templates.xml",
42+
"views/backend_customization.xml",
43+
"views/res_config_settings_views.xml",
44+
"views/about_settings.xml",
45+
"views/ir_module_module_views.xml",
46+
],
47+
"assets": {
48+
"web.assets_backend": [
49+
"spp_branding_kit/static/src/js/webclient.js",
50+
"spp_branding_kit/static/src/js/user_menu.js",
51+
],
52+
"web.assets_frontend": [
53+
"spp_branding_kit/static/src/css/login_branding.css",
54+
],
55+
},
56+
"images": [
57+
"static/description/icon.png",
58+
"static/description/banner.png",
59+
],
60+
"installable": True,
61+
"application": False,
62+
"auto_install": False,
63+
"post_init_hook": "post_init_hook",
64+
"uninstall_hook": "uninstall_hook",
65+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import main
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import json
2+
3+
from werkzeug.urls import url_encode
4+
from werkzeug.wrappers import Response
5+
6+
from odoo import http
7+
from odoo.http import request
8+
9+
from odoo.addons.portal.controllers.web import Home
10+
11+
from ..utils import get_param, telemetry_payload, version_info_payload
12+
13+
14+
class OpenSPPHome(Home):
15+
"""Restrict debug mode to administrators when enabled via parameter."""
16+
17+
@http.route()
18+
def web_client(self, s_action=None, **kw):
19+
# Enforce optional debug restriction before rendering
20+
debug_admin_only = get_param(request.env, "openspp.debug.admin_only", "True") == "True"
21+
22+
# Detect debug flag from kwargs or query string
23+
has_debug = bool(kw.get("debug")) or ("debug" in (request.httprequest.args or {}))
24+
if debug_admin_only and has_debug:
25+
uid = request.session.uid
26+
# If not logged in or not admin, strip debug and redirect
27+
if not uid or not request.env.user._is_admin():
28+
kw.pop("debug", None)
29+
args = {k: v for k, v in request.httprequest.args.items() if k != "debug"}
30+
query = url_encode(args)
31+
return request.redirect("/web" + (f"?{query}" if query else ""))
32+
33+
return super().web_client(s_action, **kw)
34+
35+
36+
class OpenSPPBrandingController(http.Controller):
37+
"""Custom routes for OpenSPP branding"""
38+
39+
@http.route("/openspp/about", type="http", auth="public")
40+
def openspp_about(self, **kwargs):
41+
"""Custom about page for OpenSPP"""
42+
return json.dumps(
43+
{
44+
"title": "About OpenSPP",
45+
"version": "1.0.0",
46+
"system_name": get_param(request.env, "openspp.system.name", "OpenSPP Platform"),
47+
"documentation_url": get_param(request.env, "openspp.documentation.url", "https://docs.openspp.org"),
48+
"support_url": get_param(request.env, "openspp.support.url", "https://openspp.org"),
49+
}
50+
)
51+
52+
@http.route("/web/webclient/version_info", type="json", auth="none")
53+
def version_info(self):
54+
"""Override version info to show OpenSPP branding"""
55+
return version_info_payload(request.env)
56+
57+
@http.route("/publisher-warranty", type="http", auth="none", csrf=False)
58+
def publisher_warranty(self, **kwargs):
59+
"""Handle telemetry based on configuration"""
60+
payload = telemetry_payload(request.env)
61+
return Response(json.dumps(payload), content_type="application/json")
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<odoo noupdate="1">
3+
4+
<!-- Note: Some cron jobs and views may not exist in all Odoo versions -->
5+
<!-- They will be handled safely in the post_init_hook -->
6+
7+
<!-- Remove Odoo Links from Menus -->
8+
9+
<!-- Rename Apps Store Menu to Local Apps -->
10+
<record id="base.menu_module_tree" model="ir.ui.menu">
11+
<field name="name">Local Apps</field>
12+
</record>
13+
14+
<!-- Configuration Parameters -->
15+
16+
<!-- Disable Odoo IAP (In-App Purchase) -->
17+
<record id="param_iap_endpoint" model="ir.config_parameter">
18+
<field name="key">iap.endpoint</field>
19+
<field name="value">False</field>
20+
</record>
21+
22+
<!-- Disable Update Notifications -->
23+
<record id="param_module_update_notification" model="ir.config_parameter">
24+
<field name="key">module.update.notification</field>
25+
<field name="value">False</field>
26+
</record>
27+
28+
<!-- Custom Module Categories -->
29+
<record id="module_category_openspp" model="ir.module.category">
30+
<field name="name">OpenSPP</field>
31+
<field name="sequence">1</field>
32+
</record>
33+
34+
</odoo>
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<odoo noupdate="1">
3+
4+
<!-- System Information Parameters -->
5+
<record id="param_system_name" model="ir.config_parameter">
6+
<field name="key">openspp.system.name</field>
7+
<field name="value">OpenSPP Platform</field>
8+
</record>
9+
10+
<record id="param_system_version" model="ir.config_parameter">
11+
<field name="key">openspp.system.version</field>
12+
<field name="value">1.0.0</field>
13+
</record>
14+
15+
<!-- Support and Documentation URLs -->
16+
<record id="param_support_url" model="ir.config_parameter">
17+
<field name="key">openspp.support.url</field>
18+
<field name="value">https://openspp.org/</field>
19+
</record>
20+
21+
<record id="param_documentation_url" model="ir.config_parameter">
22+
<field name="key">openspp.documentation.url</field>
23+
<field name="value">https://docs.openspp.org/</field>
24+
</record>
25+
26+
<record id="param_community_url" model="ir.config_parameter">
27+
<field name="key">openspp.community.url</field>
28+
<field name="value">https://openspp.org/</field>
29+
</record>
30+
31+
<!-- Telemetry Configuration -->
32+
<record id="param_openspp_telemetry_enabled" model="ir.config_parameter">
33+
<field name="key">openspp.telemetry.enabled</field>
34+
<field name="value">True</field>
35+
</record>
36+
37+
<record id="param_openspp_telemetry_endpoint" model="ir.config_parameter">
38+
<field name="key">openspp.telemetry.endpoint</field>
39+
<field name="value">https://telemetry.openspp.org</field>
40+
</record>
41+
42+
<!-- Disable External Services -->
43+
<record id="param_disable_external_links" model="ir.config_parameter">
44+
<field name="key">openspp.disable.external_links</field>
45+
<field name="value">True</field>
46+
</record>
47+
48+
<!-- Custom Footer Text -->
49+
<record id="param_footer_copyright" model="ir.config_parameter">
50+
<field name="key">openspp.footer.copyright</field>
51+
<field name="value">© OpenSPP Project - Open Source Social Protection Platform</field>
52+
</record>
53+
54+
<!-- Email Configuration -->
55+
<record id="param_email_from_name" model="ir.config_parameter">
56+
<field name="key">openspp.email.from_name</field>
57+
<field name="value">OpenSPP Platform</field>
58+
</record>
59+
60+
<!-- Report Configuration -->
61+
<record id="param_report_footer_text" model="ir.config_parameter">
62+
<field name="key">openspp.report.footer_text</field>
63+
<field name="value">Generated by OpenSPP Platform</field>
64+
</record>
65+
66+
<!-- Login Page Configuration -->
67+
<record id="param_login_page_title" model="ir.config_parameter">
68+
<field name="key">openspp.login.page.title</field>
69+
<field name="value">OpenSPP - Social Protection Platform</field>
70+
</record>
71+
72+
<record id="param_login_page_subtitle" model="ir.config_parameter">
73+
<field name="key">openspp.login.page.subtitle</field>
74+
<field name="value">Secure Access Portal</field>
75+
</record>
76+
77+
<!-- Database Manager Configuration -->
78+
<record id="param_database_manager_disabled" model="ir.config_parameter">
79+
<field name="key">openspp.database.manager.disabled</field>
80+
<field name="value">True</field>
81+
</record>
82+
83+
<!-- Custom Favicon Path -->
84+
<record id="param_favicon_path" model="ir.config_parameter">
85+
<field name="key">openspp.favicon.path</field>
86+
<field name="value">/spp_branding_kit/static/description/icon.png</field>
87+
</record>
88+
89+
<!-- Theme Configuration -->
90+
<record id="param_theme_primary_color" model="ir.config_parameter">
91+
<field name="key">openspp.theme.primary_color</field>
92+
<field name="value">#2c3e50</field>
93+
</record>
94+
95+
<record id="param_theme_secondary_color" model="ir.config_parameter">
96+
<field name="key">openspp.theme.secondary_color</field>
97+
<field name="value">#34495e</field>
98+
</record>
99+
100+
<!-- Analytics and Tracking -->
101+
<record id="param_google_analytics_disabled" model="ir.config_parameter">
102+
<field name="key">openspp.google_analytics.disabled</field>
103+
<field name="value">True</field>
104+
</record>
105+
106+
<!-- Custom Error Messages -->
107+
<record id="param_error_message_404" model="ir.config_parameter">
108+
<field name="key">openspp.error.message.404</field>
109+
<field name="value">Page not found in OpenSPP Platform</field>
110+
</record>
111+
112+
<record id="param_error_message_403" model="ir.config_parameter">
113+
<field name="key">openspp.error.message.403</field>
114+
<field name="value">Access denied. Please contact your OpenSPP administrator.</field>
115+
</record>
116+
117+
<record id="param_error_message_500" model="ir.config_parameter">
118+
<field name="key">openspp.error.message.500</field>
119+
<field name="value">An error occurred in OpenSPP Platform. Please try again later.</field>
120+
</record>
121+
122+
</odoo>

0 commit comments

Comments
 (0)