You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

233 lines
10 KiB

# -*- coding: utf-8 -*-
################################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
# Author: THASNI CP (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
import pytz
from collections import OrderedDict
from datetime import datetime
from dateutil.relativedelta import relativedelta
from odoo import fields
from odoo import http
from odoo.http import request
from odoo.tools import date_utils
from odoo.addons.portal.controllers import portal
from odoo.addons.portal.controllers.portal import pager
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.uid
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
@http.route('/attendance/checkin', type='http', auth='user', website=True)
def attendance_checkin(self):
"""When clicking the checkin button it will redirect to the check in
template"""
uid = request.session.uid
user_id = request.env['res.users'].browse(uid)
employee_id = request.env['hr.employee'].search(
[('user_id', '=', user_id.id)])
values = {
'name': employee_id.name,
'image': employee_id.image_1920,
'check_in': datetime.now()
}
return request.render("web_portal_attendance.check_in_template", values)
@http.route('/check/in', type='http', auth='user', website=True)
def attendance_creation(self):
"""When clicking the checkin button it will create attendance to the
backend"""
uid = request.session.uid
user_id = request.env['res.users'].browse(uid)
employee_id = request.env['hr.employee'].search(
[('user_id', '=', user_id.id)])
attendance = request.env['hr.attendance'].sudo().create({
'employee_id': employee_id.id,
'check_in': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'is_portal': True
})
check_in = datetime.now()
user_tz = pytz.timezone(
request.env.context.get('tz') or request.env.user.tz)
date_today = pytz.utc.localize(check_in).astimezone(user_tz)
formatted_time = datetime.strftime(date_today, '%H:%M:%S')
values = {
'attendance': attendance,
'name': employee_id.name,
'image': employee_id.image_1920,
'check_out': False,
'formatted_time': formatted_time,
}
return request.render(
"web_portal_attendance.check_in_welcome_note_template", values)
@http.route('/check/out', type='http', auth='user', website=True)
def attendance_checkout(self):
"""When clicking the checkout button it will store the checkout time
and worked hours in the check in log """
uid = request.session.uid
user_id = request.env['res.users'].browse(uid)
employee_id = request.env['hr.employee'].search(
[('user_id', '=', user_id.id)])
values = {
'name': employee_id.name,
'image': employee_id.image_1920
}
return request.render("web_portal_attendance.check_out_template",
values)
@http.route('/check/out/last', type='http', auth='user', website=True)
def attendance_final_checkout(self):
"""To display the final checkout template """
uid = request.session.uid
user_id = request.env['res.users'].browse(uid)
employee_id = request.env['hr.employee'].search(
[('user_id', '=', user_id.id)])
check_out = datetime.now()
user_tz = pytz.timezone(
request.env.context.get('tz') or request.env.user.tz)
date_today = pytz.utc.localize(check_out).astimezone(user_tz)
formatted_time = datetime.strftime(date_today, '%H:%M:%S')
attendance = request.env['hr.attendance'].search(
[('employee_id', '=', employee_id.id), ('check_out', '=', False),
('is_portal', '=', True)],
order="check_in desc", limit=1)
# If there is an attendance record with no check-out time,
# update it with the current time
if attendance:
check_out = datetime.now()
check_in = attendance.check_in
worked_hours = check_out - check_in
total_seconds = worked_hours.total_seconds()
hours = int(total_seconds / 3600)
minutes = int((total_seconds % 3600) / 60)
worked_hours_str = "{:02d}:{:02d}".format(hours, minutes)
hours, minutes = map(int, worked_hours_str.split(':'))
worked_hours_float = hours + minutes / 60.0
attendance.write({
'check_out': check_out.strftime('%Y-%m-%d %H:%M:%S'),
'worked_hours': worked_hours_float
})
values = {
'name': employee_id.name,
'image': employee_id.image_1920,
'formatted_time': formatted_time
}
return request.render("web_portal_attendance.portal_last_checkout",
values)
@http.route(['/attendance/list', '/attendance/list/page/<int:page>'],
type='http', website=True)
def attendance_search_sort_view(self, page=1, search=None,
search_in="Check In",
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)])
search_list = {
'Work Hour': {'label': 'Work Hour', 'input': 'Work Hour',
'domain': [('worked_hours', 'ilike', search)]},
'Check In': {'label': 'Check In', 'input': 'Check In',
'domain': [('check_in', 'ilike', search)]},
'Check Out': {'label': 'Check Out', 'input': 'Check Out',
'domain': [('check_out', 'ilike', search)]}, }
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'))]}}
search_domain = search_list[search_in]['domain']
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)] + search_domain + filter_domain)
page_detail = pager(url='/attendance/list',
total=total_attendance,
page=page,
step=10,
url_args={'search': search,
'search_in': search_in,
'filterby': filterby})
attendance_domain = [('is_portal', '=', True),
('employee_id', '=', employee_id.id)]
if search_domain:
attendance_domain += search_domain
if filter_domain:
attendance_domain += filter_domain
attendance = attendance_obj.search(
attendance_domain,
limit=10,
offset=page_detail['offset'])
vals = {
'attendance': attendance,
'page_name': 'attendance',
'pager': page_detail,
'search': search,
'search_in': search_in,
'searchbar_inputs': search_list,
'default_url': '/attendance/list',
'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),
'filterby': filterby,
}
return request.render(
"web_portal_attendance.portal_list_attendance_order", vals)