2024-06-13 00:12:17 +08:00
|
|
|
|
import datetime
|
|
|
|
|
|
2024-05-15 10:02:51 +08:00
|
|
|
|
from django.db import models
|
|
|
|
|
|
2024-06-18 21:54:54 +08:00
|
|
|
|
from application.org_mgnt.models import PrimaryDepartment, SecondaryDepartment
|
|
|
|
|
|
2024-05-15 18:41:23 +08:00
|
|
|
|
|
2024-06-16 14:07:40 +08:00
|
|
|
|
# 岗位表
|
2024-05-15 18:41:23 +08:00
|
|
|
|
class Position(models.Model):
|
2024-06-16 14:07:40 +08:00
|
|
|
|
position_id = models.AutoField(primary_key=True, verbose_name='岗位ID')
|
2024-06-14 16:47:56 +08:00
|
|
|
|
position_name = models.CharField(max_length=255, verbose_name='岗位名称')
|
|
|
|
|
position_description = models.TextField(verbose_name='岗位描述')
|
2024-05-15 18:41:23 +08:00
|
|
|
|
|
|
|
|
|
class Meta:
|
2024-06-14 16:47:56 +08:00
|
|
|
|
verbose_name = '岗位表'
|
|
|
|
|
verbose_name_plural = '岗位表'
|
2024-05-15 18:41:23 +08:00
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return self.position_name
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 职级表
|
|
|
|
|
class Rank(models.Model):
|
2024-05-27 23:39:32 +08:00
|
|
|
|
rank_id = models.AutoField(primary_key=True, verbose_name='职级ID')
|
2024-05-15 18:41:23 +08:00
|
|
|
|
rank_name = models.CharField(max_length=255, verbose_name='职级名称')
|
|
|
|
|
rank_description = models.TextField(verbose_name='职级描述')
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
verbose_name = '职级表'
|
|
|
|
|
verbose_name_plural = '职级表'
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return self.rank_name
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 人员基本信息表
|
|
|
|
|
class EmployeeInformation(models.Model):
|
2024-06-16 20:17:45 +08:00
|
|
|
|
GENDER_CHOICES = [
|
2024-05-15 18:41:23 +08:00
|
|
|
|
('男', '男'),
|
|
|
|
|
('女', '女'),
|
|
|
|
|
('其他', '其他')
|
2024-06-16 20:17:45 +08:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
BLOOD_TYPE_CHOICES = [
|
2024-05-15 18:41:23 +08:00
|
|
|
|
('A', 'A'),
|
|
|
|
|
('B', 'B'),
|
|
|
|
|
('AB', 'AB'),
|
|
|
|
|
('O', 'O'),
|
|
|
|
|
('其他', '其他')
|
2024-06-16 20:17:45 +08:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
MARITAL_STATUS_CHOICES = [
|
2024-05-15 18:41:23 +08:00
|
|
|
|
('未婚', '未婚'),
|
|
|
|
|
('已婚未育', '已婚未育'),
|
|
|
|
|
('已婚已育', '已婚已育'),
|
|
|
|
|
('离婚', '离婚'),
|
|
|
|
|
('其他', '其他')
|
2024-06-16 20:17:45 +08:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
POLITICAL_AFFILIATION_CHOICES = [
|
2024-05-15 18:41:23 +08:00
|
|
|
|
('共产党员', '共产党员'),
|
|
|
|
|
('共青团员', '共青团员'),
|
|
|
|
|
('群众', '群众'),
|
2024-06-13 23:40:57 +08:00
|
|
|
|
('民主党派', '民主党派'),
|
2024-05-15 18:41:23 +08:00
|
|
|
|
('其他', '其他')
|
2024-06-16 20:17:45 +08:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
EMPLOYMENT_TYPE_CHOICES = [
|
2024-05-15 18:41:23 +08:00
|
|
|
|
('全职', '全职'),
|
|
|
|
|
('兼职', '兼职'),
|
|
|
|
|
('实习', '实习')
|
2024-06-16 20:17:45 +08:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
STATUS_CHOICES = [
|
2024-05-15 18:41:23 +08:00
|
|
|
|
('在职', '在职'),
|
|
|
|
|
('离职', '离职')
|
2024-06-16 20:17:45 +08:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
EDUCATION_CHOICES = [
|
|
|
|
|
('高中', '高中'),
|
|
|
|
|
('大专', '大专'),
|
|
|
|
|
('本科', '本科'),
|
|
|
|
|
('硕士研究生', '硕士研究生'),
|
|
|
|
|
('博士研究生', '博士研究生'),
|
|
|
|
|
('其他', '其他')
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
RESIGNATION_TYPE_CHOICES = [
|
|
|
|
|
('合同期满', '合同期满'),
|
|
|
|
|
('主动辞职', '主动辞职'),
|
|
|
|
|
('无条件辞职', '无条件辞职'),
|
|
|
|
|
('试用未通过', '试用未通过'),
|
|
|
|
|
('辞退', '辞退'),
|
|
|
|
|
('其他', '其他')
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
employee_id = models.AutoField(primary_key=True)
|
|
|
|
|
name = models.CharField(max_length=255, verbose_name='姓名')
|
2024-06-19 05:32:15 +08:00
|
|
|
|
id_number = models.CharField(max_length=255, verbose_name='身份证号', unique=True, blank=True, null=True)
|
|
|
|
|
gender = models.CharField(max_length=10, choices=GENDER_CHOICES, verbose_name='性别', blank=True, null=True)
|
|
|
|
|
birthday = models.DateField(verbose_name='生日', blank=True, null=True)
|
|
|
|
|
age = models.IntegerField(verbose_name='年龄', blank=True, null=True)
|
|
|
|
|
height = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='身高(cm)', blank=True, null=True)
|
|
|
|
|
weight = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='体重(kg)', blank=True, null=True)
|
|
|
|
|
blood_type = models.CharField(max_length=3, choices=BLOOD_TYPE_CHOICES, verbose_name='血型', blank=True, null=True)
|
|
|
|
|
ethnicity = models.CharField(max_length=255, verbose_name='民族', blank=True, null=True)
|
|
|
|
|
domicile = models.CharField(max_length=255, verbose_name='户籍地', blank=True, null=True)
|
|
|
|
|
marital_status = models.CharField(max_length=50, choices=MARITAL_STATUS_CHOICES, verbose_name='婚姻状态', blank=True, null=True)
|
|
|
|
|
political_affiliation = models.CharField(max_length=50, choices=POLITICAL_AFFILIATION_CHOICES, verbose_name='政治面貌', blank=True, null=True)
|
|
|
|
|
entry_date = models.DateField(verbose_name='入职日期', blank=True, null=True)
|
|
|
|
|
regularization_date = models.DateField(verbose_name='转正日期', blank=True, null=True)
|
|
|
|
|
employment_type = models.CharField(max_length=50, choices=EMPLOYMENT_TYPE_CHOICES, verbose_name='用工性质', blank=True, null=True)
|
|
|
|
|
status = models.CharField(max_length=50, choices=STATUS_CHOICES, verbose_name='状态', blank=True, null=True)
|
|
|
|
|
primary_department = models.CharField(max_length=255, verbose_name='一级部门', blank=True, null=True)
|
|
|
|
|
secondary_department = models.CharField(max_length=255, verbose_name='二级部门', blank=True, null=True)
|
|
|
|
|
position = models.CharField(max_length=255, verbose_name='岗位')
|
|
|
|
|
rank = models.CharField(max_length=255, verbose_name='职级')
|
|
|
|
|
contract_end_date = models.DateField(verbose_name='当前合同到期日期', blank=True, null=True)
|
|
|
|
|
mobile_number = models.CharField(max_length=255, verbose_name='手机号', blank=True, null=True)
|
|
|
|
|
email = models.EmailField(verbose_name='邮箱', blank=True, null=True)
|
|
|
|
|
mailing_address = models.CharField(max_length=255, verbose_name='通信地址', blank=True, null=True)
|
|
|
|
|
emergency_contact = models.CharField(max_length=255, verbose_name='紧急联系人', blank=True, null=True)
|
|
|
|
|
relation_with_contact = models.CharField(max_length=255, verbose_name='与本人关系', blank=True, null=True)
|
|
|
|
|
emergency_contact_phone = models.CharField(max_length=255, verbose_name='紧急联系人电话', blank=True, null=True)
|
|
|
|
|
education = models.CharField(max_length=50, choices=EDUCATION_CHOICES, verbose_name='学历', blank=True, null=True)
|
|
|
|
|
undergraduate_school = models.CharField(max_length=255, verbose_name='本科毕业院校', blank=True, null=True)
|
|
|
|
|
graduate_school = models.CharField(max_length=255, verbose_name='研究生毕业院校', blank=True, null=True)
|
|
|
|
|
major = models.CharField(max_length=255, verbose_name='专业', blank=True, null=True)
|
|
|
|
|
technical_title = models.CharField(max_length=255, verbose_name='技术职称', blank=True, null=True)
|
|
|
|
|
base_salary = models.TextField(verbose_name='基础工资(元)', blank=True, null=True)
|
|
|
|
|
salary_account_number = models.CharField(max_length=255, verbose_name='工资卡号', blank=True, null=True)
|
|
|
|
|
bank_of_salary_account = models.CharField(max_length=255, verbose_name='工资卡开户行', blank=True, null=True)
|
|
|
|
|
resignation_type = models.CharField(max_length=50, choices=RESIGNATION_TYPE_CHOICES, verbose_name='离职类型', blank=True, null=True)
|
|
|
|
|
resignation_reason = models.TextField(verbose_name='离职原因', blank=True, null=True)
|
|
|
|
|
resignation_date = models.DateField(verbose_name='离职日期', blank=True, null=True)
|
2024-05-15 18:41:23 +08:00
|
|
|
|
|
2024-06-18 21:54:54 +08:00
|
|
|
|
def save(self, *args, **kwargs):
|
|
|
|
|
primary_department_name = PrimaryDepartment.objects.filter(department_name=self.primary_department).first()
|
|
|
|
|
secondary_department = SecondaryDepartment.objects.filter(secondary_department_name=self.secondary_department).first()
|
|
|
|
|
position = Position.objects.filter(position_name=self.position).first()
|
|
|
|
|
rank = Rank.objects.filter(rank_name=self.rank).first()
|
|
|
|
|
|
|
|
|
|
if not primary_department_name:
|
|
|
|
|
raise ValueError("一级部门不存在")
|
|
|
|
|
|
|
|
|
|
if not secondary_department:
|
|
|
|
|
raise ValueError("二级部门不存在")
|
|
|
|
|
|
|
|
|
|
if not position:
|
|
|
|
|
raise ValueError("岗位不存在")
|
|
|
|
|
|
|
|
|
|
if not rank:
|
2024-06-19 05:32:15 +08:00
|
|
|
|
raise ValueError("职级不存在")
|
2024-06-18 21:54:54 +08:00
|
|
|
|
|
|
|
|
|
super(EmployeeInformation, self).save(*args, **kwargs)
|
2024-06-14 01:59:38 +08:00
|
|
|
|
|
2024-05-15 18:41:23 +08:00
|
|
|
|
class Meta:
|
|
|
|
|
verbose_name = '人员基本信息表'
|
|
|
|
|
verbose_name_plural = '人员基本信息表'
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
|
|
|
2024-06-12 16:40:51 +08:00
|
|
|
|
# 工资变更记录表
|
|
|
|
|
class SalaryChangeRecord(models.Model):
|
|
|
|
|
employee = models.ForeignKey(EmployeeInformation, on_delete=models.CASCADE, related_name='salary_change_records')
|
|
|
|
|
change_date = models.DateField(verbose_name='变更日期')
|
|
|
|
|
previous_value = models.DecimalField(max_digits=15, decimal_places=2, verbose_name='前值')
|
|
|
|
|
new_value = models.DecimalField(max_digits=15, decimal_places=2, verbose_name='最新值')
|
|
|
|
|
approved_by = models.CharField(max_length=255, verbose_name='核准人')
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
verbose_name = '工资变更记录表'
|
|
|
|
|
verbose_name_plural = '工资变更记录表'
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return f"{self.employee.name} - {self.change_date}"
|
|
|
|
|
|
|
|
|
|
|
2024-05-15 18:41:23 +08:00
|
|
|
|
# 员工考勤记录表
|
|
|
|
|
class EmployeeAttendanceRecord(models.Model):
|
|
|
|
|
record_id = models.AutoField(primary_key=True)
|
2024-06-16 14:07:40 +08:00
|
|
|
|
employee = models.ForeignKey('hrm_mgnt.EmployeeInformation', on_delete=models.CASCADE, verbose_name='姓名')
|
2024-05-15 18:41:23 +08:00
|
|
|
|
year_month = models.DateField(verbose_name='年月')
|
|
|
|
|
late = models.IntegerField(default=0, verbose_name='迟到')
|
|
|
|
|
early_leave = models.IntegerField(default=0, verbose_name='早退')
|
|
|
|
|
absenteeism = models.IntegerField(default=0, verbose_name='旷工')
|
|
|
|
|
annual_leave = models.IntegerField(default=0, verbose_name='年假')
|
|
|
|
|
personal_leave = models.IntegerField(default=0, verbose_name='事假')
|
|
|
|
|
sick_leave = models.IntegerField(default=0, verbose_name='病假')
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
verbose_name = '员工考勤记录表'
|
|
|
|
|
verbose_name_plural = '员工考勤记录表'
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return f"{self.employee.name} - {self.year_month.strftime('%Y-%m')}"
|
|
|
|
|
|
|
|
|
|
|
2024-06-12 16:40:51 +08:00
|
|
|
|
# 其他假期详细记录表
|
2024-05-15 18:41:23 +08:00
|
|
|
|
class OtherLeaveDetails(models.Model):
|
2024-06-16 20:17:45 +08:00
|
|
|
|
LEAVE_TYPE_CHOICES = [
|
2024-05-27 23:39:32 +08:00
|
|
|
|
('事假', '事假'),
|
|
|
|
|
('年假', '年假'),
|
|
|
|
|
('病假', '病假'),
|
|
|
|
|
('婚假', '婚假'),
|
|
|
|
|
('丧假', '丧假'),
|
2024-06-16 20:17:45 +08:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
record_id = models.AutoField(primary_key=True)
|
2024-06-18 21:54:54 +08:00
|
|
|
|
attendance_record = models.ForeignKey(EmployeeAttendanceRecord, on_delete=models.CASCADE,
|
|
|
|
|
related_name='other_leaves', verbose_name='考勤记录')
|
2024-06-16 20:17:45 +08:00
|
|
|
|
leave_type = models.CharField(max_length=255, choices=LEAVE_TYPE_CHOICES, verbose_name='假期类型')
|
2024-05-15 18:41:23 +08:00
|
|
|
|
days = models.IntegerField(verbose_name='天数')
|
|
|
|
|
description = models.TextField(verbose_name='说明')
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
verbose_name = '其他假期详细记录'
|
|
|
|
|
verbose_name_plural = '其他假期详细记录'
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return f"{self.leave_type} - {self.days} days"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 年假使用记录
|
|
|
|
|
class AnnualLeaveRecord(models.Model):
|
2024-05-27 23:39:32 +08:00
|
|
|
|
record_id = models.AutoField(primary_key=True, verbose_name='记录编号')
|
2024-05-15 18:41:23 +08:00
|
|
|
|
year = models.IntegerField(verbose_name='年份')
|
2024-06-16 20:17:45 +08:00
|
|
|
|
employee_name = models.CharField(max_length=255, verbose_name='姓名')
|
|
|
|
|
primary_department = models.CharField(max_length=255, verbose_name='一级部门')
|
2024-05-15 18:41:23 +08:00
|
|
|
|
total_annual_leave = models.IntegerField(verbose_name='年假天数')
|
|
|
|
|
used_annual_leave = models.IntegerField(verbose_name='已请年假数')
|
|
|
|
|
remaining_annual_leave = models.IntegerField(verbose_name='剩余年假数')
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
verbose_name = '年假使用记录'
|
2024-05-27 23:39:32 +08:00
|
|
|
|
verbose_name_plural = '年假使用记录表'
|
2024-05-15 18:41:23 +08:00
|
|
|
|
|
|
|
|
|
def __str__(self):
|
2024-06-16 14:07:40 +08:00
|
|
|
|
return f"{self.employee.name} - {self.year}"
|
2024-06-13 00:12:17 +08:00
|
|
|
|
|
|
|
|
|
|
2024-06-14 16:47:43 +08:00
|
|
|
|
# 员工绩效
|
2024-06-13 00:12:17 +08:00
|
|
|
|
class PerformanceEvaluation(models.Model):
|
|
|
|
|
YEAR_CHOICES = [(r, r) for r in range(1980, datetime.date.today().year + 1)]
|
|
|
|
|
|
|
|
|
|
performance_id = models.AutoField(primary_key=True)
|
|
|
|
|
employee = models.ForeignKey(EmployeeInformation, on_delete=models.CASCADE, verbose_name='员工')
|
|
|
|
|
year = models.IntegerField(choices=YEAR_CHOICES, verbose_name='年度')
|
|
|
|
|
performance_score = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='年度绩效')
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
verbose_name = '员工绩效'
|
|
|
|
|
verbose_name_plural = '员工绩效表'
|
|
|
|
|
unique_together = ('employee', 'year')
|
|
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
|
return f"{self.employee.name} - {self.year} - {self.performance_score}"
|