Enable Dark Mode!
how-to-add-filters-option-in-website-portal-documents-in-odoo-16.jpg
By: Vishnu P

How to Add Filters Option in Website Portal Documents in Odoo 16

Technical Odoo 16

In Odoo, we have an option for a Customer Portal on the Website module.  It helps to access our documents from the website, like Quotations, Sale orders, Purchase Orders, and many more options. We can get these documents by clicking on each menu. You can refer to the following  blog to learn about how to create customized menus inside a website portal: How to Add a Custom Menu in the Customer Portal of Odoo 16

Users can usually modify or reduce the displayed content in a website portal by using filters to suit their individual choices or needs. A customer portal may give users access to their order history, and filters may make it easier for them to sort and locate particular orders based on the date, status, or other relevant information. Filters are used to improve the user experience by making it simpler for users to discover the information they are looking for and saving time and effort when browsing through huge amounts of content.

Now in the blog, let us discuss how to apply the filter option for the customized menu on the website portal. For this purpose, we have created a custom menu called “Attendance” inside the customer portal.

how-to-add-filters-option-in-website-portal-documents-in-odoo-16-1-cybrosys

We can add the custom menu inside the website customer portal using the following template in xml:

<template id="portal_my_home_menu_attendance"
         name="Portal layout : Attendance menu entries"
         inherit_id="portal.portal_breadcrumbs" priority="30">
   <xpath expr="//ol[hasclass('o_portal_submenu')]" position="inside">
       <li t-if="page_name == 'attendance'"
           t-attf-class="breadcrumb-item #{'active ' if not attendance else ''}">
           <a t-if="attendance"
              t-attf-href="/attendance/list?{{ keep_query() }}">
               Attendance
           </a>
           <t t-else="">Attendance</t>
       </li>
   </xpath>
</template>

Then, after we need to define a function inside the Python controller to show and add the custom menu with the record count, we can use the following code for that.

class PortalAttendance(portal.CustomerPortal):
   """To get the values of portal attendance"""
   def _prepare_home_portal_values(self, counters):
       """To get the count of the attendance in portal"""
       values = super(PortalAttendance, self)._prepare_home_portal_values(
           counters)
       uid = request.session.id
       user_id = request.env['res.users'].browse(uid)
       employee_id = request.env['hr.employee'].search(
           [('user_id', '=', user_id.id)])
       attendance_count = request.env['hr.attendance'].search_count(
           [('is_portal', '=', True), ('employee_id', '=', employee_id.id)])
       values.update({
           'attendance_count': attendance_count
       })
       return values

In this function, we override  the _prepare_home_portal_values() function and fetch the attendance count and pass the value to the attendence_count. Overriding the function will allow you to add features to an existing function.

In the template, we specified the URL for the custom menu. It will trigger the corresponding URL while clicking our custom portal, and then, we need to define a function for the specific URL in a controller.

@http.route(['/attendance/list', '/attendance/list/page/<int:page>'],
           type='http', website=True)
def attendance_search_sort_view(self, filterby="all", **kwargs):
   """To search and filter in the list view of attendance"""
   uid = request.session.uid
   user_id = request.env['res.users'].browse(uid)
   employee_id = request.env['hr.employee'].search(
       [('user_id', '=', user_id.id)])
   today = fields.Date.today()
   last_week = today + relativedelta(weeks=-1)
   last_month = today + relativedelta(months=-1)
   last_year = today + relativedelta(years=-1)
   searchbar_filters = {
       'all': {'label': 'All', 'domain': []},
       'today': {
           'label': 'Today',
           'domain': [("check_in", ">=",
                       fields.Datetime.to_string(fields.Datetime.today())),
                      ("check_in", "<=", fields.Datetime.to_string(
                          fields.Datetime.today().replace(hour=23,
                                                          minute=59,
                                                          second=59)))]},
       'week': {
           'label': 'Last Week',
           'domain': [
               ('check_in', '>=', date_utils.start_of(last_week, "week")),
               ('check_in', '<=', date_utils.end_of(last_week, 'week'))]},
       'month': {
           'label': 'Last Month',
           'domain': [('check_in', '>=',
                       date_utils.start_of(last_month, 'month')),
                      ('check_in', '<=',
                       date_utils.end_of(last_month, 'month'))]},
       'year': {
           'label': 'Last Year',
           'domain': [
               ('check_in', '>=', date_utils.start_of(last_year, 'year')),
               ('check_in', '<=', date_utils.end_of(last_year, 'year'))]}}
   filter_domain = searchbar_filters[filterby]['domain']
   attendance_obj = request.env['hr.attendance'].search(
       [('is_portal', '=', True), ('employee_id', '=', employee_id.id)])
   total_attendance = attendance_obj.search_count(
       [('is_portal', '=', True),
        ('employee_id', '=',
         employee_id.id)] + filter_domain)
   page_detail = pager(url='/attendance/list',
                       total=total_attendance,
                       url_args={'filt’rby': filterby})
   attendance_domain = [('is_portal', '=', True),
                        ('employee_id', '=', employee_id.id)]
   if filter_domain:
      attendance_domain += filter_domain
   attendance = attendance_obj.search(
       attendance_domain,
         )
   vals = {
       'attendance': attendance,
       'page_name': 'attendance',
       'pager': page_detail,
       'default_url': '/attendance/list',
       'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),
       'filterby': filterby,
   }
   return request.render(
       "web_portal_attendance.portal_list_attendance_order", vals)

The above controller will trigger while we click the custom menu that we created. In this, we added five filters that are ‘All’,‘Today’,’Last Week’,’Last Month’, ‘Last Year’. We set the “All’ filter option as a default option for the view. For the filter, we need to set the values of filter options using the relativedelta using the following code:

today = fields.Date.today()
last_week = today + relativedelta(weeks=-1)
last_month = today + relativedelta(months=-1)
last_year = today + relativedelta(years=-1)

Then after we need to set the label and filter domain for all filters. We can use the following code for that.

searchbar_filters = {

   'all': {'label': 'All', 'domain': []},
   'today': {
       'label': 'Today',
       'domain': [("check_in", ">=",
                   fields.Datetime.to_string(fields.Datetime.today())),
                  ("check_in", "<=", fields.Datetime.to_string(
                      fields.Datetime.today().replace(hour=23,
                                                      minute=59,
                                                      second=59)))]},
   'week': {
       'label': 'Last Week',
       'domain': [
           ('check_in', '>=', date_utils.start_of(last_week, "week")),
           ('check_in', '<=', date_utils.end_of(last_week, 'week'))]},
   'month': {
       'label': 'Last Month',
       'domain': [('check_in', '>=',
                   date_utils.start_of(last_month, 'month')),
                  ('check_in', '<=',
                   date_utils.end_of(last_month, 'month'))]},
   'year': {
       'label': 'Last Year',
       'domain': [
           ('check_in', '>=', date_utils.start_of(last_year, 'year')),
           ('check_in', '<=', date_utils.end_of(last_year, 'year'))]}}

Then after we need to fetch the attendance record from the database based on the filter that we selected using the code:

filter_domain = searchbar_filters[filterby]['domain']
attendance_obj = request.env['hr.attendance'].search(
   [('is_portal', '=', True), ('employee_id', '=', employee_id.id)])
total_attendance = attendance_obj.search_count(
   [('is_portal', '=', True),
    ('employee_id', '=',
     employee_id.id)] + filter_domain)
page_detail = pager(url='/attendance/list',
                   total=total_attendance,
                   url_args={'filterby': filterby})
attendance_domain = [('is_portal', '=', True),
                    ('employee_id', '=', employee_id.id)]
if filter_domain:
   attendance_domain += filter_domain
attendance = attendance_obj.search(
   attendance_domain,
  )

After fetching the attendance record, we need to pass the values to the template that we created for the view.

vals = {
   'attendance': attendance,
   'page_name': 'attendance',
   'pager': page_detail,
   'default_url': '/attendance/list',
   'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),
   'filterby': filterby,
}
return request.render(
   "web_portal_attendance.portal_list_attendance_order", vals)

After providing code, we can see the filter by option is added inside the top right corner.

how-to-add-filters-option-in-website-portal-documents-in-odoo-16-2-cybrosys

By default, we can see all records of the employee. We can apply the filters by clicking on the filter options.

how-to-add-filters-option-in-website-portal-documents-in-odoo-16-3-cybrosys

In the customer portal on the website, we can add a custom filter by option in a custom menu in this way. By choosing proper filters, the filter by functionality enables users to access huge amounts of data.


If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message