PURPOSE Clean code and be and more performance oriented. SPECIFICATIONS Various portal pages hold references to archive_groups. It was a summary of customer documents for portal, containing a count of all documents split by model. Currently its computation is not used. Indeed archive_groups is displayed only in 'my_details' page that does not hold any document-based reference or code call. Other calls to archive_groups are dead code as the result is not used. Since 13.0 it is even not computed on standard pages to speedup their load (as it was not used). It is not used anymore and its computation and references can be removed safely, especially with v14 in mind for which we want to remove dead code to maintain. Followup of odoo/odoo#55228 LINKS Task ID-2329081 PR odoo/odoo#55800 PR #12368 closes odoo/odoo#56859 X-original-commit: e75086000ee4317b2ad2994db5d906fbcbd5081f Related: odoo/enterprise#12830 Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com> Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
235 lines
10 KiB
Python
235 lines
10 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from collections import OrderedDict
|
|
from operator import itemgetter
|
|
|
|
from odoo import 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
|
|
|
|
|
|
class CustomerPortal(CustomerPortal):
|
|
|
|
def _prepare_home_portal_values(self, counters):
|
|
values = super()._prepare_home_portal_values(counters)
|
|
if 'project_count' in counters:
|
|
values['project_count'] = request.env['project.project'].search_count([])
|
|
if 'task_count' in counters:
|
|
values['task_count'] = request.env['project.task'].search_count([])
|
|
return values
|
|
|
|
# ------------------------------------------------------------
|
|
# My Project
|
|
# ------------------------------------------------------------
|
|
def _project_get_page_view_values(self, project, access_token, **kwargs):
|
|
values = {
|
|
'page_name': 'project',
|
|
'project': project,
|
|
}
|
|
return self._get_page_view_values(project, access_token, values, 'my_projects_history', False, **kwargs)
|
|
|
|
@http.route(['/my/projects', '/my/projects/page/<int:page>'], type='http', auth="user", website=True)
|
|
def portal_my_projects(self, page=1, date_begin=None, date_end=None, sortby=None, **kw):
|
|
values = self._prepare_portal_layout_values()
|
|
Project = request.env['project.project']
|
|
domain = []
|
|
|
|
searchbar_sortings = {
|
|
'date': {'label': _('Newest'), 'order': 'create_date desc'},
|
|
'name': {'label': _('Name'), 'order': 'name'},
|
|
}
|
|
if not sortby:
|
|
sortby = 'date'
|
|
order = searchbar_sortings[sortby]['order']
|
|
|
|
if date_begin and date_end:
|
|
domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)]
|
|
|
|
# projects count
|
|
project_count = Project.search_count(domain)
|
|
# pager
|
|
pager = portal_pager(
|
|
url="/my/projects",
|
|
url_args={'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby},
|
|
total=project_count,
|
|
page=page,
|
|
step=self._items_per_page
|
|
)
|
|
|
|
# content according to pager and archive selected
|
|
projects = Project.search(domain, order=order, limit=self._items_per_page, offset=pager['offset'])
|
|
request.session['my_projects_history'] = projects.ids[:100]
|
|
|
|
values.update({
|
|
'date': date_begin,
|
|
'date_end': date_end,
|
|
'projects': projects,
|
|
'page_name': 'project',
|
|
'default_url': '/my/projects',
|
|
'pager': pager,
|
|
'searchbar_sortings': searchbar_sortings,
|
|
'sortby': sortby
|
|
})
|
|
return request.render("project.portal_my_projects", values)
|
|
|
|
@http.route(['/my/project/<int:project_id>'], type='http', auth="public", website=True)
|
|
def portal_my_project(self, project_id=None, access_token=None, **kw):
|
|
try:
|
|
project_sudo = self._document_check_access('project.project', project_id, access_token)
|
|
except (AccessError, MissingError):
|
|
return request.redirect('/my')
|
|
|
|
values = self._project_get_page_view_values(project_sudo, access_token, **kw)
|
|
return request.render("project.portal_my_project", values)
|
|
|
|
# ------------------------------------------------------------
|
|
# My Task
|
|
# ------------------------------------------------------------
|
|
def _task_get_page_view_values(self, task, access_token, **kwargs):
|
|
values = {
|
|
'page_name': 'task',
|
|
'task': task,
|
|
'user': request.env.user
|
|
}
|
|
return self._get_page_view_values(task, access_token, values, 'my_tasks_history', False, **kwargs)
|
|
|
|
@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 = {
|
|
'date': {'label': _('Newest'), 'order': 'create_date desc'},
|
|
'name': {'label': _('Title'), 'order': 'name'},
|
|
'stage': {'label': _('Stage'), 'order': 'stage_id, project_id'},
|
|
'project': {'label': _('Project'), 'order': 'project_id, stage_id'},
|
|
'update': {'label': _('Last Stage Update'), 'order': 'date_last_stage_update desc'},
|
|
}
|
|
searchbar_filters = {
|
|
'all': {'label': _('All'), 'domain': []},
|
|
}
|
|
searchbar_inputs = {
|
|
'content': {'input': 'content', 'label': _('Search <span class="nolabel"> (in Content)</span>')},
|
|
'message': {'input': 'message', 'label': _('Search in Messages')},
|
|
'customer': {'input': 'customer', 'label': _('Search in Customer')},
|
|
'stage': {'input': 'stage', 'label': _('Search in Stages')},
|
|
'project': {'input': 'project', 'label': _('Search in Project')},
|
|
'all': {'input': 'all', 'label': _('Search in All')},
|
|
}
|
|
searchbar_groupby = {
|
|
'none': {'input': 'none', 'label': _('None')},
|
|
'project': {'input': 'project', 'label': _('Project')},
|
|
'stage': {'input': 'stage', 'label': _('Stage')},
|
|
}
|
|
|
|
# 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 = 'all'
|
|
domain = searchbar_filters.get(filterby, searchbar_filters.get('all'))['domain']
|
|
|
|
# default group by value
|
|
if not groupby:
|
|
groupby = 'project'
|
|
|
|
if date_begin and date_end:
|
|
domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)]
|
|
|
|
# search
|
|
if search and search_in:
|
|
search_domain = []
|
|
if search_in in ('content', 'all'):
|
|
search_domain = OR([search_domain, ['|', ('name', 'ilike', search), ('description', 'ilike', search)]])
|
|
if search_in in ('customer', 'all'):
|
|
search_domain = OR([search_domain, [('partner_id', 'ilike', search)]])
|
|
if search_in in ('message', 'all'):
|
|
search_domain = OR([search_domain, [('message_ids.body', 'ilike', search)]])
|
|
if search_in in ('stage', 'all'):
|
|
search_domain = OR([search_domain, [('stage_id', 'ilike', search)]])
|
|
if search_in in ('project', 'all'):
|
|
search_domain = OR([search_domain, [('project_id', 'ilike', search)]])
|
|
domain += search_domain
|
|
|
|
# task count
|
|
task_count = request.env['project.task'].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
|
|
if groupby == 'project':
|
|
order = "project_id, %s" % order # force sort on project first to group by project in view
|
|
elif groupby == 'stage':
|
|
order = "stage_id, %s" % order # force sort on stage first to group by stage in view
|
|
|
|
tasks = request.env['project.task'].search(domain, order=order, limit=self._items_per_page, offset=pager['offset'])
|
|
request.session['my_tasks_history'] = tasks.ids[:100]
|
|
|
|
if groupby == 'project':
|
|
grouped_tasks = [request.env['project.task'].concat(*g) for k, g in groupbyelem(tasks, itemgetter('project_id'))]
|
|
elif groupby == 'stage':
|
|
grouped_tasks = [request.env['project.task'].concat(*g) for k, g in groupbyelem(tasks, itemgetter('stage_id'))]
|
|
else:
|
|
grouped_tasks = [tasks]
|
|
|
|
values.update({
|
|
'date': date_begin,
|
|
'date_end': date_end,
|
|
'grouped_tasks': grouped_tasks,
|
|
'page_name': 'task',
|
|
'default_url': '/my/tasks',
|
|
'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)
|
|
|
|
@http.route(['/my/task/<int:task_id>'], type='http', auth="public", website=True)
|
|
def portal_my_task(self, task_id, access_token=None, **kw):
|
|
try:
|
|
task_sudo = self._document_check_access('project.task', task_id, access_token)
|
|
except (AccessError, MissingError):
|
|
return request.redirect('/my')
|
|
|
|
# ensure attachment are accessible with access token inside template
|
|
for attachment in task_sudo.attachment_ids:
|
|
attachment.generate_access_token()
|
|
values = self._task_get_page_view_values(task_sudo, access_token, **kw)
|
|
return request.render("project.portal_my_task", values)
|