feat: 添加离职记录表

This commit is contained in:
caoqianming 2025-11-06 09:48:36 +08:00
parent b9d72f9619
commit 6e8fdddac0
6 changed files with 99 additions and 8 deletions

View File

@ -0,0 +1,47 @@
# Generated by Django 3.2.12 on 2025-11-06 01:42
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('wf', '0004_workflow_view_path2'),
('hrm', '0019_certificate_state'),
]
operations = [
migrations.AddField(
model_name='employee',
name='end_date',
field=models.DateField(blank=True, null=True, verbose_name='离职日期'),
),
migrations.AddField(
model_name='employee',
name='start_date',
field=models.DateField(blank=True, null=True, verbose_name='入职日期'),
),
migrations.CreateModel(
name='Resignation',
fields=[
('id', models.CharField(editable=False, help_text='主键ID', max_length=20, primary_key=True, serialize=False, verbose_name='主键ID')),
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
('end_date', models.DateField(verbose_name='离职日期')),
('reason', models.TextField(verbose_name='离职原因')),
('handle_date', models.DateField(blank=True, null=True, verbose_name='办理离职交接日期')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='resignation_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('employee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hrm.employee', verbose_name='员工')),
('ticket', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='wf.ticket', verbose_name='关联工单')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='resignation_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
],
options={
'abstract': False,
},
),
]

View File

@ -55,6 +55,8 @@ class Employee(CommonBModel):
on_delete=models.SET_NULL, null=True, blank=True) on_delete=models.SET_NULL, null=True, blank=True)
face_data = models.JSONField( face_data = models.JSONField(
'人脸数据', null=True, blank=True) # 存储的是字典(模型名:人脸数据) '人脸数据', null=True, blank=True) # 存储的是字典(模型名:人脸数据)
start_date = models.DateField('入职日期', null=True, blank=True)
end_date = models.DateField('离职日期', null=True, blank=True)
class Meta: class Meta:
verbose_name = '员工补充信息' verbose_name = '员工补充信息'
@ -190,3 +192,14 @@ class Certificate(CommonAModel):
self.state = new_state self.state = new_state
self.save(update_fields=['state']) self.save(update_fields=['state'])
return new_state return new_state
class Resignation(CommonADModel):
"""
TN:离职记录
"""
employee = models.ForeignKey(Employee, verbose_name='员工', on_delete=models.CASCADE)
end_date = models.DateField('离职日期')
reason = models.TextField('离职原因')
handle_date = models.DateField('办理离职交接日期', null=True, blank=True)
ticket = models.ForeignKey('wf.ticket', verbose_name='关联工单', on_delete=models.SET_NULL, null=True, blank=True)

View File

@ -8,7 +8,8 @@ from django.utils import timezone
from apps.utils.serializers import CustomModelSerializer from apps.utils.serializers import CustomModelSerializer
from apps.utils.constants import EXCLUDE_FIELDS from apps.utils.constants import EXCLUDE_FIELDS
from apps.hrm.models import Certificate, ClockRecord, Employee, NotWorkRemark, Attendance from apps.hrm.models import (Certificate, ClockRecord, Employee,
NotWorkRemark, Attendance, Resignation)
from apps.system.serializers import DeptSimpleSerializer, UserSimpleSerializer from apps.system.serializers import DeptSimpleSerializer, UserSimpleSerializer
from django.db import transaction from django.db import transaction
from django.core.cache import cache from django.core.cache import cache
@ -313,3 +314,11 @@ class AttendanceSerializer(CustomModelSerializer):
new_data['note'] = validated_data.get('note', '') new_data['note'] = validated_data.get('note', '')
new_data['state'] = validated_data['state'] new_data['state'] = validated_data['state']
return super().update(instance, validated_data) return super().update(instance, validated_data)
class ResignationSerializer(CustomModelSerializer):
belong_dept_name = serializers.CharField(source="employee.belong_dept.name", read_only=True)
post_name = serializers.CharField(source="employee.post.name", read_only=True)
class Meta:
model = Resignation
fields = '__all__'

View File

@ -8,14 +8,16 @@ from dateutil import tz
from django.conf import settings from django.conf import settings
from django.utils import timezone from django.utils import timezone
from django.core.cache import cache from django.core.cache import cache
from rest_framework.exceptions import ParseError
from apps.system.models import User from apps.system.models import User
from apps.hrm.models import ClockRecord, Employee from apps.hrm.models import ClockRecord, Employee, Resignation
from apps.third.dahua import dhClient from apps.third.dahua import dhClient
from apps.third.models import TDevice from apps.third.models import TDevice
from apps.third.tapis import dhapis from apps.third.tapis import dhapis
from apps.utils.tools import rannum, ranstr from apps.utils.tools import rannum, ranstr
import numpy as np import numpy as np
from apps.wf.models import Ticket, Transition
myLogger = logging.getLogger('log') myLogger = logging.getLogger('log')
@ -493,3 +495,12 @@ class HrmService:
dhClient.request( dhClient.request(
**dhapis['card_door_authority_delete'], json=rdict) **dhapis['card_door_authority_delete'], json=rdict)
print(f'{ep.name}-办公室打卡权限已删除') print(f'{ep.name}-办公室打卡权限已删除')
def bind_resignation(ticket: Ticket, transition: Transition, new_ticket_data: dict):
ins = Resignation.objects.get(id=new_ticket_data['rpj'])
if ins.ticket and ins.ticket.id != ticket.id:
raise ParseError('重复创建工单')
ticket.create_by = ins.create_by
ticket.save()

View File

@ -1,4 +1,5 @@
from apps.hrm.views import CertificateViewSet, ClockRecordViewSet, EmployeeViewSet, NotWorkRemarkViewSet, AttendanceViewSet from apps.hrm.views import (CertificateViewSet, ClockRecordViewSet, EmployeeViewSet, NotWorkRemarkViewSet,
AttendanceViewSet, ResignationViewSet)
from django.urls import path, include from django.urls import path, include
from rest_framework.routers import DefaultRouter from rest_framework.routers import DefaultRouter
@ -12,6 +13,7 @@ router.register('not_work_remark', NotWorkRemarkViewSet,
basename='not_work_reamrk') basename='not_work_reamrk')
router.register('certificate', CertificateViewSet, basename='certificate') router.register('certificate', CertificateViewSet, basename='certificate')
router.register('attendance', AttendanceViewSet, basename='attendance') router.register('attendance', AttendanceViewSet, basename='attendance')
router.register('resignation', ResignationViewSet, basename='resignation')
urlpatterns = [ urlpatterns = [
path(API_BASE_URL, include(router.urls)), path(API_BASE_URL, include(router.urls)),
] ]

View File

@ -12,21 +12,22 @@ from rest_framework.response import Response
from apps.hrm.errors import NO_NEED_LEVEL_REMARK from apps.hrm.errors import NO_NEED_LEVEL_REMARK
from apps.hrm.filters import (CertificateFilterSet, ClockRecordFilterSet, EmployeeFilterSet, from apps.hrm.filters import (CertificateFilterSet, ClockRecordFilterSet, EmployeeFilterSet,
NotWorkRemarkFilterSet) NotWorkRemarkFilterSet)
from apps.hrm.models import Certificate, ClockRecord, Employee, NotWorkRemark, Attendance from apps.hrm.models import Certificate, ClockRecord, Employee, NotWorkRemark, Attendance, Resignation
from apps.hrm.serializers import (CertificateCreateUpdateSerializer, CertificateSerializer, ChannelAuthoritySerializer, from apps.hrm.serializers import (CertificateCreateUpdateSerializer, CertificateSerializer, ChannelAuthoritySerializer,
ClockRecordListSerializer, ClockRecordListSerializer,
EmployeeCreateUpdateSerializer, EmployeeDetailSerializer, EmployeeImproveSerializer, EmployeeCreateUpdateSerializer, EmployeeDetailSerializer, EmployeeImproveSerializer,
EmployeeNotWorkRemarkSerializer, EmployeeNotWorkRemarkSerializer,
EmployeeSerializer, EmployeeSerializer,
ClockRecordSimpleSerializer, ClockRecordCreateSerializer, ClockRecordSimpleSerializer, ClockRecordCreateSerializer,
NotWorkRemarkListSerializer, CorrectSerializer, AttendanceSerializer) NotWorkRemarkListSerializer, CorrectSerializer, AttendanceSerializer,
ResignationSerializer)
from apps.hrm.services import HrmService from apps.hrm.services import HrmService
from apps.third.dahua import dhClient from apps.third.dahua import dhClient
from apps.third.tapis import dhapis from apps.third.tapis import dhapis
from apps.utils.export import export_excel from apps.utils.export import export_excel
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
from apps.utils.mixins import BulkCreateModelMixin, BulkDestroyModelMixin from apps.utils.mixins import BulkCreateModelMixin, BulkDestroyModelMixin, CustomListModelMixin
epTypeOptions = {'employee': '正式员工', 'remployee': '相关方', epTypeOptions = {'employee': '正式员工', 'remployee': '相关方',
'visitor': '访客', 'driver': '货车司机'} 'visitor': '访客', 'driver': '货车司机'}
@ -390,3 +391,11 @@ class CertificateViewSet(CustomModelViewSet):
def perform_update(self, serializer): def perform_update(self, serializer):
ins: Certificate = serializer.save() ins: Certificate = serializer.save()
ins.get_state(need_update=True) ins.get_state(need_update=True)
class ResignationViewSet(CustomListModelMixin, BulkCreateModelMixin, CustomGenericViewSet):
perms_map = {"get": "*", "post": "resignation.create"}
select_related_fields = ['employee', 'employee__belong_dept', 'employee__post']
queryset = Resignation.objects.all()
serializer_class = ResignationSerializer
search_fields = ["employee__name"]