mirror of
https://github.com/bringout/oca-ocb-hr.git
synced 2026-04-25 20:32:03 +02:00
19.0 vanilla
This commit is contained in:
parent
a1137a1456
commit
e1d89e11e3
2789 changed files with 1093187 additions and 605897 deletions
|
|
@ -1,14 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from collections import OrderedDict
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from operator import itemgetter
|
||||
|
||||
from odoo import fields, http, _
|
||||
from odoo.fields import Domain
|
||||
from odoo.http import request
|
||||
from odoo.tools import date_utils, groupby as groupbyelem
|
||||
from odoo.osv.expression import AND, OR
|
||||
|
||||
from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager
|
||||
from odoo.addons.project.controllers.portal import ProjectCustomerPortal
|
||||
|
|
@ -26,99 +24,96 @@ class TimesheetCustomerPortal(CustomerPortal):
|
|||
|
||||
def _get_searchbar_inputs(self):
|
||||
return {
|
||||
'all': {'input': 'all', 'label': _('Search in All')},
|
||||
'employee': {'input': 'employee', 'label': _('Search in Employee')},
|
||||
'project': {'input': 'project', 'label': _('Search in Project')},
|
||||
'task': {'input': 'task', 'label': _('Search in Task')},
|
||||
'name': {'input': 'name', 'label': _('Search in Description')},
|
||||
'name': {'input': 'name', 'label': _('Search in Description'), 'sequence': 10},
|
||||
'employee_id': {'input': 'employee_id', 'label': _('Search in Employee'), 'sequence': 20},
|
||||
'project_id': {'input': 'project_id', 'label': _('Search in Project'), 'sequence': 30},
|
||||
'task_id': {'input': 'task_id', 'label': _('Search in Task'), 'sequence': 40},
|
||||
'parent_task_id': {'input': 'parent_task_id', 'label': _('Search in Parent Task'), 'sequence': 70},
|
||||
}
|
||||
|
||||
def _task_get_searchbar_sortings(self, milestones_allowed):
|
||||
values = super()._task_get_searchbar_sortings(milestones_allowed)
|
||||
values['progress'] = {'label': _('Progress'), 'order': 'progress asc', 'sequence': 10}
|
||||
return values
|
||||
def _task_get_searchbar_sortings(self, milestones_allowed, project=False):
|
||||
return super()._task_get_searchbar_sortings(milestones_allowed, project) | {
|
||||
'progress asc': {'label': _('Progress'), 'order': 'progress asc', 'sequence': 100},
|
||||
}
|
||||
|
||||
def _get_searchbar_groupby(self):
|
||||
return {
|
||||
'none': {'input': 'none', 'label': _('None')},
|
||||
'project': {'input': 'project', 'label': _('Project')},
|
||||
'task': {'input': 'task', 'label': _('Task')},
|
||||
'date': {'input': 'date', 'label': _('Date')},
|
||||
'employee': {'input': 'employee', 'label': _('Employee')}
|
||||
'none': {'label': _('None'), 'sequence': 10},
|
||||
'date': {'label': _('Date'), 'sequence': 20},
|
||||
'project_id': {'label': _('Project'), 'sequence': 30},
|
||||
'parent_task_id': {'label': _('Parent Task'), 'sequence': 40},
|
||||
'task_id': {'label': _('Task'), 'sequence': 50},
|
||||
'employee_id': {'label': _('Employee'), 'sequence': 70},
|
||||
}
|
||||
|
||||
def _get_search_domain(self, search_in, search):
|
||||
search_domain = []
|
||||
if search_in in ('project', 'all'):
|
||||
search_domain = OR([search_domain, [('project_id', 'ilike', search)]])
|
||||
if search_in in ('name', 'all'):
|
||||
search_domain = OR([search_domain, [('name', 'ilike', search)]])
|
||||
if search_in in ('employee', 'all'):
|
||||
search_domain = OR([search_domain, [('employee_id', 'ilike', search)]])
|
||||
if search_in in ('task', 'all'):
|
||||
search_domain = OR([search_domain, [('task_id', 'ilike', search)]])
|
||||
return search_domain
|
||||
|
||||
def _get_groupby_mapping(self):
|
||||
return {
|
||||
'project': 'project_id',
|
||||
'task': 'task_id',
|
||||
'employee': 'employee_id',
|
||||
'date': 'date'
|
||||
}
|
||||
if search_in in self._get_searchbar_inputs():
|
||||
return Domain(search_in, 'ilike', search)
|
||||
else:
|
||||
return Domain.FALSE
|
||||
|
||||
def _get_searchbar_sortings(self):
|
||||
return {
|
||||
'date': {'label': _('Newest'), 'order': 'date desc'},
|
||||
'employee': {'label': _('Employee'), 'order': 'employee_id'},
|
||||
'project': {'label': _('Project'), 'order': 'project_id'},
|
||||
'task': {'label': _('Task'), 'order': 'task_id'},
|
||||
'name': {'label': _('Description'), 'order': 'name'},
|
||||
'date desc': {'label': _('Newest')},
|
||||
'employee_id': {'label': _('Employee')},
|
||||
'project_id': {'label': _('Project')},
|
||||
'task_id': {'label': _('Task')},
|
||||
'name': {'label': _('Description')},
|
||||
}
|
||||
|
||||
def _project_get_page_view_values(self, project, access_token, page=1, date_begin=None, date_end=None, sortby=None, search=None, search_in='content', groupby=None, **kwargs):
|
||||
values = super()._project_get_page_view_values(project, access_token, page, date_begin, date_end, sortby, search, search_in, groupby, **kwargs)
|
||||
values['allow_timesheets'] = project.allow_timesheets
|
||||
return values
|
||||
|
||||
@http.route(['/my/timesheets', '/my/timesheets/page/<int:page>'], type='http', auth="user", website=True)
|
||||
def portal_my_timesheets(self, page=1, sortby=None, filterby=None, search=None, search_in='all', groupby='none', **kw):
|
||||
Timesheet = request.env['account.analytic.line']
|
||||
domain = Timesheet._timesheet_get_portal_domain()
|
||||
domain = Domain(Timesheet._timesheet_get_portal_domain())
|
||||
Timesheet_sudo = Timesheet.sudo()
|
||||
|
||||
values = self._prepare_portal_layout_values()
|
||||
_items_per_page = 100
|
||||
items_per_page = 100
|
||||
|
||||
searchbar_sortings = self._get_searchbar_sortings()
|
||||
|
||||
searchbar_inputs = self._get_searchbar_inputs()
|
||||
searchbar_inputs = dict(sorted(self._get_searchbar_inputs().items(), key=lambda item: item[1]['sequence']))
|
||||
|
||||
searchbar_groupby = self._get_searchbar_groupby()
|
||||
searchbar_groupby = dict(sorted(self._get_searchbar_groupby().items(), key=lambda item: item[1]['sequence']))
|
||||
|
||||
today = fields.Date.today()
|
||||
quarter_start, quarter_end = date_utils.get_quarter(today)
|
||||
last_quarter_date = date_utils.subtract(quarter_start, weeks=1)
|
||||
last_quarter_start, last_quarter_end = date_utils.get_quarter(last_quarter_date)
|
||||
last_week = today + relativedelta(weeks=-1)
|
||||
last_month = today + relativedelta(months=-1)
|
||||
last_year = today + relativedelta(years=-1)
|
||||
|
||||
searchbar_filters = {
|
||||
'all': {'label': _('All'), 'domain': []},
|
||||
'last_year': {'label': _('Last Year'), 'domain': [('date', '>=', date_utils.start_of(last_year, 'year')), ('date', '<=', date_utils.end_of(last_year, 'year'))]},
|
||||
'last_quarter': {'label': _('Last Quarter'), 'domain': [('date', '>=', last_quarter_start), ('date', '<=', last_quarter_end)]},
|
||||
'last_month': {'label': _('Last Month'), 'domain': [('date', '>=', date_utils.start_of(last_month, 'month')), ('date', '<=', date_utils.end_of(last_month, 'month'))]},
|
||||
'last_week': {'label': _('Last Week'), 'domain': [('date', '>=', date_utils.start_of(last_week, "week")), ('date', '<=', date_utils.end_of(last_week, 'week'))]},
|
||||
'today': {'label': _('Today'), 'domain': [("date", "=", today)]},
|
||||
'week': {'label': _('This week'), 'domain': [('date', '>=', date_utils.start_of(today, "week")), ('date', '<=', date_utils.end_of(today, 'week'))]},
|
||||
'month': {'label': _('This month'), 'domain': [('date', '>=', date_utils.start_of(today, 'month')), ('date', '<=', date_utils.end_of(today, 'month'))]},
|
||||
'year': {'label': _('This year'), 'domain': [('date', '>=', date_utils.start_of(today, 'year')), ('date', '<=', date_utils.end_of(today, 'year'))]},
|
||||
'week': {'label': _('This Week'), 'domain': [('date', '>=', date_utils.start_of(today, "week")), ('date', '<=', date_utils.end_of(today, 'week'))]},
|
||||
'month': {'label': _('This Month'), 'domain': [('date', '>=', date_utils.start_of(today, 'month')), ('date', '<=', date_utils.end_of(today, 'month'))]},
|
||||
'quarter': {'label': _('This Quarter'), 'domain': [('date', '>=', quarter_start), ('date', '<=', quarter_end)]},
|
||||
'last_week': {'label': _('Last week'), 'domain': [('date', '>=', date_utils.start_of(last_week, "week")), ('date', '<=', date_utils.end_of(last_week, 'week'))]},
|
||||
'last_month': {'label': _('Last month'), 'domain': [('date', '>=', date_utils.start_of(last_month, 'month')), ('date', '<=', date_utils.end_of(last_month, 'month'))]},
|
||||
'last_year': {'label': _('Last year'), 'domain': [('date', '>=', date_utils.start_of(last_year, 'year')), ('date', '<=', date_utils.end_of(last_year, 'year'))]},
|
||||
'year': {'label': _('This Year'), 'domain': [('date', '>=', date_utils.start_of(today, 'year')), ('date', '<=', date_utils.end_of(today, 'year'))]},
|
||||
}
|
||||
# default sort by value
|
||||
if not sortby:
|
||||
sortby = 'date'
|
||||
order = searchbar_sortings[sortby]['order']
|
||||
sortby = 'date desc'
|
||||
# default filter by value
|
||||
if not filterby:
|
||||
filterby = 'all'
|
||||
domain = AND([domain, searchbar_filters[filterby]['domain']])
|
||||
domain &= Domain(searchbar_filters[filterby]['domain'])
|
||||
|
||||
if search and search_in:
|
||||
domain += self._get_search_domain(search_in, search)
|
||||
domain &= self._get_search_domain(search_in, search)
|
||||
|
||||
if parent_task_id := kw.get('parent_task_id'):
|
||||
domain &= Domain('parent_task_id', '=', int(parent_task_id))
|
||||
|
||||
timesheet_count = Timesheet_sudo.search_count(domain)
|
||||
# pager
|
||||
|
|
@ -127,30 +122,29 @@ class TimesheetCustomerPortal(CustomerPortal):
|
|||
url_args={'sortby': sortby, 'search_in': search_in, 'search': search, 'filterby': filterby, 'groupby': groupby},
|
||||
total=timesheet_count,
|
||||
page=page,
|
||||
step=_items_per_page
|
||||
step=items_per_page,
|
||||
)
|
||||
|
||||
def get_timesheets():
|
||||
groupby_mapping = self._get_groupby_mapping()
|
||||
field = groupby_mapping.get(groupby, None)
|
||||
orderby = '%s, %s' % (field, order) if field else order
|
||||
timesheets = Timesheet_sudo.search(domain, order=orderby, limit=_items_per_page, offset=pager['offset'])
|
||||
field = None if groupby == 'none' else groupby
|
||||
orderby = '%s, %s' % (field, sortby) if field else sortby
|
||||
timesheets = Timesheet_sudo.search(domain, order=orderby, limit=items_per_page, offset=pager['offset'])
|
||||
if field:
|
||||
if groupby == 'date':
|
||||
raw_timesheets_group = Timesheet_sudo.read_group(
|
||||
domain, ["unit_amount:sum", "ids:array_agg(id)"], ["date:day"]
|
||||
raw_timesheets_group = Timesheet_sudo._read_group(
|
||||
domain, ['date:day'], ['unit_amount:sum', 'id:recordset'], order='date:day desc'
|
||||
)
|
||||
grouped_timesheets = [(Timesheet_sudo.browse(group["ids"]), group["unit_amount"]) for group in raw_timesheets_group]
|
||||
grouped_timesheets = [(records, unit_amount) for __, unit_amount, records in raw_timesheets_group]
|
||||
|
||||
else:
|
||||
time_data = Timesheet_sudo.read_group(domain, [field, 'unit_amount:sum'], [field])
|
||||
mapped_time = dict([(m[field][0] if m[field] else False, m['unit_amount']) for m in time_data])
|
||||
time_data = Timesheet_sudo._read_group(domain, [field], ['unit_amount:sum'])
|
||||
mapped_time = {field.id: unit_amount for field, unit_amount in time_data}
|
||||
grouped_timesheets = [(Timesheet_sudo.concat(*g), mapped_time[k.id]) for k, g in groupbyelem(timesheets, itemgetter(field))]
|
||||
return timesheets, grouped_timesheets
|
||||
|
||||
grouped_timesheets = [(
|
||||
timesheets,
|
||||
sum(Timesheet_sudo.search(domain).mapped('unit_amount'))
|
||||
Timesheet_sudo._read_group(domain, aggregates=['unit_amount:sum'])[0][0]
|
||||
)] if timesheets else []
|
||||
return timesheets, grouped_timesheets
|
||||
|
||||
|
|
@ -169,23 +163,24 @@ class TimesheetCustomerPortal(CustomerPortal):
|
|||
'groupby': groupby,
|
||||
'searchbar_inputs': searchbar_inputs,
|
||||
'searchbar_groupby': searchbar_groupby,
|
||||
'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),
|
||||
'searchbar_filters': searchbar_filters,
|
||||
'filterby': filterby,
|
||||
'is_uom_day': request.env['account.analytic.line']._is_timesheet_encode_uom_day(),
|
||||
})
|
||||
return request.render("hr_timesheet.portal_my_timesheets", values)
|
||||
|
||||
|
||||
class TimesheetProjectCustomerPortal(ProjectCustomerPortal):
|
||||
|
||||
def _show_task_report(self, task_sudo, report_type, download):
|
||||
domain = request.env['account.analytic.line']._timesheet_get_portal_domain()
|
||||
task_domain = AND([domain, [('task_id', '=', task_sudo.id)]])
|
||||
task_domain = Domain(domain) & Domain('task_id', '=', task_sudo.id)
|
||||
timesheets = request.env['account.analytic.line'].sudo().search(task_domain)
|
||||
return self._show_report(model=timesheets,
|
||||
report_type=report_type, report_ref='hr_timesheet.timesheet_report_task_timesheets', download=download)
|
||||
|
||||
def _prepare_tasks_values(self, page, date_begin, date_end, sortby, search, search_in, groupby, url="/my/tasks", domain=None, su=False):
|
||||
values = super()._prepare_tasks_values(page, date_begin, date_end, sortby, search, search_in, groupby, url, domain, su)
|
||||
def _prepare_tasks_values(self, page, date_begin, date_end, sortby, search, search_in, groupby, url="/my/tasks", domain=None, su=False, project=False):
|
||||
values = super()._prepare_tasks_values(page, date_begin, date_end, sortby, search, search_in, groupby, url, domain, su, project)
|
||||
values.update(
|
||||
is_uom_day=request.env['account.analytic.line']._is_timesheet_encode_uom_day(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,21 +1,26 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from collections import defaultdict
|
||||
from odoo.fields import Domain
|
||||
from odoo.http import request
|
||||
from odoo.osv import expression
|
||||
|
||||
from odoo.addons.project.controllers.portal import CustomerPortal
|
||||
|
||||
|
||||
class ProjectCustomerPortal(CustomerPortal):
|
||||
|
||||
def _prepare_project_sharing_session_info(self, project, task=None):
|
||||
session_info = super()._prepare_project_sharing_session_info(project, task)
|
||||
|
||||
def _get_project_sharing_company(self, project):
|
||||
company = project.company_id
|
||||
if not company:
|
||||
timesheet = request.env['account.analytic.line'].sudo().search([('project_id', '=', project.id)], limit=1)
|
||||
company = timesheet.company_id or request.env.user.company_id
|
||||
return company
|
||||
|
||||
def _prepare_project_sharing_session_info(self, project):
|
||||
session_info = super()._prepare_project_sharing_session_info(project)
|
||||
company = request.env['res.company'].sudo().browse(session_info['user_companies']['current_company'])
|
||||
timesheet_encode_uom = company.timesheet_encode_uom_id
|
||||
project_time_mode_uom = company.project_time_mode_id
|
||||
|
||||
session_info['user_companies']['allowed_companies'][company.id].update(
|
||||
timesheet_uom_id=timesheet_encode_uom.id,
|
||||
timesheet_uom_factor=project_time_mode_uom._compute_quantity(
|
||||
|
|
@ -33,20 +38,16 @@ class ProjectCustomerPortal(CustomerPortal):
|
|||
'timesheet_widget': uom.timesheet_widget,
|
||||
} for uom in [timesheet_encode_uom, project_time_mode_uom]
|
||||
}
|
||||
session_info['user_context']['allow_timesheets'] = project.allow_timesheets
|
||||
return session_info
|
||||
|
||||
def _task_get_page_view_values(self, task, access_token, **kwargs):
|
||||
values = super(ProjectCustomerPortal, self)._task_get_page_view_values(task, access_token, **kwargs)
|
||||
values = super()._task_get_page_view_values(task, access_token, **kwargs)
|
||||
domain = request.env['account.analytic.line']._timesheet_get_portal_domain()
|
||||
task_domain = expression.AND([domain, [('task_id', '=', task.id)]])
|
||||
subtask_domain = expression.AND([domain, [('task_id', 'in', task.child_ids.ids)]])
|
||||
task_domain = Domain(domain) & Domain('task_id', '=', task.id)
|
||||
timesheets = request.env['account.analytic.line'].sudo().search(task_domain)
|
||||
subtasks_timesheets = request.env['account.analytic.line'].sudo().search(subtask_domain)
|
||||
timesheets_by_subtask = defaultdict(lambda: request.env['account.analytic.line'].sudo())
|
||||
for timesheet in subtasks_timesheets:
|
||||
timesheets_by_subtask[timesheet.task_id] |= timesheet
|
||||
|
||||
values['allow_timesheets'] = task.allow_timesheets
|
||||
values['timesheets'] = timesheets
|
||||
values['timesheets_by_subtask'] = timesheets_by_subtask
|
||||
values['is_uom_day'] = request.env['account.analytic.line']._is_timesheet_encode_uom_day()
|
||||
return values
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue