diff --git a/finance/views.py b/finance/views.py index 3e43995..4a49ac6 100644 --- a/finance/views.py +++ b/finance/views.py @@ -1324,40 +1324,126 @@ class UserDeparture(APIView): user.state = "已离职" user.save(update_fields=['Dateofdeparture', 'state']) - # 创建离职审批记录 - today = datetime.datetime.now() - formatted_date = today.strftime("%Y-%m-%d") + # 根据团队类型判断是否需要审批 + # 规则: + # - 个人团队(personal/独立律师):不触发审批 + # - 团队(team/团队律师):需要审批,直接选择某个人,审批人需要指定结算工资 + from User.models import Team - # 统一使用personincharge字段(统一规则:纯数字字符串=部门ID,非纯数字字符串=审批员用户名) - if personincharge: - # 判断是部门ID还是审批员用户名 + # 获取用户的团队信息 + team_name = user.team # 用户的团队名称(CharField) + team = None + if team_name: + try: + team = Team.objects.get(name=team_name, is_deleted=False) + except Team.DoesNotExist: + # 如果团队不存在,默认按团队类型处理(需要审批) + pass + + # 判断是否需要审批 + if team and team.team_type == 'personal': + # 个人团队(独立律师):不触发审批,直接完成 + # 不创建审批记录,但记录日志 + new_data = { + 'user_id': user.id, + 'username': user.username, + 'Dateofdeparture': Dateofdeparture, + 'state': user.state, + 'team_type': 'personal', + 'note': '个人团队,无需审批' + } + log_operation( + request=request, + operation_type='CREATE', + module='Finance', + action='新增离职财务登记(个人团队)', + target_type='User', + target_id=user.id, + target_name=user.username, + new_data=new_data, + remark=f'新增离职财务登记:{user.username},离职时间 {Dateofdeparture}(个人团队,无需审批)' + ) + else: + # 团队类型(团队律师):需要审批,必须指定审批人 + settlement_salary = request.data.get('settlement_salary') # 结算工资(可选,审批人可以后续填写) + + if not personincharge: + return Response({ + 'status': 'error', + 'message': '团队类型需要指定审批人,请选择审批人', + 'code': 1 + }, status=status.HTTP_400_BAD_REQUEST) + + # 验证审批人是否存在(personincharge应该是用户名,不是部门ID) from User.utils import is_department_id if is_department_id(personincharge): - # 如果是部门ID,验证部门是否存在 - try: - department = Department.objects.get(id=int(personincharge)) - except (Department.DoesNotExist, ValueError): - return Response({'status': 'error', 'message': '审批部门不存在', 'code': 1}, status=status.HTTP_400_BAD_REQUEST) - personincharge_value = format_personincharge(personincharge, is_department=is_department_id(personincharge)) - else: - personincharge_value = "" - - Approval.objects.create( - title=username + "离职财务登记", - content=username + "在" + Dateofdeparture + "办理离职登记", - times=formatted_date, - personincharge=personincharge_value, - state='审核中', - type="离职财务登记", - user_id=str(user.id) - ) + # 不允许使用部门ID,必须直接选择某个人 + return Response({ + 'status': 'error', + 'message': '请直接选择审批人(用户名),不能使用部门ID', + 'code': 1 + }, status=status.HTTP_400_BAD_REQUEST) + + # 验证审批人用户是否存在 + try: + approver = User.objects.get(username=personincharge, is_deleted=False) + except User.DoesNotExist: + return Response({ + 'status': 'error', + 'message': f'审批人"{personincharge}"不存在或已被删除', + 'code': 1 + }, status=status.HTTP_404_NOT_FOUND) + + # 创建离职审批记录 + today = datetime.datetime.now() + formatted_date = today.strftime("%Y-%m-%d") + + # 构建审批内容,包含结算工资信息(如果已提供) + content_parts = [f"{username}在{Dateofdeparture}办理离职登记"] + if settlement_salary: + content_parts.append(f"结算工资:{settlement_salary}元") + else: + content_parts.append("结算工资:待审批人指定") + content = ",".join(content_parts) + + approval = Approval.objects.create( + title=username + "离职财务登记", + content=content, + times=formatted_date, + personincharge=personincharge, # 直接使用审批人用户名 + state='审核中', + type="离职财务登记", + user_id=str(user.id) + ) + + # 记录操作日志 + new_data = { + 'user_id': user.id, + 'username': user.username, + 'Dateofdeparture': Dateofdeparture, + 'state': user.state, + 'approver': personincharge, + 'settlement_salary': settlement_salary if settlement_salary else '待审批人指定' + } + log_operation( + request=request, + operation_type='CREATE', + module='Finance', + action='新增离职财务登记', + target_type='User', + target_id=user.id, + target_name=user.username, + new_data=new_data, + remark=f'新增离职财务登记:{user.username},离职时间 {Dateofdeparture},审批人 {personincharge}' + ) return Response({ 'message': '离职登记成功', 'code': 0, 'data': { 'has_cases': False, - 'case_count': 0 + 'case_count': 0, + 'needs_approval': team is None or team.team_type != 'personal' # 是否需要审批 } }, status=status.HTTP_200_OK) diff --git a/模型修改建议.md b/模型修改建议.md new file mode 100644 index 0000000..6e51be7 --- /dev/null +++ b/模型修改建议.md @@ -0,0 +1,84 @@ +# 模型修改建议 + +## 当前实现分析 + +### 现状 +1. **结算工资存储方式**:目前结算工资信息存储在 `Approval.content` 字段中,作为文本内容的一部分 +2. **审批处理**:审批处理接口(`approvalProcessing`)中还没有处理"离职财务登记"类型的审批 +3. **数据查询**:如果结算工资只存在文本中,后续查询和统计会比较困难 + +## 建议:添加 `settlement_salary` 字段 + +### 推荐方案:添加可选字段 + +**优点**: +1. ✅ **便于查询和统计**:可以单独查询和统计结算工资数据 +2. ✅ **便于更新**:审批人可以单独更新结算工资,不需要解析和替换文本 +3. ✅ **数据结构清晰**:结算工资作为独立字段,结构更清晰 +4. ✅ **向后兼容**:设为可选字段,不影响现有数据 + +**缺点**: +1. ⚠️ 需要数据库迁移 +2. ⚠️ 需要更新相关代码 + +### 建议的模型修改 + +在 `Approval` 模型中添加: + +```python +class Approval(models.Model): + title = models.CharField(max_length=100) + content = models.TextField() # 内容 + times = models.DateField() # 提交时间 + completeTiem = models.DateField(null=True, blank=True, default=None) # 完成时间 + personincharge = models.CharField(max_length=100) # 负责人/审批部门 + state = models.CharField(max_length=100) # 状态 + type = models.CharField(max_length=100) # 类别 + user_id = models.CharField(max_length=100) # 事件id + settlement_salary = models.CharField(max_length=100, null=True, blank=True) # 结算工资(仅离职财务登记使用) + is_deleted = models.BooleanField(default=False) # 软删除标记 +``` + +### 是否需要修改? + +#### 如果只是简单使用(当前方案) +- ❌ **不需要修改模型** +- 结算工资存在 `content` 文本中 +- 适合:不需要单独查询和统计结算工资的场景 + +#### 如果需要更好的数据管理(推荐) +- ✅ **建议修改模型** +- 添加 `settlement_salary` 字段 +- 适合:需要查询、统计、单独更新结算工资的场景 + +## 我的建议 + +**建议添加 `settlement_salary` 字段**,原因: + +1. **审批人需要指定结算工资**:如果只存在文本中,审批人更新时需要解析和替换文本,比较麻烦 +2. **财务统计需求**:结算工资是重要的财务数据,可能需要单独查询和统计 +3. **数据完整性**:作为独立字段,数据更规范,便于后续扩展 + +## 实施步骤(如果决定修改) + +1. **修改模型**:在 `Approval` 模型中添加 `settlement_salary` 字段 +2. **创建迁移**:`python manage.py makemigrations` +3. **执行迁移**:`python manage.py migrate` +4. **更新代码**: + - 修改 `UserRegister` 接口,保存结算工资到字段 + - 修改 `approvalProcessing` 接口,支持更新结算工资 + - 修改相关查询接口,返回结算工资字段 + +## 当前实现(不修改模型) + +如果决定不修改模型,当前实现已经可以工作: +- 结算工资存在 `content` 中 +- 审批人可以查看和修改(通过修改content文本) +- 适合简单场景 + +## 总结 + +- **简单场景**:不修改模型也可以,结算工资存在文本中 +- **推荐方案**:添加 `settlement_salary` 字段,便于管理和查询 + +您希望采用哪种方案? diff --git a/离职登记接口优化说明.md b/离职登记接口优化说明.md new file mode 100644 index 0000000..369f2c5 --- /dev/null +++ b/离职登记接口优化说明.md @@ -0,0 +1,243 @@ +# 离职登记接口优化说明 + +## 优化内容 + +根据需求11,离职登记接口已优化,**根据团队类型自动判断是否需要审批**,审批人需要指定结算工资。 + +## 接口信息 + +- **URL**:`/finance/user-departure` +- **方法**:POST +- **功能**:离职财务登记 + +## 审批逻辑(需求11) + +根据用户的**所属团队类型**自动判断是否需要审批: + +### 个人团队(personal/独立律师) +- ❌ **不触发审批** +- 离职登记直接完成,不创建审批记录 +- 用户状态直接更新为"已离职" + +### 团队(team/团队律师) +- ✅ **需要审批** +- 必须指定审批人(`personincharge` 字段,必填) +- 审批人必须是用户名(不能使用部门ID) +- **审批人需要指定结算工资** +- 审批通过后,再抄送财务 + +## 请求参数 + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| username | string | 是 | 用户名 | +| Dateofdeparture | string | 是 | 离职时间(格式:YYYY-MM-DD) | +| personincharge | string | 条件必填 | 审批人用户名(仅团队类型必填) | +| settlement_salary | string | 否 | 结算工资(可选,审批人可以后续填写) | + +## 请求示例 + +### 个人团队(不需要审批人) + +```json +POST /finance/user-departure +{ + "username": "张三", + "Dateofdeparture": "2024-01-15" +} +``` + +**说明**:个人团队不触发审批,不需要提供 `personincharge` 和 `settlement_salary` + +### 团队(需要审批人) + +```json +POST /finance/user-departure +{ + "username": "李四", + "Dateofdeparture": "2024-01-15", + "personincharge": "王五", + "settlement_salary": "5000" +} +``` + +**说明**: +- 团队类型必须提供审批人用户名 +- `settlement_salary` 可选,如果未提供,审批内容会显示"结算工资:待审批人指定" + +## 响应示例 + +### 成功响应 + +```json +{ + "message": "离职登记成功", + "code": 0, + "data": { + "has_cases": false, + "case_count": 0, + "needs_approval": true + } +} +``` + +**字段说明**: +- `has_cases`: 是否有未转移的案件 +- `case_count`: 未转移案件数量 +- `needs_approval`: 是否需要审批(true=团队类型,false=个人团队) + +### 错误响应 + +#### 缺少必填参数 +```json +{ + "status": "error", + "message": "缺少参数:用户名和离职时间不能为空", + "code": 1 +} +``` + +#### 用户不存在 +```json +{ + "status": "error", + "message": "用户不存在或已被删除", + "code": 1 +} +``` + +#### 有未转移的案件 +```json +{ + "status": "error", + "message": "该用户还有3个案件未转移,请先转移案件后再进行离职登记", + "code": 1, + "data": { + "has_cases": true, + "case_count": 3, + "cases": [ + { + "id": 1, + "times": "2024-01-01", + "client_username": "客户A", + "party_username": "对方B", + "description": "案件描述" + } + ] + } +} +``` + +#### 团队类型未提供审批人 +```json +{ + "status": "error", + "message": "团队类型需要指定审批人,请选择审批人", + "code": 1 +} +``` + +#### 使用了部门ID(不允许) +```json +{ + "status": "error", + "message": "请直接选择审批人(用户名),不能使用部门ID", + "code": 1 +} +``` + +#### 审批人不存在 +```json +{ + "status": "error", + "message": "审批人\"王五\"不存在或已被删除", + "code": 1 +} +``` + +#### 日期格式错误 +```json +{ + "status": "error", + "message": "离职时间格式错误,请使用YYYY-MM-DD格式", + "code": 1 +} +``` + +## 审批内容格式 + +### 包含结算工资 +``` +张三在2024-01-15办理离职登记,结算工资:5000元 +``` + +### 未包含结算工资(待审批人指定) +``` +李四在2024-01-15办理离职登记,结算工资:待审批人指定 +``` + +**说明**:审批人可以在审批时修改结算工资信息。 + +## 工作流程 + +### 个人团队流程 +``` +提交离职登记 + ↓ +检查是否有未转移案件 + ↓ +更新用户状态为"已离职" + ↓ +完成(不创建审批) +``` + +### 团队流程 +``` +提交离职登记 + ↓ +检查是否有未转移案件 + ↓ +验证审批人 + ↓ +更新用户状态为"已离职" + ↓ +创建审批记录(状态:审核中) + ↓ +等待审批人审批并指定结算工资 + ↓ +审批通过后抄送财务 +``` + +## 注意事项 + +1. **案件转移** + - 如果用户有未转移的案件,必须先转移案件才能离职 + - 系统会返回未转移案件的详细信息 + +2. **团队设置** + - 确保用户在人事管理中已正确设置所属团队 + - 团队必须在团队管理中已创建 + +3. **审批人选择** + - 必须直接选择某个人(用户名) + - 不能使用部门ID + - 审批人必须是有效的用户 + +4. **结算工资** + - 可以在提交时提供 `settlement_salary` + - 如果未提供,审批内容会显示"待审批人指定" + - 审批人可以在审批时修改结算工资 + +5. **操作日志** + - 所有离职登记操作都会记录到操作日志 + - 个人团队和团队类型的日志内容不同 + +## 更新日志 + +### v2.0.0 (2024-01-XX) +- ✅ 根据团队类型自动判断是否需要审批 +- ✅ 个人团队(personal/独立律师):不触发审批 +- ✅ 团队(team/团队律师):需要审批,必须指定审批人 +- ✅ 审批人必须直接选择某个人(用户名),不能使用部门ID +- ✅ 支持结算工资字段(可选) +- ✅ 审批内容包含结算工资信息