Skip to content

Horilla CRM v1.10.0 — Platform Restructure, Namespace Migration & Database Sync Utility

Choose a tag to compare

@horilla-opensource horilla-opensource released this 11 May 09:21
· 231 commits to master since this release

Release Date: 11 May 2026
Version: 1.10.0
Status: Major Platform Restructure, Namespace Migration, Database Sync Utility & CRM Stability Release


Horilla CRM v1.10.0

Horilla CRM v1.10.0 is a major platform restructuring release that consolidates the entire support-app ecosystem under a unified horilla.contrib.* namespace, introduces a dedicated database sync utility for safe v1.9.1 → v1.10.0 upgrades, and ships extensive fixes across CRM modules, generics, permissions, currency handling, and the UI layer.

This update reorganizes the platform into a cleaner, more maintainable architecture while preserving data integrity, hardening permissions, and refining the user experience across every module.


This release focuses on:

🏗️ Platform Restructure & horilla.contrib Namespace Migration
🗄️ Database Sync Utility (sync_db) for Safe Upgrades
🔐 Permissions, Feature Registry & Self-Registration
🌐 URL Prefixing, Routing & Navigation Improvements
⚡ HTMX, Generics & List/Filter UX Enhancements
🧩 CRM Module Fixes (Leads, Opportunities, Activity, Cadences, Reports, Reviews, Forecast, Dashboard)
💱 Currency Cascade & Multi-Currency Improvements
📅 Calendar, Channels (Redis) & Infrastructure Updates
🎨 UI/UX Consistency & Delete Confirmation UX
🛠️ Code Quality, Black/djangofmt, Encoding Cleanup & Pylint Fixes


The result is a more modular, maintainable, and upgrade-safe CRM platform.


Highlights


🏗️ Platform Restructure — horilla_*horilla.contrib.*

The headline change of v1.10.0: 15 support apps moved from top-level horilla_* packages into the unified horilla.contrib.* namespace with new short app labels.

Apps Migrated

Old package New package New label
horilla_activity horilla.contrib.activity activity
horilla_automations horilla.contrib.automations automations
horilla_cadences horilla.contrib.cadences cadences
horilla_calendar horilla.contrib.calendar calendar
horilla_core horilla.contrib.core core
horilla_dashboard horilla.contrib.dashboard dashboard
horilla_duplicates horilla.contrib.duplicates duplicates
horilla_generics horilla.contrib.generics generics
horilla_keys horilla.contrib.keys keys
horilla_mail horilla.contrib.mail mail
horilla_notifications horilla.contrib.notifications notifications
horilla_processes.approvals horilla.contrib.process.approvals approvals
horilla_processes.reviews horilla.contrib.process.reviews reviews
horilla_reports horilla.contrib.reports reports
horilla_theme horilla.contrib.theme theme
horilla_utils horilla.contrib.utils utils

horilla_crm is out of scope for this migration — its directory and tables are unchanged.

AppLauncher Updates

Every contrib apps.py now sets:

  • name = "horilla.contrib.<app>" (dotted path)
  • label = "<app>" — explicitly pinned so the app_label is independent of the dotted path
  • url_module = "horilla.contrib.<app>.urls"
  • url_namespace = "<app>" (short form)
  • get_api_paths() rewritten to new dotted paths and namespaces

Codebase-Wide Refactor

  • All Python imports rewritten: from horilla_<app>... → from horilla.contrib.<app>...
  • INSTALLED_APPS updated in horilla/settings/base.py
  • URL reversals, {% url %}, reverse(), and reverse_lazy() calls migrated to new short namespaces
  • Template static paths: {% static 'horilla_<app>/...' %}{% static '<app>/...' %}
  • FK string refs updated to new app labels ("core.HorillaUser", not the package path)
  • Permission codename strings updated (user.has_perm("activity.view_activity"))
  • Hard-to-grep landmines reviewed: string-sender signals, auditlog model lists, fixture files, Celery beat task names, ContentType app_label lookups

🗄️ Database Sync Utility — sync_db

A new sync_db management command was added to migrate existing v1.9.1 databases to the v1.10.0 layout safely and idempotently.

What It Rewrites

  • django_migrations.app — old labels → new contrib labels
  • django_content_type.app_label — propagates automatically to:
    • auth_permission (FK to content type)
    • auth_group_permissions and auth_user_user_permissions (FK IDs preserved — no row changes)
    • CRM FieldPermission and Role tables (FK-based, unaffected)
  • Table names where the prefix changed (e.g. horilla_activity_*activity_*)

Upgrade Path

  • Documented in README.md (v1.9 → v1.10.0 upgrade guide)
  • Run python manage.py sync_db before starting the v1.10.0 server
  • Permission rows preserved by FK integrity — no permissions need to be re-granted

⚠️ Breaking change for existing v1.9.1 deployments. A database migration is required before running v1.10.0.


🔐 Permissions, Registration & Feature Registry

Feature Registration Refactor

  • Models can now be registered before the feature exists
  • Registry keys (e.g. duplicate_models) map back to real feature names
  • Explicit-feature registration works even when the feature has a fixed include list
  • Hardcoded CRM model lists removed from contrib features — CRM apps now register themselves
  • CRM-specific naming replaced with Horilla-neutral wording where the platform is meant
  • Hardcoded automation model skips replaced with FEATURE_REGISTRY lookups

Permission Fixes

  • Fixed opportunity, opportunity team, and team-member-role permission issues
  • Fixed shortcut permissions for users with “own” access
  • Improved shortcut settings UI and button visibility

🌐 URL & Routing Updates

CRM URL Prefixing

  • All CRM module URL paths prefixed with crm/
  • Hardcoded URLs replaced with reverse_lazy
  • post_migrate shortkey URL migration added for crm-prefixed routes

Navigation & Resolution

  • Sidebar active-menu detection fixed by matching sidebar IDs and base app paths
  • NoReverseMatch exported from horilla.urls
  • Duplicate app shortcut handlers removed; optional shortcuts registered conditionally

HTMX, Generics & List/Filter UX

Queryset & Helper Centralization

  • apply_conditions and get_queryset_for_module centralized in queryset_utils
  • Redundant dashboard/helper.py removed
  • Dashboard charts, dashboard helper, and calendar all wired through centralized utils

List View Improvements

  • Fixed cell text wrapping and broken HTML rendering for custom fields
  • Drag-handle layout improved for long cell values
  • Tooltip on truncated cell text shows only on actual overflow
  • Saved-list Edit/Delete button styles updated to primary theme classes
  • Delete mode and bulk update POST payloads correctly detected as bulk operations

Select2 & Filter Fixes

  • Reinitialized Select2 when opening navbar filter panel (dropdown width fix)
  • Applied filters preserved when changing quick filter values
  • Select2 false matches fixed by filtering on __str__ instead of all model char fields
  • Dynamic approver user field switched to Select2 pagination, scoped by company

Notes Attachment Modal

  • Fixed Summernote image upload
  • Resolved NoReverseMatch by correcting namespace in attachment reverse URLs

🧩 CRM Module Fixes & Enhancements

Leads

  • Updated KPI naming for clarity
  • Resolved circular import by moving lead-score pre_save handler from models.py to signals.py

Opportunity

  • Fixed permissions, team permissions, and team-member-role display in related list & edit form

Activity

  • Status filter no longer triggers unintended status updates
  • Added shared tab-list col_attrs mixin so task/meeting/call/event rows open detail with referrer and section params for correct breadcrumb navigation
  • Prevented spurious Potential Duplicates tab injection by setting self.model on detail tab views
  • Fixed Meetings tab click script after delete to return users to the correct tab

Reports

  • Fixed report detail rendering when no columns are selected (counts, chart, hide detail table)

Reviews

  • Fixed approver field visibility and validation error persistence in ReviewProcessRuleForm
  • Suppressed browser focusable errors on hidden fields and prevented HTMX toggle from wiping error messages on re-render

Cadences

  • Cadence tab registration moved into each CRM app via register_cadence_tab
  • Prevented report page referer from overriding detail back navigation
  • Latest runtime activity now surfaces next follow-up type and response in record tabs list view

Duplicates

  • Fixed Potential Duplicates tab appearing on unregistered CRM modules

Campaigns

  • Default member_type set to lead in add-member form

Dashboard

  • Default home chart and table cards now stretch evenly
  • Removed responsive height shrink for many charts
  • Added table sections for accounts, campaigns, and contacts with section-aware detail URL navigation

Forecast

  • Fixed dropdowns covered by sticky table header (z-index)
  • Removed forecast auto-recalculation on model save
  • Restricted calculator writes to computed fields via update_fields

💱 Currency & Core Improvements

Default Currency Cascade

  • Optimized default-currency change with bulk exchange-rate fetches and bulk currency/rate updates
  • Background CRM amount conversion via signal dispatch

Multi-Currency UI

  • Corrected HTMX targets and reload flow after dated rate save
  • Inline validation error rendering and value retention in dated conversion rates form
  • selected_start_date defaults to first available dated exchange range when no explicit selection is provided

Core Enhancements

  • Scheduled export detail modal with row-click navigation and frequency-aware fields
  • Superuser tab reload scoped to #super_user_list
  • Superuser Select2 dropdown fixed by adding missing data-form-class
  • Recycle bin bulk action visibility improved by restyling delete action

📅 Calendar & Infrastructure

  • Google Calendar integration setting now resolved by active company
  • Fixed apps.py labels for mail and duplicates modules
  • Default channel layer backend switched to Redis for production-grade WebSocket scaling

🔔 Notifications & Settings

  • sidebarModal3 moved to <body> to escape header stacking context — action icons no longer bleed over the notification panel
  • Removed forced scroll overflow from My Settings — relies on natural page scrolling

🎨 UI/UX Improvements

Delete Confirmation UX

  • Hard/soft bulk-delete prompts updated for clarity
  • Cancel actions repositioned for consistency
  • Icon usage aligned across delete flows
  • Dependency previews replaced with scrollable infinite-load flow
  • Backend pagination added so large related datasets remain fast and clear before deletion

Process Module

  • Standardized rule action buttons in approval and review detail accordions

🛠️ Code Quality & Refactoring

Formatting & Encoding

  • Black formatting applied across Python files
  • djangofmt applied across templates
  • UTF-8 BOM stripped from 32 templates introduced by the contrib move
  • Mojibake text cleaned and static asset references standardized
  • BOM removed from header template; sort icon rendering fixed after encoding corruption
  • Stray </div> removed from sub_sidebar and unwanted divs across templates

Imports & Standards

  • Core/generics views refactored to local import standards
  • Import section headers normalized across contrib apps
  • Pylint warnings resolved across CRM apps: C0305, W0612, W0404, W0611, C0303

Messaging & Cleanup

  • Trailing exclamation marks removed from success messages and CLI output across core, dashboard, generics, and CRM
  • Committed company and profile images cleaned from media/
  • Theme post_migrate signal dispatch_uid refined
  • Context processors extracted into module-level CONTEXT_PROCESSORS list in horilla/settings/base.py
  • Generic and module view handlers refactored for consistent queryset/context processing
  • Dashboard, lead, campaign, forecast, and opportunity view handling standardized for consistent filters and context across app flows

Documentation

  • README reframed around the Horilla platform layout
  • License corrected to LGPL-2.1
  • SECURITY in-scope section updated to reflect the new contrib app layout
  • v1.9 → v1.10.0 upgrade guide added

🛠️ Fixes & Stability

Major Fixes

  • Fixed feature registration ordering and registry key mapping
  • Fixed opportunity, opportunity team, and shortcut “own” access permissions
  • Fixed Potential Duplicates tab injection on unregistered modules
  • Fixed Select2 false matches and dropdown width on filter panel
  • Fixed circular import in lead scoring
  • Fixed Summernote image upload and NoReverseMatch in notes attachments
  • Fixed status filter triggering unintended status updates in Activity
  • Fixed report detail when no columns are selected
  • Fixed forecast sticky-header z-index and auto-recalculation on save
  • Fixed multi-currency HTMX targets and dated rate save flow
  • Fixed sidebar active-menu detection
  • Fixed Meetings tab click script post-delete

Stability Improvements

  • Safer feature registration with deferred resolution
  • Cleaner queryset/context processing across contrib apps
  • Better handling of large dependency previews in delete flows
  • More reliable currency cascade with bulk operations and background dispatch

📜 Changelog Summary

v1.10.0 (11 May 2026)

Added

  • horilla.contrib.* namespace consolidating 15 support apps
  • sync_db management command for v1.9.1 → v1.10.0 database migration
  • v1.9 → v1.10.0 upgrade guide in README.md
  • crm/ URL prefix for all CRM module routes
  • post_migrate shortkey URL migration for crm-prefixed routes
  • Scheduled export detail modal with frequency-aware fields
  • Dashboard table sections for accounts, campaigns, and contacts
  • Section-aware detail URL navigation from dashboard rows
  • Cadence tab registration via register_cadence_tab
  • Background CRM amount conversion on default-currency change
  • Redis as the default channel layer backend
  • NoReverseMatch export from horilla.urls

Improved

  • Platform structure under horilla.contrib.* namespace
  • Feature registration with deferred resolution and registry-key mapping
  • CRM apps now self-register instead of being hardcoded in contrib features
  • Centralized apply_conditions and get_queryset_for_module in queryset_utils
  • Default-currency change flow with bulk exchange-rate fetches
  • Delete confirmation UX with scrollable infinite-load dependency previews
  • Saved-list Edit/Delete button styles using primary theme classes
  • List view cell wrapping, drag-handle layout, and overflow tooltips
  • Recycle bin bulk action visibility
  • Approver field with Select2 pagination scoped by company
  • Sidebar active-menu detection
  • Generic and module view handlers for consistent queryset/context processing
  • Dashboard, lead, campaign, forecast, and opportunity view standardization
  • README, SECURITY, and license documentation

Fixed

  • Opportunity, opportunity team, and team-member-role permissions
  • Shortcut permissions for users with “own” access
  • Lead scoring circular import
  • Activity status filter triggering unintended status updates
  • Activity tab navigation after delete (Meetings tab script + selected tab persistence)
  • Report detail when no columns are selected
  • Review approver field visibility and validation persistence
  • Cadences detail back navigation overridden by report referer
  • Potential Duplicates tab on unregistered CRM modules
  • Campaigns default member_type not set to lead
  • Dashboard chart/card stretching and responsive shrink
  • Forecast dropdowns covered by sticky header
  • Forecast auto-recalculation on save (now restricted to computed fields)
  • Multi-currency HTMX targets and dated rate save flow
  • Inline validation in dated conversion rates form
  • Default selected_start_date for dated exchange ranges
  • Superuser tab reload scope and Select2 dropdown
  • Notification panel stacking (sidebarModal3 moved to <body>)
  • My Settings forced scroll overflow
  • Summernote image upload and NoReverseMatch in notes attachments
  • Select2 false matches and filter-panel dropdown width
  • Quick filter losing applied filters on value change
  • Google Calendar integration setting resolved by active company
  • apps.py labels for mail and duplicates modules
  • UTF-8 BOM in 32 templates and sort icon rendering
  • Mojibake text and stray </div> in templates
  • Pylint warnings (C0305, W0612, W0404, W0611, C0303) across CRM apps

🎯 Impact

Horilla CRM v1.10.0 is a major restructuring release that lays a cleaner foundation for the platform’s future.

This release:

  • Consolidates the platform under a unified horilla.contrib.* namespace
  • Provides a safe, idempotent database upgrade path via sync_db
  • Strengthens feature registration and self-registration for CRM apps
  • Optimizes currency cascade with bulk operations and background dispatch
  • Refines permissions, HTMX flows, and list/filter UX across the platform
  • Modernizes infrastructure with Redis-backed channels and Black/djangofmt formatting
  • Fixes long-standing issues across CRM modules, calendar sync, and the dashboard

Overall

v1.10.0 makes Horilla CRM more modular, maintainable, and upgrade-safe, delivering a cleaner architecture, a reliable database migration utility, and a refined user experience across every module. 🚀