You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django的Payslip模型中筛选CWorkAttendance授权出勤记录?

解决方案:筛选授权考勤记录并生成薪资单

Alright, let's break down how to implement this logic step by step. Here's what you need to do:


1. 筛选授权的CWorkAttendance记录

首先,我们要从CWorkAttendance中过滤出所有状态为**授权(AUTHORIZED)**的记录。利用模型中定义的常量可以避免硬编码,让代码更易维护:

from .models import CWorkAttendance

# 获取所有授权的考勤记录,同时关联员工表避免N+1查询
authorized_attendances = CWorkAttendance.objects.filter(
    work_entry_status=CWorkAttendance.AUTHORIZED
).select_related('work_employee')

使用select_related('work_employee')可以一次性加载关联的CEmployees数据,提升查询效率。


2. 按员工分组统计工时数据

薪资单是按员工生成的,所以我们需要对授权考勤记录按员工分组,统计总工作时长、加班时长等核心数据。这里用到Django的聚合函数Sum:

from django.db.models import Sum

# 按员工分组,统计总工作秒数(假设work_duration存储的是秒)
employee_work_summary = authorized_attendances.values('work_employee').annotate(
    total_work_seconds=Sum('work_duration')
)

注意:如果你的work_duration存储的是分钟/小时,需要自行转换为秒,方便后续薪资计算。


3. 整合逻辑生成Payslip记录

接下来,我们可以编写一个函数,结合员工的薪资费率(从CEmployees表获取),计算薪资总额并创建Payslip记录。首先需要确保CEmployees模型包含所需的费率字段(你提到要从主表获取,这里假设模型已有这些字段):

补充CEmployees模型(示例)

class CEmployees(models.Model):
    # 其他员工字段(姓名、工号等)
    basic_hourly_rate = models.IntegerField()  # 基本时薪
    ot_hourly_rate = models.IntegerField()     # 加班时薪

生成薪资单的核心函数

from datetime import datetime
from django.db.models import Sum
from .models import CWorkAttendance, Payslip, CEmployees

def generate_payslip(employee: CEmployees, from_date: datetime.date):
    # 筛选该员工在指定起始日期后的所有授权考勤
    employee_attendances = CWorkAttendance.objects.filter(
        work_employee=employee,
        work_entry_status=CWorkAttendance.AUTHORIZED,
        work_start_time__gte=from_date
    ).select_related('work_employee')
    
    # 统计总工作秒数,若没有记录则默认0
    total_work_seconds = employee_attendances.aggregate(Sum('work_duration'))['work_duration__sum'] or 0
    total_work_hours = total_work_seconds // 3600  # 转换为小时
    
    # 计算加班时长(假设每月标准工时为160小时,可根据实际规则调整)
    standard_monthly_seconds = 160 * 3600
    total_ot_seconds = max(0, total_work_seconds - standard_monthly_seconds)
    basic_work_seconds = total_work_seconds - total_ot_seconds
    
    # 从员工表获取费率
    basic_rate = employee.basic_hourly_rate
    ot_rate = employee.ot_hourly_rate
    
    # 计算薪资总额
    basic_amount = (basic_work_seconds / 3600) * basic_rate
    ot_amount = (total_ot_seconds / 3600) * ot_rate
    total_amount = round(basic_amount + ot_amount, 2)
    
    # 生成符合要求的薪资单号(MM/YY/自增数)
    current_month_year = datetime.now().strftime("%m/%y")
    # 获取当月已生成的薪资单数量,自增编号
    monthly_payslip_count = Payslip.objects.filter(
        payslip_generation_date__month=datetime.now().month,
        payslip_generation_date__year=datetime.now().year
    ).count() + 1
    # 注意:如果payslip_number要存带斜杠的格式,建议把模型字段改成CharField(max_length=15)
    payslip_number = f"{current_month_year}/{monthly_payslip_count:04d}"  # 示例:08/24/0001
    
    # 创建Payslip记录
    payslip = Payslip.objects.create(
        payslip_number=payslip_number,
        payslip_employee=employee,
        payslip_generation_date=datetime.now(),
        payslip_total_hours=total_work_hours,
        payslip_from_date=from_date,
        payslip_total_basic_seconds=basic_work_seconds,
        payslip_total_ot_seconds=total_ot_seconds,
        payslip_basic_hourly_rate=basic_rate,
        payslip_basic_ot_rate=ot_rate,
        payslip_total_amount=total_amount,
        payslip_entry_status=Payslip.GENERATED
    )
    return payslip

4. 批量生成薪资单(可选)

如果需要给所有员工批量生成薪资单,可以循环CEmployees的记录,调用上述函数:

def bulk_generate_payslips(from_date: datetime.date):
    employees = CEmployees.objects.all()
    for employee in employees:
        generate_payslip(employee, from_date)

注意事项

  • 薪资单号字段调整:当前你的Payslip模型中payslip_number是IntegerField,但如果要存储MM/YY/自增数这种带斜杠的格式,建议改成CharField(max_length=15),否则会报错。
  • 加班规则自定义:上述示例中的加班计算规则是假设每月标准160小时,你可以根据公司实际考勤政策调整逻辑。
  • 日期范围优化:如果需要生成指定日期区间的薪资单,可以在filter中添加work_start_time__lte=to_date参数,限定结束日期。

内容的提问来源于stack exchange,提问作者Unknown Username

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:14:09