Welcome back to our Odoo development series! Today, we’re diving deep into a game-changing customization for your project management workflow: the Odoo 18 Assignee Filter. If you’ve ever struggled to get a quick overview of who’s working on what, or wanted to easily filter tasks by individual team members directly within your calendar view, this tutorial is for you.
Managing projects effectively in Odoo often means having clear visibility into task assignments and workload distribution. While Odoo provides robust project management tools, sometimes a small, targeted customization can make a massive difference in day-to-day usability. The addition of a dedicated assignee filter to your project task calendar sidebar in Odoo 18 will empower you to do exactly that, transforming how you monitor and manage your team’s efforts.
This powerful enhancement allows you to instantly see tasks assigned to specific users, check individual workloads, and maintain better oversight without ever leaving the calendar. It’s a significant upgrade for team leads, project managers, and anyone who needs dynamic insights into their project’s progress.
Ready to supercharge your Odoo 18 experience? Let’s jump into the code and see how to make this essential feature a reality, step by step. This tutorial is based on the comprehensive guide found in the video: Odoo 18 Development Add Assignee Filter in Project Task Calendar View.
Why the Odoo 18 Assignee Filter is a Must-Have for Your Team
Before we delve into the technical implementation, let’s understand the profound impact this seemingly simple customization can have. The Odoo 18 Assignee Filter isn’t just a convenience; it’s a strategic tool for better project management.
- Enhanced Workload Visibility: Quickly identify which team members are heavily loaded and which might have capacity for new tasks. This is crucial for balanced task distribution and preventing burnout.
- Streamlined Project Oversight: As a project manager, you gain an immediate, visual understanding of individual contributions to ongoing projects. No more clicking through multiple menus or generating reports just to see who’s doing what.
- Improved Team Collaboration: When everyone can easily see each other’s assigned tasks in a clear calendar format, it fosters transparency and can streamline communication regarding task dependencies.
- Faster Decision Making: Need to reassign a task due to an urgent change? A glance at the filtered calendar view can help you make quicker, more informed decisions about resource allocation.
- Personalized Views: Individual users can quickly filter their own tasks or the tasks of specific colleagues they collaborate closely with, making their daily workflow more efficient.
This level of granular control and clear visualization is what makes the Odoo 18 Assignee Filter an indispensable tool for any organization leveraging Odoo for project management.
I. Prerequisites and Initial Setup
Before we start coding, ensure you have the following:
- Odoo 18 Instance: This tutorial is specifically for Odoo 18. While the concepts might apply to earlier versions, the exact implementation details could vary.
- Developer Mode Enabled: In your Odoo instance, navigate to
Settings
and activateDeveloper Mode
(usually found at the bottom of the page). This is essential for accessing technical features and debugging. - Visual Studio Code (or your preferred IDE): We’ll be writing Python and XML code, so a good code editor is highly recommended.
- Custom Addons Path: Ensure you have a custom addons path configured in your Odoo installation where you can place your new module. For more on Odoo module development, consider external resources like the Odoo Documentation.
With these in place, let’s begin structuring our custom module.
1. Create a Custom Module Folder:
Within your Odoo addons path (e.g., odoo/custom_addons/
), create a new folder for your custom module. Let’s name it calendar_filter
. This name should be short, descriptive, and unique within your Odoo environment.
2. Create Module Files and Folders:
Inside the calendar_filter
folder, create the following essential files and sub-folders. This structure adheres to Odoo’s module conventions, ensuring your module is organized and easily maintainable.
__init__.py
(an empty file, required to make the folder a Python package)__manifest__.py
(defines module metadata)models/
models/__init__.py
(empty file, for importing other Python files in this directory)models/task_filters.py
(our custom Python logic)
static/
static/description/
(optional, for module icon and description images)static/description/icon.png
(optional: add a simple icon for your module, such as a filter icon, to enhance its appearance in the Odoo Apps list.)
security/
security/ir.model.access.csv
(defines access rights for our custom model)
views/
views/views.xml
(contains our UI customizations and view inheritance)
II. Implementing the Core Logic: Step-by-Step Code Walkthrough
Now, let’s populate these files with the necessary code. Each step is crucial for the successful implementation of the Odoo 18 Assignee Filter.
1. __manifest__.py
: Module Definition
This file acts as the identity card for your Odoo module. It tells Odoo everything it needs to know about your module, from its name to its dependencies.
{
'name': 'Project Task Calendar Assignee Filter',
'version': '1.0.0',
'category': 'Extra Tools',
'author': 'Your Name/Company', # e.g., Odoistic
'summary': 'Adds an assignee filter to the project task calendar sidebar.',
'description': 'This module introduces a dedicated assignee filter to the Odoo 18 project task calendar view, enabling users to efficiently filter tasks by assigned user. Enhance workload visibility and project management with this intuitive sidebar control.',
'depends': ['web', 'project', 'calendar'],
'license': 'LGPL-3',
'installable': True,
'application': False,
'data': [
'security/ir.model.access.csv',
'views/views.xml',
],
'images': ['static/description/icon.png'], # Add this line if you have an icon
}
Explanation:
name
: This is the human-readable title of your module, displayed in the Odoo Apps list. Keep it clear and descriptive.version
: Follows a semantic versioning pattern (e.g.,1.0.0
). Important for tracking updates and dependencies.category
: Classifies your module in the Odoo Apps dashboard.Extra Tools
is suitable for UI enhancements.author
: Attribution for the module. You can put your name, company, or organization here.summary
: A concise, one-line description visible in the Apps list cards. This highlights the core value, which is adding the Odoo 18 Assignee Filter.description
: A longer, more detailed explanation shown on the module’s detail page. Here, we emphasize the benefits of the Odoo 18 Assignee Filter for workload management.depends
: Lists the technical dependencies required for your module to function.web
: Required for general UI assets and widgets.project
: Essential because we are customizingproject.task
and project-related views.calendar
: Necessary for interacting with Odoo’s calendar view framework.
license
: Specifies the license governing use and distribution.LGPL-3
is common for Odoo Community modules.installable
: Set toTrue
to allow Odoo to install your module.application
: IfTrue
, the module appears as a standalone application in the Apps dashboard. For a filter add-on,False
is often appropriate unless it’s a major feature.data
: A critical list of XML and CSV files that Odoo loads at install time. This is where we specify our security rules and view modifications.images
: (Optional) Path to your module icon.
2. models/__init__.py
: Python Package Initialization
This file tells Python to treat the models
directory as a package.
# models/__init__.py
from . import task_filters
Here, we simply import our task_filters.py
file, making its classes available to the Odoo framework.
3. models/task_filters.py
: Custom Models for Filtering
This file introduces two key models: an extension of project.task
and a new helper model task.filters
. Together, they enable the dynamic behavior of our Odoo 18 Assignee Filter.
from odoo import models, fields, api
class ProjectTask(models.Model):
_inherit = 'project.task'
_description = 'Task extension for assignee filter'
# Adding a direct Many2one field for a single assignee.
# This simplifies filtering compared to many2many user_ids/collaborators.
assignee_id = fields.Many2one(
'res.users',
string='Assigned To',
index=True, # Indexing for faster search/filter performance
help="Directly assigned user for quick filtering in calendar view."
)
class TaskFilters(models.Model):
_name = 'task.filters'
_description = 'User-specific Task Calendar Filters'
# SQL constraint to ensure a user cannot store duplicate entries for the same assignee.
# This keeps the sidebar list clean and prevents redundant toggles.
_sql_constraints = [
('user_id_assignee_id_unique', 'unique(user_id, assignee_id)', 'A user cannot store duplicate entries for the same assignee.')
]
# The user who owns these filter preferences.
user_id = fields.Many2one(
'res.users',
string='User',
required=True,
index=True,
ondelete='cascade', # If the user is deleted, their filter preferences are also deleted.
help="The Odoo user whose filter preferences are stored."
)
# The assignee that the user wants to include or exclude in calendar filtering.
assignee_id = fields.Many2one(
'res.users',
string='Assignee',
required=True,
help="The specific assignee whose tasks are toggled in the calendar filter."
)
# A boolean field to represent the checked or unchecked state in the sidebar UI.
assignee_checked = fields.Boolean(
string='Assignee Filtered',
default=True,
help="Indicates if this assignee's tasks should be shown in the filtered calendar view."
)
# Soft toggle to archive a filter preference without deleting (optional, for future enhancements).
active = fields.Boolean(
string='Active Filter',
default=True,
help="If set to false, this filter preference is inactive but not deleted."
)
@api.model
def unlink_assignee_filters(self, assignee_id):
"""
Deletes all task filters records associated with a specific assignee ID.
This is useful for cleanup, e.g., when an assignee is deactivated or removed
and you want to clean up related filter preferences in one call.
"""
if assignee_id:
filters_to_unlink = self.search([('assignee_id', '=', assignee_id)])
if filters_to_unlink:
filters_to_unlink.unlink()
_logger.info(f"Cleaned up task filter preferences for assignee_id: {assignee_id}")
return True
Explanation:
ProjectTask
(Inheritingproject.task
):_inherit = 'project.task'
: This line tells Odoo to extend the existingproject.task
model.assignee_id = fields.Many2one(...)
: We add a newMany2one
field that links directly tores.users
. This field represents the single, primary assignee for a task. Whileproject.task
hasuser_ids
(aMany2many
for collaborators), a directMany2one
is often simpler for explicit “assigned to” filtering.index=True
significantly speeds up database queries involving this field, crucial for an efficient Odoo 18 Assignee Filter.
TaskFilters
(A New Custom Model):_name = 'task.filters'
: Defines a brand new Odoo model. This model will store user-specific preferences for which assignees are checked/unchecked in the calendar sidebar._sql_constraints
:('user_id_assignee_id_unique', 'unique(user_id, assignee_id)', ...)
: This ensures that for any given user, there’s only one entry for a particular assignee. This prevents redundant filter preferences and keeps the UI clean.
user_id
: AMany2one
field linking tores.users
, indicating who owns this filter preference.ondelete='cascade'
ensures that if a user is deleted, their associated filter preferences are automatically cleaned up.assignee_id
: AnotherMany2one
tores.users
, representing which assignee’s tasks are being toggled (included/excluded) by theuser_id
.assignee_checked
: A boolean field. This is the core of our filter’s state.True
means the assignee is selected/checked in the sidebar,False
means they are unchecked. This directly drives the filtering logic of the Odoo 18 Assignee Filter.active
: A standard boolean field, often used for “soft deletion” or deactivation, allowing you to hide a filter preference without permanently deleting it.unlink_assignee_filters(self, assignee_id)
: This helper method is crucial for data integrity. If an Odoo user is removed from your system, you can use this method to clean up alltask.filters
records where that user was anassignee_id
.
4. security/ir.model.access.csv
: Defining Access Rights
For any custom model, you must define access rights. This file specifies who can read, write, create, and delete records in our task.filters
model.
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_task_filters,Access Task Filters,calendar_filter.model_task_filters,,1,1,1,1
Explanation:
id
: A unique external identifier for this access rule (e.g.,access_task_filters
).name
: A human-readable name for the rule.model_id:id
: This references our custom model (task.filters
). The format ismodule_name.model_name_with_underscores
.group_id:id
: (Optional) Specifies which security group this rule applies to. Leaving it empty (as shown) means it applies to all users by default. For production, you might want to restrict it, perhaps to a specific project manager group, or couple it with a record rule.perm_read, perm_write, perm_create, perm_unlink
: These are boolean flags (1 = True, 0 = False) for read, write, create, and delete permissions, respectively. Here, we grant full permissions (1,1,1,1) for simplicity, allowing all users to manage their own filter preferences.
Best Practice Note on Security:
While granting full permissions to all users for their own task.filters
is generally fine, for sensitive data or to enforce stricter privacy, you would typically add a record rule. A record rule would limit the visibility of task.filters
records so that user_id
is equal to the current user’s ID (user_id = user.id
). This ensures users only see and manage their own filter preferences, enhancing the privacy aspect of the Odoo 18 Assignee Filter. For example: object.user_id.id == user.id
.
5. views/views.xml
: Customizing the Calendar View
This XML file is where the magic happens in terms of UI. We’ll use view inheritance to inject our Odoo 18 Assignee Filter directly into the existing project task calendar view.
<odoo>
<data>
<record id="project_task_calendar_assignee_filter_view" model="ir.ui.view">
<field name="name">project.task.calendar.assignee.filter.inherit</field>
<field name="model">project.task</field>
<field name="inherit_id" ref="project.view_task_calendar"/>
<field name="arch" type="xml">
<!-- Locate the existing user_id field and replace it with our custom assignee_id filter -->
<xpath expr="//field[@name='user_id']" position="replace">
<field name="assignee_id"
string="Filter by Assignee"
widget="many2many_tags"
options="{'color_field': 'color', 'no_create_edit': True}"
domain="[('share', '=', False)]" # Show only internal users
write_model="task.filters" # Store filter state in task.filters model
write_field="assignee_id" # Map chosen assignee to assignee_id in task.filters
filter_field="assignee_checked" # Use assignee_checked to track state
avatar_field="avatar_128" # Display user avatars
/>
</xpath>
</field>
</record>
</data>
</odoo>
Explanation:
<record>
: Defines a new view inheritance record in Odoo.id
: A unique external ID for this inheritance record.model
: Specifies that we are modifying a view related to theproject.task
model.inherit_id
: This is crucial. It points to the standard Odoo view we want to modify.project.view_task_calendar
is the XML ID for the default project task calendar view.arch
(type="xml"
): Contains the XML structure for our modifications.
<xpath>
: An XPath expression is used to precisely locate an element within the inherited view’s XML structure.expr="//field[@name='user_id']"
: This targets the existing<field name="user_id">
element within the calendar view.position="replace"
: This instruction tells Odoo to replace the originaluser_id
field with our new field definition. This is how we effectively inject our Odoo 18 Assignee Filter.
<field name="assignee_id">
: Our new field definition for the filter.name="assignee_id"
: References theMany2one
field we added toproject.task
intask_filters.py
.string="Filter by Assignee"
: The label that will appear for the filter in the sidebar.widget="many2many_tags"
: This widget provides a friendly, tag-based selection interface in the sidebar, perfect for selecting multiple assignees.options="{'color_field': 'color', 'no_create_edit': True}"
: Custom options for the widget.color_field
can add color coding, andno_create_edit
prevents users from creating or editingres.users
records directly from this filter.domain="[('share', '=', False)]"
: This domain ensures that only internal Odoo users (non-portal/non-share users) appear in the assignee selection list, keeping the filter relevant to your internal team.write_model="task.filters"
: This is key. It tells Odoo that the state of this filter (which assignees are checked/unchecked) should be stored in our customtask.filters
model.write_field="assignee_id"
: Maps the chosen assignee (fromres.users
) to theassignee_id
field in ourtask.filters
model.filter_field="assignee_checked"
: Indicates that the boolean fieldassignee_checked
intask.filters
should be used to track whether an assignee is selected or not in the UI. When a user clicks an assignee in the sidebar, Odoo updates this boolean field for the correspondingtask.filters
record.avatar_field="avatar_128"
: Displays the user’s avatar (a 128-pixel version) next to their name in the filter sidebar, making it visually appealing and easier to identify team members.
III. Module Installation and Verification
With all the code in place, it’s time to install your new module and see the Odoo 18 Assignee Filter in action!
- Restart Odoo Service:** After making changes to Python files (
.py
), you must restart your Odoo server. For example, if you’re running Odoo via a service, usesudo service odoo-server restart
. - **Update Apps List:**
- Log in to your Odoo instance.
- Navigate to the
Apps
dashboard. - Click on
Update Apps List
to ensure Odoo detects your new module.
- Install the Module:**
- In the
Apps
dashboard, search for “Project Task Calendar Assignee Filter” or “calendar_filter”. - Click the
Activate
button to install your module. Odoo will load all thedata
files (.csv
and.xml
) and register your new models.
- In the
- Test the Filter:**
- Once installed, navigate to the
Project
module. - Open any project and then switch to the
Calendar
view. - Voila! You should now see a brand new “Filter by Assignee” section in the left sidebar, listing your Odoo users.
- Click on different assignees to filter the tasks displayed in the calendar. You will instantly see how the tasks update based on your selection, showcasing the power of the Odoo 18 Assignee Filter. You can select multiple assignees or clear all to see everyone’s tasks.
- Once installed, navigate to the
IV. Beyond the Basics: Enhancing Your Odoo 18 Assignee Filter
While the current implementation provides a robust Odoo 18 Assignee Filter, Odoo’s extensibility allows for further enhancements:
- User-Specific Persistent Preferences: Our
task.filters
model already lays the groundwork! Theassignee_checked
field stores the state. Odoo’swrite_model
andwrite_field
attributes automatically handle saving and retrieving these user-specific preferences. This means if a user selects a set of assignees, leaves the calendar, and returns, their previous filter selection for the Odoo 18 Assignee Filter will be preserved. - Dynamic Filtering Based on Current Project: Currently, the filter applies across all tasks. You could modify the domain of the
assignee_id
field inviews.xml
to only show users assigned to tasks within the current project context. This would require more advanced view inheritance and possibly some JavaScript to capture the current project ID. - Custom Styling and UX Improvements: Use CSS in your
static
folder to customize the look and feel of the filter elements, perhaps highlighting selected assignees more prominently. - Advanced Permissions with Record Rules: Revisit
ir.model.access.csv
. For stricter security, add a record rule fortask.filters
to ensure users can only read and modify their own filter preferences (e.g.,['|', ('user_id', '=', user.id), ('user_id', '=', False)]
). This is a crucial step for data privacy, ensuring your Odoo 18 Assignee Filter remains secure. - Performance Optimization: For very large Odoo instances with thousands of users and tasks, ensure your database indices are optimized for the
assignee_id
field onproject.task
and bothuser_id
andassignee_id
ontask.filters
.
V. Troubleshooting Common Issues
Encountering problems? Here are a few common issues and their solutions:
- Module Not Appearing in Apps List:
- Did you restart the Odoo service after creating the module folder?
- Is your
__manifest__.py
file correctly formatted (especiallyinstallable: True
)? - Is your
calendar_filter
folder in the correct custom addons path? - Did you click “Update Apps List”?
- Filter Not Visible in Calendar View:
- Did you install the module successfully? Check the installed modules list.
- Is
views/views.xml
correctly structured? Pay close attention to theinherit_id
andxpath
expressions. A typo inproject.view_task_calendar
oruser_id
will prevent the inheritance from working. - Are all dependencies (
web
,project
,calendar
) listed in__manifest__.py
and correctly installed?
- Permissions Errors (e.g., “Access Denied”):
- Check
security/ir.model.access.csv
to ensure yourtask.filters
model has appropriate read/write/create/unlink permissions. - If you added a record rule, ensure it’s correctly defined and not overly restrictive for the current user.
- Check
- Python Errors on Server Restart:
- Review
models/task_filters.py
for any syntax errors or incorrect field definitions. Check your Odoo server logs for detailed traceback information. - Ensure
from . import task_filters
is present inmodels/__init__.py
.
- Review
Conclusion: Empower Your Odoo 18 Project Management
Implementing the Odoo 18 Assignee Filter is a fantastic way to elevate your project management capabilities. It provides immediate, actionable insights into workload distribution and task assignments, fostering greater efficiency and collaboration within your team. This customization, while seemingly small, delivers significant value by making your Odoo 18 calendar view more dynamic, user-friendly, and powerful.
We’ve walked through the entire process, from setting up your module structure to defining models, access rights, and view customizations. By following these step-by-step instructions, you’ve not only added a crucial feature but also gained a deeper understanding of Odoo’s powerful extensibility framework.
If you found this tutorial useful and enjoyed mastering the Odoo 18 Assignee Filter, don’t forget to like, share, and subscribe for more Odoo development tips and tricks! Your engagement helps us create more valuable content.
Looking for custom Odoo development, full implementation services, or expert guidance for your Odoo projects? Feel free to reach out to our team directly at contact@odooexperts.com
. We’re here to help you unlock Odoo’s full potential.
You can also support our channel and help us continue creating free tutorials by making a donation through PayPal at farukabidgmail.com
. Every contribution, big or small, truly makes a difference.
Thanks for watching, and we’ll see you in the next video!
Discover more from teguhteja.id
Subscribe to get the latest posts sent to your email.