159 lines
8.3 KiB
Python
159 lines
8.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
import binascii, json
|
|
from odoo import fields, http, SUPERUSER_ID, _
|
|
from odoo.exceptions import AccessError, MissingError, ValidationError
|
|
from odoo.http import request
|
|
from ....addons.portal.controllers import portal
|
|
from datetime import datetime, date, time, timedelta
|
|
from dateutil.relativedelta import relativedelta
|
|
|
|
class CustomerPortal(portal.CustomerPortal):
|
|
|
|
@http.route(['/my/attendance/month/detail/<int:attendance_id>'], type='http', auth="public", website=True)
|
|
def portal_attendance_month_detail_page(self, attendance_id, report_type=None, access_token=None, message=False, download=False, **kw):
|
|
# 后期有需求的话可以进行加密处理数据,包括请求地址进行加密处理数据
|
|
try:
|
|
attendance_sudo = self._document_check_access('hr.attendance.month.detail', attendance_id, access_token=access_token)
|
|
except (AccessError, MissingError):
|
|
return request.redirect('/my')
|
|
|
|
values = {
|
|
'attendance_month': attendance_sudo,
|
|
'message': message,
|
|
'report_type': 'html',
|
|
'res_company': attendance_sudo.employee_id.user_id.company_id,
|
|
}
|
|
return request.render('yuthon_hr_attendance.attendance_month_portal_template', values)
|
|
|
|
@http.route(['/my/attendance/month/detail/<int:attendance_id>/accept'], type='json', auth="public", website=True)
|
|
def portal_attendance_month_detail_quote_accept(self, attendance_id, access_token=None, name=None, signature=None):
|
|
# 后期有需求的话可以进行加密处理数据,包括请求地址进行加密处理数据
|
|
access_token = access_token or request.httprequest.args.get('access_token')
|
|
try:
|
|
attendance_sudo = self._document_check_access('hr.attendance.month.detail', attendance_id, access_token=access_token)
|
|
except (AccessError, MissingError):
|
|
return {'error': _('无效的信息')}
|
|
|
|
try:
|
|
attendance_sudo.write({
|
|
'signed_by': name,
|
|
'signed_on': fields.Datetime.now(),
|
|
'signature': signature,
|
|
'state': "confirmed"
|
|
})
|
|
request.env.cr.commit()
|
|
except (TypeError, binascii.Error) as e:
|
|
return {'error': _('无效的签名.')}
|
|
|
|
query_string = '&message=sign_ok'
|
|
return {
|
|
'force_refresh': True,
|
|
'redirect_url': attendance_sudo.get_portal_url(query_string=query_string),
|
|
}
|
|
|
|
@http.route('/phone/vacation/self', type='http', auth="none", csrf=False, cors='*')
|
|
def phone_vacation_self(self, **kw):
|
|
users_id = int(kw.get('users_id'))
|
|
user = request.env['res.users'].sudo().browse(int(users_id))
|
|
employee_id = user.with_company(user.company_id.id).employee_id.id
|
|
employee = request.env['hr.employee'].sudo().browse(employee_id)
|
|
records = request.env['yuthon.vacation.reports'].sudo().search([('employee_id.id', '=', employee_id)])
|
|
data = {}
|
|
for record in records:
|
|
year = record.vacation_date.year
|
|
key = f'{year}年'
|
|
if key not in data:
|
|
data[key] = []
|
|
vacation_state = '已确认' if record.vacation_state == 'confirmed' else '待确认'
|
|
|
|
# 检查是否有未办结的人力流程
|
|
has_pending, pending_tip = record._has_pending_hr_workflow(employee_id, record.vacation_date)
|
|
can_confirm = record.vacation_state != 'confirmed' and not has_pending
|
|
|
|
data[key].append({
|
|
'id': record.id,
|
|
'state': vacation_state,
|
|
'month': record.vacation_date.month,
|
|
# 'can_confirm': can_confirm,
|
|
# 'pending_tip': pending_tip if has_pending else '',
|
|
})
|
|
return json.dumps({'data': data, 'code': 200, 'message': ''})
|
|
|
|
@http.route('/phone/vacation/self/detail', type='http', auth="none", csrf=False, cors='*')
|
|
def phone_vacation_self_detail(self, **kw):
|
|
record = request.env['yuthon.vacation.reports'].sudo().search([('id', '=', kw.get('id'))])
|
|
|
|
def format_vacation_value(value, unit, multiply=1):
|
|
num = float(value or 0) * multiply
|
|
if num == 0:
|
|
return "0"
|
|
if unit == "小时":
|
|
return f"{round(num, 1)}{unit}"
|
|
return f"{num}{unit}"
|
|
|
|
# 检查是否有未办结的人力流程
|
|
employee_id = record.employee_id.id
|
|
has_pending, pending_tip = record._has_pending_hr_workflow(employee_id, record.vacation_date)
|
|
can_confirm = record.vacation_state != 'confirmed' and not has_pending
|
|
|
|
data = {
|
|
'state': '已确认' if record.vacation_state == 'confirmed' else '待确认',
|
|
# 'can_confirm': can_confirm,
|
|
# 'pending_tip': pending_tip if has_pending else '',
|
|
'日期': record.display_date,
|
|
'应到': format_vacation_value(record.should_attendance, '天'),
|
|
'实到': format_vacation_value(record.actual_attendance, '天'),
|
|
'外派': format_vacation_value(record.expatriation, '天'),
|
|
'迟到': format_vacation_value(record.is_late_card, '次'),
|
|
'早退': format_vacation_value(record.is_early_card, '次'),
|
|
'缺卡': format_vacation_value(record.is_no_card, '次'),
|
|
'旷工': format_vacation_value(record.is_work, '次'),
|
|
'异常': format_vacation_value(record.is_abnormal, '次'),
|
|
'年假': format_vacation_value(record.done_leave, '天'),
|
|
'加班时': format_vacation_value(record.done_working_overtime, '小时'),
|
|
'补休': format_vacation_value(record.cop_leave, '小时', 8),
|
|
'调休': format_vacation_value(record.compensatory_leave, '天'),
|
|
'事假': format_vacation_value(record.leave_of_absence, '天'),
|
|
'加班时(法定假)': format_vacation_value(record.statutory_leave, '小时'),
|
|
'育儿假': format_vacation_value(record.parental_leave, '天'),
|
|
'值班调休': format_vacation_value(record.duty_off_leave, '天'),
|
|
'婚假': format_vacation_value(record.marriage_leave, '天'),
|
|
'产假': format_vacation_value(record.maternity_leave, '天'),
|
|
'陪产假': format_vacation_value(record.paternity_leave, '天'),
|
|
'计生假': format_vacation_value(record.family_planning_leave, '天'),
|
|
'丧假': format_vacation_value(record.bereavement_leave, '天'),
|
|
'探亲假': format_vacation_value(record.home_visit_leave, '天'),
|
|
'家长会假': format_vacation_value(record.parents_meeting_leave, '天'),
|
|
'病假(普通)': format_vacation_value(record.general_sick_leave, '天'),
|
|
'病假(住院期)': format_vacation_value(record.hospital_sick_leave, '天'),
|
|
'病假(出院恢复期)': format_vacation_value(record.recovery_sick_leave, '天'),
|
|
'考试假': format_vacation_value(record.exam_leave, '天'),
|
|
}
|
|
return json.dumps({'data': data, 'code': 200, 'message': ''})
|
|
|
|
@http.route('/phone/vacation/self/status', type='http', auth="none", csrf=False, cors='*')
|
|
def phone_vacation_self_status(self, **kw):
|
|
record_id = request.env['yuthon.vacation.reports'].sudo().search([('id', '=', kw.get('id'))])
|
|
if not record_id:
|
|
return json.dumps({'code': 400, 'message': '记录不存在'})
|
|
|
|
# 检查是否有未办结的人力流程
|
|
has_pending, pending_tip = record_id._has_pending_hr_workflow(
|
|
record_id.employee_id.id, record_id.vacation_date)
|
|
if has_pending:
|
|
return json.dumps({'code': 403, 'message': pending_tip})
|
|
|
|
record_id.write({'vacation_state': 'confirmed'})
|
|
return json.dumps({'code': 200, 'message': 'OK'})
|
|
|
|
@http.route('/phone/attendance_summary/btn_list', type='http', auth="none", csrf=False, cors='*')
|
|
def phone_attendance_summary_btn_list(self, **kw):
|
|
approvals = request.env['soong.workflow'].sudo().search([('name', 'in', ['补卡', '请假', '外出'])])
|
|
menu_id = request.env.ref('soong_workflow.menu_workflow_approval_request_new').sudo()
|
|
data = {
|
|
'records': {a.name: a.id for a in approvals},
|
|
'menu_id': menu_id.id,
|
|
'action_id': menu_id.action.id
|
|
}
|
|
return json.dumps({'code': 200, 'message': 'OK', 'data': data})
|