Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
4b2fe42
feat: add spp_branding_kit module for custom branding
jeremi Aug 21, 2025
9980f8f
fix the build
jeremi Aug 21, 2025
27e9550
Try to fix again the build
jeremi Aug 21, 2025
364aca4
fix(spp_branding_kit): resolve XPath conflicts with g2p_theme module
jeremi Aug 21, 2025
91ecfd3
fix(spp_branding_kit): address all code review feedback from Gemini
jeremi Aug 22, 2025
b9e4829
test(spp_branding_kit): add comprehensive test coverage
jeremi Aug 22, 2025
6ea41ec
refactor(spp_branding_kit): reorganize documentation structure
jeremi Aug 22, 2025
72f87eb
fix(spp_branding_kit): fix test failures in build
jeremi Aug 22, 2025
1b9f08e
fix(spp_branding_kit): remove tests that require HTTP request context
jeremi Aug 22, 2025
c950e77
fix(spp_branding_kit): fix failing tests and update license filtering…
jeremi Aug 22, 2025
ebfc88f
fix(spp_branding_kit): remove debug mode restriction to fix singleton…
jeremi Aug 22, 2025
02a4ed8
spp_branding_kit: drop server-side Apps filtering; UI-only default to…
jeremi Sep 15, 2025
05b8607
spp_branding_kit: refine controllers and hooks; correct JSON response…
jeremi Sep 15, 2025
811903c
spp_branding_kit: adopt dotted keys; add HttpCase tests; cleanup tests
jeremi Sep 15, 2025
26ce9f4
spp_branding_kit: remove obsolete settings fields and tests; update r…
jeremi Sep 15, 2025
341edcb
spp_branding_kit: format controllers after import reorder
jeremi Sep 15, 2025
c9128e6
spp_branding_kit: remove stale comments; format CSS/XML after cleanup
jeremi Sep 15, 2025
8b78e20
spp_branding_kit: format utils and controllers after refactor
jeremi Sep 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
243 changes: 243 additions & 0 deletions spp_branding_kit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
# OpenSPP Branding Kit for Odoo 17

A comprehensive debranding and rebranding module for Odoo 17 that replaces all Odoo branding with OpenSPP
branding throughout the platform.

## Features

### Complete Debranding

- ✅ Removes "Powered by Odoo" messages from all interfaces
- ✅ Eliminates Odoo.com links and references
- ✅ Disables telemetry and external communications
- ✅ Removes enterprise promotion elements
- ✅ Hides app store and theme store links

### Custom Branding

- 🎨 Custom website footer with OpenSPP information
- 🎨 Branded login page with OpenSPP styling
- 🎨 Professional PDF reports with OpenSPP headers/footers
- 🎨 Customized backend interface with OpenSPP colors
- 🎨 Modified user menu with OpenSPP links
- 🎨 Custom email signatures and templates

### Technical Features

- 🔧 Follows Odoo best practices for upgrade safety
- 🔧 Uses proper inheritance mechanisms
- 🔧 Compatible with OCA debranding modules
- 🔧 Modular architecture for easy customization
- 🔧 No core code modifications

## Requirements

- Odoo 17 Community Edition
- Python 3.8+
- PostgreSQL 12+

### Recommended OCA Modules

For complete debranding, install these modules from the
[OCA/server-brand](https://github.com/OCA/server-brand) repository:

- `disable_odoo_online` (17.0.1.0.0)
- `portal_odoo_debranding` (17.0.1.0.0)
- `remove_odoo_enterprise` (17.0.1.0.1)

## Installation

### 1. Clone the Module

```bash
cd /path/to/your/custom-addons
git clone [repository-url] openspp_branding_kit
```

### 2. Install OCA Dependencies (Recommended)

```bash
cd /path/to/your/custom-addons
git clone --branch 17.0 https://github.com/OCA/server-brand.git
```

### 3. Update Odoo Configuration

Add the module paths to your `odoo.conf`:

```ini
[options]
addons_path = /path/to/openspp_branding_kit,/path/to/server-brand,/path/to/odoo/addons

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The addons_path in your odoo.conf example is misleading. It should point to the directory that contains the addon modules, not the addon module directory itself. This will cause confusion for users trying to install the module.

Suggested change
addons_path = /path/to/openspp_branding_kit,/path/to/server-brand,/path/to/odoo/addons
addons_path = /path/to/your/custom-addons,/path/to/server-brand,/path/to/odoo/addons


# Recommended security settings
list_db = False
```

### 4. Install the Module

1. Restart your Odoo server
2. Go to Apps menu
3. Update Apps List
4. Search for "OpenSPP Branding Kit"
5. Click Install

## Configuration

The module automatically applies all branding changes upon installation. However, you can further customize:

### Company Information

- Navigate to Settings → Companies → Your Company
- Update company logo, address, and contact information

### Website Customization

- Use the website builder to further customize the footer
- Modify colors and styles through the Customize menu

### Email Templates

- Go to Settings → Technical → Email Templates
- Modify the OpenSPP notification templates as needed

### Report Customization

- Navigate to Settings → Technical → Reports
- Adjust paper formats and layouts

## Module Structure

```
openspp_branding_kit/
├── __manifest__.py # Module metadata
├── __init__.py # Module initialization
├── controllers/ # HTTP controllers
│ └── main.py # Custom routes
├── data/ # Data files
│ ├── debranding_data.xml
│ ├── ir_config_parameter.xml
│ └── res_company_data.xml
├── models/ # Model overrides
│ ├── ir_http.py
│ └── res_users.py
├── security/ # Access control
│ └── ir.model.access.csv
├── static/ # Static assets
│ ├── description/ # Module description
│ └── src/ # CSS/JS assets
│ ├── js/ # JavaScript files
│ └── scss/ # SCSS stylesheets
└── views/ # XML templates
├── backend_customization.xml
├── login_templates.xml
├── report_templates.xml
├── webclient_templates.xml
└── website_templates.xml
```

## Customization Guide

### Changing Colors

Edit the SCSS variables in `static/src/scss/backend.scss`:

```scss
$openspp-primary: #2c3e50; // Main brand color
$openspp-secondary: #34495e; // Secondary color
$openspp-accent: #3498db; // Accent color
```

### Modifying Footer Content

Edit `views/website_templates.xml` to change footer text and links.

### Adding Custom Logos

1. Place your logo in `static/description/`
2. Update the path in `data/ir_config_parameter.xml`
3. Reference it in templates

## Troubleshooting

### Module Not Appearing

- Ensure the module path is in `addons_path`
- Check module permissions (should be readable)
- Update apps list with `--update=all` flag

### Branding Not Applied

- Clear browser cache
- Restart Odoo server
- Check for conflicting modules

### OCA Modules Not Working

- Verify you're using the 17.0 branch
- Check module dependencies are satisfied
- Review Odoo logs for errors

## Development

### Running Tests

```bash
./odoo-bin -c odoo.conf -d test_db --test-enable --stop-after-init -i openspp_branding_kit
```

### Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request

## Security Considerations

This module includes security enhancements:

- Disables database manager in web interface
- Blocks telemetry to external servers
- Removes potentially sensitive information from UI
- Implements secure default configurations

## License

This module is licensed under LGPL-3. See LICENSE file for full details.

## Support

- **Website**: [https://openspp.org](https://openspp.org)
- **Documentation**: [https://openspp.org/documentation](https://openspp.org/documentation)
- **GitHub**: [https://github.com/openspp](https://github.com/openspp)
- **Community**: [https://openspp.org/community](https://openspp.org/community)

## Credits

### Authors

- OpenSPP Project Team

### Contributors

- See contributors list on GitHub

### Acknowledgments

- Odoo Community Association (OCA) for debranding modules
- OpenSPP community for testing and feedback

## Changelog

### Version 17.0.1.0.0 (Latest)

- Initial release for Odoo 17
- Complete debranding functionality
- OpenSPP branding implementation
- OCA module compatibility
- Security enhancements

---

© 2025 OpenSPP Project. All rights reserved.
116 changes: 116 additions & 0 deletions spp_branding_kit/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# ABOUTME: Module initialization file for OpenSPP Branding Kit
# ABOUTME: Imports models, controllers and defines hooks for the module

from . import models
from . import controllers

import logging

_logger = logging.getLogger(__name__)


def post_init_hook(env):
"""
Post-installation hook to perform initial branding setup
"""
_logger.info("OpenSPP Branding Kit: Running post-installation setup...")

# Set default configuration parameters
try:
IrConfigParam = env["ir.config_parameter"].sudo()

# Set hide paid apps to True by default (if not already set)
if not IrConfigParam.get_param("openspp.hide_paid_apps"):
IrConfigParam.set_param("openspp.hide_paid_apps", "True")
_logger.info("Set hide paid apps to True by default")

# Set default app filter to 'apps_only' (if not already set)
if not IrConfigParam.get_param("openspp.default_app_filter"):
IrConfigParam.set_param("openspp.default_app_filter", "apps_only")
_logger.info("Set default app filter to 'apps_only'")

except Exception as e:
_logger.warning(f"Error setting default parameters: {e}")

# Disable Odoo branding elements
try:
# Deactivate brand promotion view
brand_promotion = env.ref("web.brand_promotion_message", raise_if_not_found=False)
if brand_promotion:
brand_promotion.active = False
_logger.info("Disabled Odoo brand promotion message")

# Disable update notification cron jobs (search by model/method)
Cron = env["ir.cron"].sudo()

# Disable module update related cron jobs
module_update_crons = Cron.search(
[
"|",
"|",
("model", "=", "ir.module.module"),
("model", "=", "publisher_warranty.contract"),
("cron_name", "ilike", "module"),
]
)
for cron in module_update_crons:
if cron.active:
cron.active = False
_logger.info(f"Disabled cron job: {cron.name}")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The domain used to find cron jobs to disable is too broad. Using ("cron_name", "ilike", "module") could accidentally disable important, unrelated cron jobs. It's much safer to disable them by their specific external IDs.

        crons_to_disable = [
            "publisher_warranty.cron_update_notification",
        ]
        for cron_xml_id in crons_to_disable:
            cron = env.ref(cron_xml_id, raise_if_not_found=False)
            if cron and cron.active:
                cron.active = False
                _logger.info(f"Disabled cron job: {cron.name}")


# Disable theme store menu if it exists
theme_menu = env["ir.ui.menu"].sudo().search([("name", "ilike", "Theme Store")], limit=1)
if theme_menu and theme_menu.active:
theme_menu.active = False
_logger.info("Disabled Theme Store menu")

except Exception as e:
_logger.warning(f"Error during branding setup: {e}")

# Update company information
try:
Company = env["res.company"].sudo()
main_company = Company.browse(1) # Main company
if main_company.exists():
main_company.write(
{
"report_header": "OpenSPP Platform",
"report_footer": "OpenSPP - Open Source Social Protection Platform",
"website": "https://openspp.org",
}
)
_logger.info("Updated main company branding")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Hardcoding the company ID to 1 is not multi-company safe. This will only apply the branding updates to the first company in the database. To ensure all companies are branded correctly, you should iterate over all of them.

        Company = env["res.company"].sudo()
        for company in Company.search([]):
            company.write(
                {
                    "report_header": "OpenSPP Platform",
                    "report_footer": "OpenSPP - Open Source Social Protection Platform",
                    "website": "https://openspp.org",
                }
            )
        _logger.info("Updated company branding for all companies")

except Exception as e:
_logger.warning(f"Error updating company data: {e}")

_logger.info("OpenSPP Branding Kit: Post-installation setup completed")


def uninstall_hook(env):
"""
Uninstall hook to clean up configuration parameters
"""
_logger.info("OpenSPP Branding Kit: Running uninstall cleanup...")

# Remove the hide_paid_apps parameter
try:
IrConfigParam = env["ir.config_parameter"].sudo()
param = IrConfigParam.search([("key", "=", "openspp.hide_paid_apps")])
if param:
param.unlink()
_logger.info("Removed hide_paid_apps parameter")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The uninstall_hook is incomplete. It only removes the openspp.hide_paid_apps parameter, but other parameters like openspp.default_app_filter are set in the post_init_hook and not cleaned up. For consistency, all parameters created by this module should be removed upon uninstallation.

        IrConfigParam = env["ir.config_parameter"].sudo()
        params = IrConfigParam.search([("key", "=like", "openspp.%")])
        if params:
            params.unlink()
            _logger.info("Removed all OpenSPP configuration parameters")

except Exception as e:
_logger.warning(f"Error removing configuration parameter: {e}")

# Optionally re-enable Odoo branding elements
# This is commented out by default to maintain debranding even after uninstall
# Uncomment if you want to restore Odoo branding on module removal

# try:
# brand_promotion = env.ref('web.brand_promotion_message', raise_if_not_found=False)
# if brand_promotion:
# brand_promotion.active = True
# except Exception as e:
# _logger.warning(f"Error during uninstall cleanup: {e}")

_logger.info("OpenSPP Branding Kit: Uninstall cleanup completed")
Loading
Loading