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 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_e, get_info_from_id from rest_framework.exceptions import ParseError from django.conf import settings 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_e]) 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_data, msg = HrmService.get_facedata_from_img(settings.BASE_DIR + instance.photo) if face_data: instance.facenet512_data = face_data instance.save() else: raise ParseError(msg) from apps.hrm.tasks import update_global_face_pd update_global_face_pd.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 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()