summaryrefslogtreecommitdiff
path: root/addons/hr_timesheet/controllers
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/hr_timesheet/controllers
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/hr_timesheet/controllers')
-rw-r--r--addons/hr_timesheet/controllers/__init__.py5
-rw-r--r--addons/hr_timesheet/controllers/portal.py160
-rw-r--r--addons/hr_timesheet/controllers/project.py26
3 files changed, 191 insertions, 0 deletions
diff --git a/addons/hr_timesheet/controllers/__init__.py b/addons/hr_timesheet/controllers/__init__.py
new file mode 100644
index 00000000..86c009b5
--- /dev/null
+++ b/addons/hr_timesheet/controllers/__init__.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import portal
+from . import project
diff --git a/addons/hr_timesheet/controllers/portal.py b/addons/hr_timesheet/controllers/portal.py
new file mode 100644
index 00000000..b244ee3e
--- /dev/null
+++ b/addons/hr_timesheet/controllers/portal.py
@@ -0,0 +1,160 @@
+# -*- 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 datetime import datetime
+
+from odoo import fields, http, _
+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
+
+
+class TimesheetCustomerPortal(CustomerPortal):
+
+ def _prepare_home_portal_values(self, counters):
+ values = super()._prepare_home_portal_values(counters)
+ if 'timesheet_count' in counters:
+ domain = request.env['account.analytic.line']._timesheet_get_portal_domain()
+ values['timesheet_count'] = request.env['account.analytic.line'].sudo().search_count(domain)
+ return values
+
+ def _get_searchbar_inputs(self):
+ return {
+ 'all': {'input': 'all', 'label': _('Search in All')},
+ 'project': {'input': 'project', 'label': _('Search in Project')},
+ 'name': {'input': 'name', 'label': _('Search in Description')},
+ 'employee': {'input': 'employee', 'label': _('Search in Employee')},
+ 'task': {'input': 'task', 'label': _('Search in Task')}
+ }
+
+ 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')}
+ }
+
+ 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'
+ }
+
+ @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_sudo = request.env['account.analytic.line'].sudo()
+ values = self._prepare_portal_layout_values()
+ domain = request.env['account.analytic.line']._timesheet_get_portal_domain()
+ _items_per_page = 100
+
+ searchbar_sortings = {
+ 'date': {'label': _('Newest'), 'order': 'date desc'},
+ 'name': {'label': _('Description'), 'order': 'name'},
+ }
+
+ searchbar_inputs = self._get_searchbar_inputs()
+
+ searchbar_groupby = self._get_searchbar_groupby()
+
+ today = fields.Date.today()
+ quarter_start, quarter_end = date_utils.get_quarter(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': [("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'))]},
+ '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'))]},
+ }
+ # default sort by value
+ if not sortby:
+ sortby = 'date'
+ order = searchbar_sortings[sortby]['order']
+ # default filter by value
+ if not filterby:
+ filterby = 'all'
+ domain = AND([domain, searchbar_filters[filterby]['domain']])
+
+ if search and search_in:
+ domain += self._get_search_domain(search_in, search)
+
+ timesheet_count = Timesheet_sudo.search_count(domain)
+ # pager
+ pager = portal_pager(
+ url="/my/timesheets",
+ url_args={'sortby': sortby, 'search_in': search_in, 'search': search, 'filterby': filterby, 'groupby': groupby},
+ total=timesheet_count,
+ page=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'])
+ if field:
+ if groupby == 'date':
+ time_data = Timesheet_sudo.read_group(domain, ['date', 'unit_amount:sum'], ['date:day'])
+ mapped_time = dict([(datetime.strptime(m['date:day'], '%d %b %Y').date(), m['unit_amount']) for m in time_data])
+ grouped_timesheets = [(Timesheet_sudo.concat(*g), mapped_time[k]) for k, g in groupbyelem(timesheets, itemgetter('date'))]
+ else:
+ time_data = 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])
+ 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'))
+ )] if timesheets else []
+ return timesheets, grouped_timesheets
+
+ timesheets, grouped_timesheets = get_timesheets()
+
+ values.update({
+ 'timesheets': timesheets,
+ 'grouped_timesheets': grouped_timesheets,
+ 'page_name': 'timesheet',
+ 'default_url': '/my/timesheets',
+ 'pager': pager,
+ 'searchbar_sortings': searchbar_sortings,
+ 'search_in': search_in,
+ 'search': search,
+ 'sortby': sortby,
+ 'groupby': groupby,
+ 'searchbar_inputs': searchbar_inputs,
+ 'searchbar_groupby': searchbar_groupby,
+ 'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),
+ 'filterby': filterby,
+ 'is_uom_day': request.env['account.analytic.line']._is_timesheet_encode_uom_day(),
+ })
+ return request.render("hr_timesheet.portal_my_timesheets", values)
diff --git a/addons/hr_timesheet/controllers/project.py b/addons/hr_timesheet/controllers/project.py
new file mode 100644
index 00000000..31fbe2f3
--- /dev/null
+++ b/addons/hr_timesheet/controllers/project.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from collections import defaultdict
+from odoo.http import request
+from odoo.osv import expression
+
+from odoo.addons.project.controllers.portal import CustomerPortal
+
+
+class ProjectCustomerPortal(CustomerPortal):
+
+ def _task_get_page_view_values(self, task, access_token, **kwargs):
+ values = super(ProjectCustomerPortal, self)._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)]])
+ 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['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