316 lines
12 KiB
Python
Executable File
316 lines
12 KiB
Python
Executable File
from datetime import timedelta
|
|
from rest_framework.serializers import ModelSerializer
|
|
from rest_framework import serializers
|
|
from apps.hrm.services import HrmService
|
|
from apps.utils.fields import MyFilePathField
|
|
from django.utils import timezone
|
|
|
|
|
|
from apps.utils.serializers import CustomModelSerializer
|
|
from apps.utils.constants import EXCLUDE_FIELDS
|
|
from apps.hrm.models import Certificate, ClockRecord, Employee, NotWorkRemark, Attendance
|
|
from apps.system.serializers import DeptSimpleSerializer, UserSimpleSerializer
|
|
from django.db import transaction
|
|
from django.core.cache import cache
|
|
from apps.utils.tools import check_id_number_strict, get_info_from_id
|
|
from rest_framework.exceptions import ParseError
|
|
from django.conf import settings
|
|
import datetime
|
|
|
|
|
|
class EmployeeShortSerializer(CustomModelSerializer):
|
|
belong_dept_name = serializers.CharField(
|
|
source='belong_dept.name', read_only=True)
|
|
|
|
class Meta:
|
|
model = Employee
|
|
fields = ['id', 'name', 'belong_dept_name',
|
|
'user', 'third_info', 'type']
|
|
|
|
|
|
class EmployeeSimpleSerializer(CustomModelSerializer):
|
|
belong_dept_name = serializers.CharField(
|
|
source='belong_dept.name', read_only=True)
|
|
post_name = serializers.CharField(source='post.name', read_only=True)
|
|
location = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Employee
|
|
fields = ['id', 'type', 'name', 'belong_dept', 'belong_dept_name', 'post',
|
|
'post_name', 'photo', 'third_info', 'number', 'id_number', 'location']
|
|
|
|
def get_location(self, obj):
|
|
key_str = 'ep_{}'.format(obj.id)
|
|
return cache.get(key_str, None)
|
|
|
|
# class EmployeeBaseSerializer(CustomModelSerializer):
|
|
# def save(self, **kwargs):
|
|
# if self.validated_data.get('user', None):
|
|
# user = self.validated_data['user']
|
|
# self.validated_data['name'] = user.name
|
|
# self.validated_data['belong_dept'] = user.belong_dept
|
|
# return super().save(**kwargs)
|
|
|
|
|
|
class EmployeeCreateUpdateSerializer(CustomModelSerializer):
|
|
id_number = serializers.CharField(
|
|
label="身份证号", validators=[check_id_number_strict])
|
|
|
|
class Meta:
|
|
model = Employee
|
|
exclude = EXCLUDE_FIELDS + ['is_atwork', 'last_check_time',
|
|
'not_work_remark',
|
|
'third_info',
|
|
'type', 'phone', 'belong_dept', 'post', 'user']
|
|
extra_kwargs = {
|
|
'number': {'required': True},
|
|
'photo': {'required': True},
|
|
'id_number': {'required': True},
|
|
}
|
|
|
|
@transaction.atomic
|
|
def create(self, validated_data):
|
|
instance = super().create(validated_data)
|
|
if instance.type == 'employee':
|
|
# 如果是内部员工
|
|
HrmService.sync_dahua_employee(ep=instance)
|
|
return instance
|
|
|
|
def update(self, instance, validated_data):
|
|
id_number = validated_data['id_number']
|
|
ret = get_info_from_id(id_number)
|
|
validated_data['gender'] = ret['gender']
|
|
old_photo = instance.photo
|
|
old_job_state = instance.job_state
|
|
old_name = instance.name
|
|
instance = super().update(instance, validated_data)
|
|
if old_photo != instance.photo: # 如果照片有变动,需要更新人脸库
|
|
# 使用的是face_recongition
|
|
face_data, msg = HrmService.get_facedata_from_img_x(
|
|
settings.BASE_DIR + instance.photo)
|
|
in_face_data = instance.face_data
|
|
if face_data:
|
|
if isinstance(in_face_data, dict):
|
|
in_face_data['dlib'] = face_data
|
|
instance.face_data = in_face_data
|
|
instance.save()
|
|
else:
|
|
instance.face_data = {'dlib': face_data}
|
|
instance.save()
|
|
else:
|
|
raise ParseError(msg)
|
|
from apps.hrm.tasks import update_all_facedata_cache
|
|
update_all_facedata_cache.delay()
|
|
if instance.user and instance != old_name:
|
|
instance.user.name = instance.name
|
|
instance.user.save()
|
|
if instance.type == 'remployee': # 如果是相关方
|
|
from apps.rpm.services import sync_to_rep
|
|
sync_to_rep(instance)
|
|
elif instance.type in ['visitor', 'driver']: # 如果是访客或司机
|
|
from apps.vm.services import sync_to_visitor
|
|
sync_to_visitor(instance)
|
|
if instance.job_state in [20, 30] and instance.user: # 如果离职了删除账户
|
|
instance.user.is_deleted = True
|
|
instance.user.save()
|
|
# 同时去除门禁授权
|
|
# 如果是正式员工或相关方且有门禁权限:
|
|
now = timezone.now()
|
|
if instance.type in ['employee', 'remployee']:
|
|
start_time = None
|
|
end_time = None
|
|
# 如果是正式员工,给长时间期限
|
|
if instance.third_info.get('dh_face_card', None) is None and instance.type == 'employee':
|
|
start_time = now
|
|
end_time = now + timedelta(days=7300)
|
|
if instance.job_state in [20, 30] and old_job_state == 10: # 离职或退休
|
|
start_time = now
|
|
end_time = now + timedelta(hours=8)
|
|
# 正式员工重新在职
|
|
elif instance.job_state == 10 and old_job_state in [20, 30] and instance.type == 'employee':
|
|
start_time = now
|
|
end_time = now + timedelta(days=7300)
|
|
HrmService.sync_dahua_employee(ep=instance, old_photo=old_photo,
|
|
start_time=start_time, end_time=end_time)
|
|
return instance
|
|
|
|
|
|
class EmployeeImproveSerializer(CustomModelSerializer):
|
|
photo_f = MyFilePathField(source='photo', read_only=True)
|
|
signature_f = MyFilePathField(source='signature', read_only=True)
|
|
|
|
class Meta:
|
|
model = Employee
|
|
fields = ['photo', 'id_number', 'email', 'gender',
|
|
'signature', 'photo_f', 'signature_f', 'phone']
|
|
extra_kwargs = {
|
|
'number': {'required': True},
|
|
'photo': {'required': True},
|
|
'id_number': {'required': True},
|
|
}
|
|
|
|
def update(self, instance, validated_data):
|
|
id_number = validated_data['id_number']
|
|
ret = get_info_from_id(id_number)
|
|
validated_data['gender'] = ret['gender']
|
|
return super().update(instance, validated_data)
|
|
|
|
|
|
class ChannelAuthoritySerializer(serializers.Serializer):
|
|
# pks = serializers.ListField(child=serializers.CharField(max_length=20), label="员工ID列表")
|
|
start_time = serializers.DateTimeField(label="开始时间")
|
|
end_time = serializers.DateTimeField(label="结束时间")
|
|
|
|
|
|
class EmployeeSerializer(CustomModelSerializer):
|
|
belong_dept_ = DeptSimpleSerializer(source='belong_dept', read_only=True)
|
|
user_ = UserSimpleSerializer(source='user', read_only=True)
|
|
belong_dept_name = serializers.CharField(
|
|
source='belong_dept.name', read_only=True)
|
|
post_name = serializers.CharField(source='post.name', read_only=True)
|
|
blt_ = serializers.SerializerMethodField()
|
|
photo_f = MyFilePathField(source='photo', read_only=True)
|
|
signature_f = MyFilePathField(source='signature', read_only=True)
|
|
|
|
class Meta:
|
|
model = Employee
|
|
fields = '__all__'
|
|
read_only_fields = ['is_atwork', 'last_check_time', 'not_work_remark']
|
|
|
|
def get_blt_(self, obj):
|
|
if hasattr(obj, 'blt'):
|
|
from apps.third.serializers import TDeviceSimpleSerializer
|
|
return TDeviceSimpleSerializer(instance=obj.blt).data
|
|
# if hasattr(obj, 'tdevice'):
|
|
# from apps.third.serializers import TDeviceSimpleSerializer
|
|
# return TDeviceSimpleSerializer(instance=obj.tdevice).data
|
|
return
|
|
|
|
|
|
class EmployeeDetailSerializer(EmployeeSerializer):
|
|
# door_range = serializers.SerializerMethodField()
|
|
location = serializers.SerializerMethodField()
|
|
|
|
# def get_door_range(self, obj):
|
|
# third_info = obj.third_info
|
|
# dh_face_card = third_info.get('dh_face_card', None)
|
|
# if dh_face_card:
|
|
# _, res = dhClient.request(**dhapis['card_detail'], params={'cardNumber': dh_face_card})
|
|
# return [res['startDate'], res['endDate']]
|
|
|
|
def get_location(self, obj):
|
|
key_str = 'ep_{}'.format(obj.id)
|
|
return cache.get(key_str, None)
|
|
|
|
|
|
class EmployeeNotWorkRemarkSerializer(ModelSerializer):
|
|
class Meta:
|
|
model = Employee
|
|
fields = ['not_work_remark']
|
|
|
|
|
|
class ClockRecordListSerializer(serializers.ModelSerializer):
|
|
employee_ = EmployeeSimpleSerializer(source='employee', read_only=True)
|
|
|
|
class Meta:
|
|
model = ClockRecord
|
|
fields = '__all__'
|
|
|
|
|
|
class ClockRecordCreateSerializer(serializers.ModelSerializer):
|
|
clock_time = serializers.DateTimeField(label='打卡时间', required=True)
|
|
|
|
class Meta:
|
|
model = ClockRecord
|
|
fields = ['id', 'type', 'employee', 'clock_time']
|
|
|
|
def validate(self, attrs):
|
|
attrs['trigger'] = 'manual'
|
|
return attrs
|
|
|
|
|
|
class ClockRecordSimpleSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = ClockRecord
|
|
fields = ['id', 'type', 'exception_type', 'detail']
|
|
|
|
|
|
class NotWorkRemarkListSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = NotWorkRemark
|
|
fields = '__all__'
|
|
|
|
|
|
class CertificateCreateUpdateSerializer(CustomModelSerializer):
|
|
file_f = MyFilePathField(source='file', read_only=True)
|
|
|
|
class Meta:
|
|
model = Certificate
|
|
exclude = EXCLUDE_FIELDS
|
|
|
|
|
|
class CertificateSerializer(CustomModelSerializer):
|
|
employee_name = serializers.CharField(
|
|
source='employee.name', read_only=True)
|
|
file_f = MyFilePathField(source='file', read_only=True)
|
|
|
|
class Meta:
|
|
model = Certificate
|
|
fields = '__all__'
|
|
|
|
|
|
class CorrectSerializer(serializers.Serializer):
|
|
start_time = serializers.DateTimeField()
|
|
end_time = serializers.DateTimeField()
|
|
|
|
|
|
class AttendanceSerializer(CustomModelSerializer):
|
|
user_name = serializers.CharField(
|
|
source='user.name', read_only=True)
|
|
belong_dept_name = serializers.CharField(
|
|
source='user.belong_dept.name', read_only=True)
|
|
shift_name = serializers.CharField(source='shift.name', read_only=True)
|
|
post_name = serializers.CharField(
|
|
source='user.post.name', read_only=True)
|
|
team_name = serializers.CharField(source='team.name', read_only=True)
|
|
work_time_start = serializers.DateTimeField(read_only=True)
|
|
work_time_end = serializers.DateTimeField(read_only=True)
|
|
|
|
class Meta:
|
|
model = Attendance
|
|
fields = '__all__'
|
|
extra_kwargs = {'team': {'required': True}, 'post': {'required': True}}
|
|
|
|
def create(self, validated_data):
|
|
user = validated_data['user']
|
|
shift = validated_data['shift']
|
|
work_date = validated_data['work_date']
|
|
att = Attendance.objects.filter(
|
|
user=user, work_date=work_date, shift=shift).first()
|
|
if att:
|
|
att.note = validated_data.get('note', '')
|
|
att.state = validated_data['state']
|
|
att.update_by = self.context['request'].user
|
|
att.save()
|
|
return att
|
|
else:
|
|
start_time_o = shift.start_time_o
|
|
end_time_o = shift.end_time_o
|
|
if end_time_o >= start_time_o:
|
|
validated_data['work_time_start'] = datetime.datetime.combine(
|
|
work_date, start_time_o)
|
|
validated_data['work_time_end'] = datetime.datetime.combine(
|
|
work_date, end_time_o)
|
|
else:
|
|
validated_data['work_time_start'] = datetime.datetime.combine(
|
|
work_date, start_time_o) - datetime.timedelta(days=1)
|
|
validated_data['work_time_end'] = datetime.datetime.combine(
|
|
work_date, end_time_o)
|
|
return super().create(validated_data)
|
|
|
|
def update(self, instance, validated_data):
|
|
new_data = {}
|
|
new_data['note'] = validated_data.get('note', '')
|
|
new_data['state'] = validated_data['state']
|
|
return super().update(instance, validated_data)
|