Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions project_ux/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
# directory
##############################################################################
from . import models
from . import controllers

1 change: 1 addition & 0 deletions project_ux/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
'data': [
'views/project_task_views.xml',
'views/project_project_views.xml',
'views/project_task_search_inherit.xml',
],
'demo': [
],
Expand Down
1 change: 1 addition & 0 deletions project_ux/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import portal_task
122 changes: 122 additions & 0 deletions project_ux/controllers/portal_task.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
from odoo.addons.project.controllers.portal import ProjectCustomerPortal
from collections import OrderedDict
from operator import itemgetter
from markupsafe import Markup
from odoo import conf, http, _
from odoo.exceptions import AccessError, MissingError
from odoo.http import request
from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager
from odoo.tools import groupby as groupbyelem
from odoo.osv.expression import OR, AND
from odoo.addons.web.controllers.main import HomeStaticTemplateHelpers




class ProjectCustomerPortal(ProjectCustomerPortal):

@http.route(['/my/tasks', '/my/tasks/page/<int:page>'], type='http', auth="user", website=True)
def portal_my_tasks(self, page=1, date_begin=None, date_end=None, sortby=None, filterby=None, search=None, search_in='content', groupby=None, **kw):
values = self._prepare_portal_layout_values()
searchbar_sortings = self._task_get_searchbar_sortings()
searchbar_sortings = dict(sorted(self._task_get_searchbar_sortings().items(),
key=lambda item: item[1]["sequence"]))

searchbar_filters = {
'all': {'label': _('All'), 'domain': []},
'open': {'label': _('Open'), 'domain': [('stage_id.is_closed', '=', False)]}
}

searchbar_inputs = self._task_get_searchbar_inputs()
searchbar_groupby = self._task_get_searchbar_groupby()

# extends filterby criteria with project the customer has access to
projects = request.env['project.project'].search([])
for project in projects:
searchbar_filters.update({
str(project.id): {'label': project.name, 'domain': [('project_id', '=', project.id)]}
})

# extends filterby criteria with project (criteria name is the project id)
# Note: portal users can't view projects they don't follow
project_groups = request.env['project.task'].read_group([('project_id', 'not in', projects.ids)],
['project_id'], ['project_id'])
for group in project_groups:
proj_id = group['project_id'][0] if group['project_id'] else False
proj_name = group['project_id'][1] if group['project_id'] else _('Others')
searchbar_filters.update({
str(proj_id): {'label': proj_name, 'domain': [('project_id', '=', proj_id)]}
})

# default sort by value
if not sortby:
sortby = 'date'
order = searchbar_sortings[sortby]['order']

# default filter by value
if not filterby:
filterby = 'open'
domain = searchbar_filters.get(filterby, searchbar_filters.get('all'))['domain']
# default group by value
if not groupby:
groupby = 'stage'

if date_begin and date_end:
domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)]

# search
if search and search_in:
domain += self._task_get_search_domain(search_in, search)

TaskSudo = request.env['project.task'].sudo()
domain = AND([domain, request.env['ir.rule']._compute_domain(TaskSudo._name, 'read')])

# task count
task_count = TaskSudo.search_count(domain)
# pager
pager = portal_pager(
url="/my/tasks",
url_args={'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby, 'filterby': filterby, 'groupby': groupby, 'search_in': search_in, 'search': search},
total=task_count,
page=page,
step=self._items_per_page
)
# content according to pager and archive selected
order = self._task_get_order(order, groupby)

tasks = TaskSudo.search(domain, order=order, limit=self._items_per_page, offset=pager['offset'])
request.session['my_tasks_history'] = tasks.ids[:100]

groupby_mapping = self._task_get_groupby_mapping()
group = groupby_mapping.get(groupby)
if group:
grouped_tasks = [request.env['project.task'].concat(*g) for k, g in groupbyelem(tasks, itemgetter(group))]
else:
grouped_tasks = [tasks]

task_states = dict(request.env['project.task']._fields['kanban_state']._description_selection(request.env))
if sortby == 'status':
if groupby == 'none' and grouped_tasks:
grouped_tasks[0] = grouped_tasks[0].sorted(lambda tasks: task_states.get(tasks.kanban_state))
else:
grouped_tasks.sort(key=lambda tasks: task_states.get(tasks[0].kanban_state))

values.update({
'date': date_begin,
'date_end': date_end,
'grouped_tasks': grouped_tasks,
'page_name': 'task',
'default_url': '/my/tasks',
'task_url': 'task',
'pager': pager,
'searchbar_sortings': searchbar_sortings,
'searchbar_groupby': searchbar_groupby,
'searchbar_inputs': searchbar_inputs,
'search_in': search_in,
'search': search,
'sortby': sortby,
'groupby': groupby,
'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),
'filterby': filterby,
})
return request.render("project.portal_my_tasks", values)
16 changes: 16 additions & 0 deletions project_ux/views/project_task_search_inherit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<odoo>
<record id="project_task_search_inherit" model="ir.ui.view">
<field name="name">project.task.search.form.extended.inherit</field>
<field name="model">project.task</field>
<field name="inherit_id" ref="project.view_task_search_form_extended"/>
<field name="arch" type="xml">
<xpath expr="//filter[@name='my_followed_projects']" position="after">
<separator/>
<filter string="Abierto" domain="[('stage_id.is_closed','=',False)]" name="is_open"/>
<filter string="Cerrado" domain="[('stage_id.is_closed','=',True)]" name="is_close"/>
<separator/>
</xpath>
</field>
</record>
</odoo>