1
This commit is contained in:
@@ -5,7 +5,7 @@ import logging
|
||||
from geopy.distance import geodesic
|
||||
from datetime import timedelta
|
||||
import json
|
||||
from dateutil.relativedelta import relativedelta
|
||||
import requests
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -22,15 +22,8 @@ class AppletAttendance(Controller):
|
||||
uid = request.session.authenticate(request.env.cr.dbname, login, password)
|
||||
user_id = request.env['res.users'].sudo().browse(uid)
|
||||
employee_id = user_id.with_company(user_id.company_id.id).employee_id
|
||||
data = {
|
||||
'name': employee_id.name,
|
||||
'id': user_id.id,
|
||||
'access': ['打卡'],
|
||||
}
|
||||
return_data = {'data': data,
|
||||
'code': 200,
|
||||
|
||||
'message': ''}
|
||||
data = {'name': employee_id.name, 'id': user_id.id, 'access': ['打卡'],}
|
||||
return_data = {'data': data, 'code': 200, 'message': ''}
|
||||
return json.dumps(return_data)
|
||||
|
||||
@route('/yuthon/att/today', methods=['POST'], type='http', auth='none', cors='*', csrf=False)
|
||||
@@ -58,32 +51,32 @@ class AppletAttendance(Controller):
|
||||
return {'state': 'no', 'state_result': result}
|
||||
user_id = request.env(user=SUPERUSER_ID)["res.users"].search([('id', '=', user_id.id)])
|
||||
employee_id = request.env(user=SUPERUSER_ID)["hr.employee"].search([('name', '=', user_id.name)])
|
||||
address_id = request.env(user=SUPERUSER_ID)["applet.address"].search(
|
||||
[('address_name', '=', employee_id.company_id.name)])
|
||||
attendance_id = request.env(user=SUPERUSER_ID)["hr.attendance"].search(
|
||||
[('employee_id', '=', employee_id.id), ('current_data', '=', current_data)])
|
||||
address_id = request.env(user=SUPERUSER_ID)["applet.address"].search([('address_name', '=', employee_id.company_id.name)])
|
||||
attendance_id = request.env(user=SUPERUSER_ID)["hr.attendance"].search([('employee_id', '=', employee_id.id), ('current_data', '=', current_data)])
|
||||
group_id = attendance_id.shift_name
|
||||
att_longitude = kw['att_longitude'] # 打卡经度
|
||||
att_latitude = kw['att_latitude'] # 打卡纬度
|
||||
self_address = self.get_address_from_coords(att_latitude, att_longitude)
|
||||
if not address_id:
|
||||
return_data = {
|
||||
'data': {'state': 'no', 'state_result': '该打卡地址没有配置'},
|
||||
'check_in': '未签到',
|
||||
'check_out': '未签到',
|
||||
'location': self_address['formatted_address'],
|
||||
'group_id': group_id,
|
||||
'code': '200',
|
||||
'message': 'OK',
|
||||
}
|
||||
return json.dumps(return_data)
|
||||
att_longitude = kw['att_longitude'] # 打卡经度
|
||||
att_latitude = kw['att_latitude'] # 打卡纬度
|
||||
# 从每个人的记录中获取。
|
||||
longitude = kw['att_longitude'] # 要求经度
|
||||
# longitude = address_id.longitude # 要求经度
|
||||
latitude = kw['att_latitude'] # 要求纬度
|
||||
# latitude = address_id.latitude # 要求纬度
|
||||
if not att_longitude or not att_latitude:
|
||||
return_data = {
|
||||
'data': {"message": "经纬度必填", 'state': 'no', 'state_result': '超出范围'},
|
||||
'check_in': '未签到',
|
||||
'check_out': '未签到',
|
||||
'location': self_address['formatted_address'],
|
||||
'group_id': group_id,
|
||||
'code': '200',
|
||||
'message': 'OK',
|
||||
@@ -95,14 +88,14 @@ class AppletAttendance(Controller):
|
||||
'data': {"message": "超出范围,不允许打卡", 'state': 'no', 'state_result': '超出范围'},
|
||||
'check_in': '未签到',
|
||||
'check_out': '未签到',
|
||||
'location': self_address['formatted_address'],
|
||||
'group_id': group_id,
|
||||
'code': '200',
|
||||
'message': 'OK',
|
||||
}
|
||||
return json.dumps(return_data)
|
||||
else:
|
||||
attendance_id = request.env(user=SUPERUSER_ID)["hr.attendance"].search(
|
||||
[('employee_id', '=', employee_id.id), ('current_data', '=', current_data)])
|
||||
attendance_id = request.env(user=SUPERUSER_ID)["hr.attendance"].search([('employee_id', '=', employee_id.id), ('current_data', '=', current_data)])
|
||||
check_in = attendance_id.check_in
|
||||
check_out = attendance_id.check_out
|
||||
attendance_class = attendance_id.shift_name
|
||||
@@ -113,15 +106,10 @@ class AppletAttendance(Controller):
|
||||
end_hour = int(check_out_end)
|
||||
end_minute = int((check_out_end - end_hour) * 60)
|
||||
# 拼接成 datetime 对象
|
||||
start_datetime = datetime.combine(current_data, datetime.min.time()).replace(
|
||||
hour=start_hour, minute=start_minute, second=0, microsecond=0
|
||||
) # 标准上班打卡时间
|
||||
end_datetime = datetime.combine(current_data, datetime.min.time()).replace(
|
||||
hour=end_hour, minute=end_minute, second=0, microsecond=0
|
||||
)
|
||||
start_datetime = datetime.combine(current_data, datetime.min.time()).replace(hour=start_hour, minute=start_minute, second=0, microsecond=0) # 标准上班打卡时间
|
||||
end_datetime = datetime.combine(current_data, datetime.min.time()).replace(hour=end_hour, minute=end_minute, second=0, microsecond=0)
|
||||
if attendance_id.shift_id.template_id.day2 == '次日':
|
||||
end_datetime = end_datetime + timedelta(days=1) # 标准下班打卡时间
|
||||
|
||||
is_early_card = attendance_id.is_early_card
|
||||
is_late_card = attendance_id.is_late_card
|
||||
check_in_status = '未打卡' if not check_in else ('迟到' if is_late_card else '正常')
|
||||
@@ -135,13 +123,10 @@ class AppletAttendance(Controller):
|
||||
state_result = '早退'
|
||||
elif not check_in or not check_out:
|
||||
state_result = '未打卡'
|
||||
|
||||
def get_status_color(status):
|
||||
return 'red' if status in ['迟到', '早退', '未打卡'] else 'green'
|
||||
|
||||
check_in_str = check_in.strftime('%H:%M:%S') if check_in else ' '
|
||||
check_out_str = check_out.strftime('%H:%M:%S') if check_out else ' '
|
||||
# 构建带样式的富文本
|
||||
check_in_html = f'<p style="color:{get_status_color(check_in_status)}">{check_in_str}</p>'
|
||||
check_out_html = f'<p style="color:{get_status_color(check_out_status)}">{check_out_str}</p>'
|
||||
return_data = {
|
||||
@@ -170,6 +155,19 @@ class AppletAttendance(Controller):
|
||||
distance = geodesic(point1, point2).kilometers
|
||||
return distance <= radius_km
|
||||
|
||||
def get_address_from_coords(self, latitude, longitude):
|
||||
api_key = 'BHXBZ-RHJC3-Y7R3G-OOMZ2-N6FBE-NQFIB' # 替换为你的实际密钥
|
||||
url = f'https://apis.map.qq.com/ws/geocoder/v1?location={latitude},{longitude}&key={api_key}'
|
||||
response = requests.get(url)
|
||||
data = response.json()
|
||||
if data['status'] == 0:
|
||||
address = data['result']['address']
|
||||
formatted_address = data['result']['formatted_addresses']['recommend']
|
||||
return {'address': address, 'formatted_address': formatted_address}
|
||||
else:
|
||||
print(f"Error: {data['message']}")
|
||||
return None
|
||||
|
||||
@route('/yuthon/att/record', methods=['POST'], type='http', auth='none', csrf=False)
|
||||
def apple_yuthon_att_record(self, **kw):
|
||||
"""
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
'license': 'LGPL-3',
|
||||
'data': [
|
||||
'data/will_task_time_data.xml',
|
||||
'data/task_code_data.xml',
|
||||
'data/mail_template.xml',
|
||||
'data/tsak_time_data.xml',
|
||||
'security/yuthon_will_task_security.xml',
|
||||
|
||||
Reference in New Issue
Block a user