最近为工作在写一套考勤系统。
考勤数据采集、请假单、出差单、加班单,还有班次时间段管理、人员管理等都写好了。
最后冲关考勤日报的生成处理,思考了三天,头脑还是一片迷糊,上来CSDN放松放松,看看有没有处理过和考勤系统的指点一下。
头脑纠结的地方:
1、每天四次卡:上班上下班、下午下下班。
2、如果中午只打了一次,那这个得根据上、下午是否请假或出差来放到相应时间点。
3、加班起始或结束的时间可能是跟正常下班或上班的时间连到一起的。
4、加班会加到隔天去。
5、公司是大小周制,一周上6天,一周上5天。
6、正常情况下周日是休息日,如果碰上国家放假调整,可能就会出现反常。
7、部分部门采用加班单跟上班间双重确认的方式来认定是否计加班,另外的部分则不写加班单,只按实际打卡时间。如果取当天离上班时间最近的刷卡时间做为上班卡,也会出现因夜间加班到早上4、5点,故上午不去上班的状况,就会错把加班的下班卡当做上午的上班卡了。
如果取下班最近的时间点,则会把加班时间给丢了。如果加班到隔天,这个又要怎么取。
每个时间点都很好几个因素挂上关系,绕来绕去。脑子里头越想越多,越想越复杂,越想越不知道从何着手。
连大方向都迷失了
唉工厂的考勤比一般公司复杂多了。
求救命啊,脑子要炸开了我就是想给每个员工每天生成一记录,记录他的上班各个时间段的打卡时间,加班的打卡时间,加班时长、请假时长、迟到时间、早退时长
判断究意是节假日呢还是正常工作日,加班开始时间如果跟下班时间重叠则不计异常哪怕是最没效率,最笨的方法都想不到了。
写了几年的程序,第一次这么纠结,非常膜拜那些专业的HR系统开发人员

解决方案 »

  1.   

    考勤最核心的内容就是考勤算法,考勤时间段的设置直接影响考勤算法的效率。
    1、每天四次卡:上班上下班、下午下下班。
     A: 无论多少次,都是时间段,时间段包括:开始上班时间,上班时间,上班考勤结束时间,下班开始时间,下班时间,下班结束时间。这样处理之后,你这里只不过是使用两个时间段而已。
    2、如果中午只打了一次,那这个得根据上、下午是否请假或出差来放到相应时间点。
    A:请假要预先计算,有请假,就不计算考勤
    3、加班起始或结束的时间可能是跟正常下班或上班的时间连到一起的。
    A:确定了下班结束时间,就可以剥离加班。可使用选项处理。
    4、加班会加到隔天去。
    A:加班时间按照0点进行分割,之前的算作前一天。
    5、公司是大小周制,一周上6天,一周上5天。
    A:增加选项,算法上只不过是多计算一天。
    6、正常情况下周日是休息日,如果碰上国家放假调整,可能就会出现反常。
    A:国家放假要单独设置,优先考虑放假、休假、出差,所有的这些都是考勤异常的内容。
    7、部分部门采用加班单跟上班间双重确认的方式来认定是否计加班,另外的部分则不写加班单,只按实际打卡时间。
    A:这里要有一个标准或者设定,无论哪种形式的加班肯定是有条件的,比如:下班多久后算加班?可以使用选项进行处理。另外原始记录和最终考勤计算结果是要分开的,每个人,每一天都要有一条考勤记录,记录人员的ID,上下班时间及考勤异常等情况。
      

  2.   

    我想不到什么有效率的方法,只能把该员工当天的记录取出来,然后把这些记录分别传到变量:当天最早、离早班上班前最近、离早班上班后最近,离早班上班前最近,离早班下班后最近,离下午班上班前最近、离下午班上班后最近,离下午班下班前最近,离下午班下班后最近,当天最晚。
    然后根据班次起始时间,把可能异常一一提出判断,把相应变量传给员工考勤日报表。
    if  then
    else
    if  then
    else
    if then
    else
    .
    .
    .
    头都晕了。。
      

  3.   

        if dstCLog['fCheckTime'] <= T11 then
        begin
          X1 := dstCLog['fCheckTime']
        end
        else
        begin
          if (dstCLog['fCheckTime'] > T11) and (dstCLog['fCheckTime'] < T2) then
          begin
            if C1 = '' then
              C1 := dstCLog['fCheckTime'];
            C2 := dstCLog['fCheckTime'];
          end
          else
            if (dstCLog['fCheckTime'] >= T2) and (dstCLog['fCheckTime'] <= T3) then
            begin
              if X2 = '' then
                X2 := dstCLog['fCheckTime'];
              X3 := dstCLog['fCheckTime'];
            end
            else
              if (dstCLog['fCheckTime'] > T3) and (dstCLog['fCheckTime'] < T44) then
              begin
                if C3 = '' then
                  C3 := dstCLog['fCheckTime'];
                C4 := dstCLog['fCheckTime'];
              end
              else
                if dstCLog['fCheckTime'] >= T44 then
                  X4 := dstCLog['fCheckTime']
        end;
        dstCLog.Next;
      end;
      

  4.   

    楼主可以借鉴一下主流的HR系统供应商,多了解几家HR系统的处理流程,依我看,考勤的核心计算基本上都是通过庞大的SQL存储过程来实现的,不防往这方面下功夫,Delphi界面不外呼就是一些数据控件
      

  5.   

    一些GGYY的设置,建议放在SP中去搞。
      

  6.   

    确实在存储过程中来实现是比较有效率的。
    第一次做这个考勤处理,先在delphi中来实现,有了成熟的处理过程再过去。
      

  7.   

    在后台写过程 函数,其它据逻辑,写好,如 getValidtime(Tady:datetime)..... 这个肯定要写好多过程,函数 ,这样规则变时 只修改后台就OK 了,前台就一些公式规则的录入 ,计算全部后台,前台仅报表呈现…………一点点想法 真正也没乍写过考勤
      

  8.   

    班段(确定上下班时间点)
    班次(确定每天上下班时间点,及工作天如何分割)
    排班(确认个人每天上下班时间点)请假及出差(影响上下班时间点,假别影响薪资)
    加班(影响上下班时间点,加班类型可能影响薪资)
    异常上下班(时间点修正,也可以通过重建一个班次来实现,但异常是有原因备查的,修改月排班则往往没有原因说明)以上可推算出每天每个班段的上下班时间点,通过匹配算法,匹配每天打卡,每次打卡。
    这是固定时间点上下班的算法,是必须支持的。
    另外的浮动时间点上下班的匹配算法则不需要具体的上下班时间点,请假与加班方式影响也不一样。迟到早退计法(迟到早退另计还是在班段工时中直接扣,还是每天累加......)、
    加班工时计法(固定班段为加班,还是超8小时为加班,周日工时回补平时上班,跨天加班计法.....)
    旷工计法(打一次卡是否为旷工,还是当天工时为0就旷工?...因为需要做旷工统计及旷工提醒)
    自动补卡规则(出差自动补卡,缺卡批量自动补卡,补卡统计影响薪资)
    周日算法(周日双倍,何为周日,这个有多种解释,需要制定具体规则,然后依规则计算周日)
    国假日算法( 法定国假日不支持跨天,固定为0时交割。)
    夜班津贴计法(也就是分时段计工时)
    ......
    除了这些的算法规则外,还得应付使用上的一些要求:
    自动倒班,依打卡时间定班次,当班查岗支持,班次复制修改,批量作业,入职离职当天特别打卡支持及识别离职时间点。
    检测与处理不合理现象(如:时间冲突(加班与上班冲突,排班冲突.....),请假期间代打卡(可能录入错误的请假时间),跨天加班异常.....)。多种多样的考勤规则,业务逻辑复杂。当前实现支持到哪一步,是考勤软件需要考虑的。
    我不建议用SQL语言实现全部考勤计算过程,当支持的规则多了,实测结果SQL实现的计算速度也比不上App计算。