浏览代码

1.加班期间缺卡自动补卡并记录加班时长。
2.加班打卡记录最早打卡和最迟打卡时间,作为开始和结束时间。

zhengqiang 4 年之前
父节点
当前提交
7d23727bbf

+ 1 - 0
common/src/main/java/com/jpsoft/shinestar/modules/base/dao/WorkOverPersonDAO.java

@@ -24,4 +24,5 @@ public interface WorkOverPersonDAO {
     List<WorkOverPerson> findByWorkOverId(String workOverId);
     WorkOverPerson findByPersonIdAndDate(Long personId, Date attendanceDate);
     List<WorkOverPerson> findByPersonIdAndSEDate(Long personId, Date startDate,Date endDate);
+    WorkOverPerson findByPersonIdAndOffsetMinute(Long personId, Date recordTime, int earlyMinutes, int delayMinutes);
 }

+ 11 - 4
common/src/main/java/com/jpsoft/shinestar/modules/base/entity/WorkOverPerson.java

@@ -34,10 +34,6 @@ public class WorkOverPerson {
     private Date updateTime;
     @ApiModelProperty(value = "是否删除")
     private Boolean delFlag = false;
-    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8")
-    @ApiModelProperty(value = "加班完成时间")
-    private Date finishTime;
     @ApiModelProperty(value = "加班时长(分钟)")
     private Integer duration;
     @ApiModelProperty(value = "加班时长描述")
@@ -59,10 +55,21 @@ public class WorkOverPerson {
 
     @ApiModelProperty(value = "审批人名称")
     private String approvalPersonName;
+
     @ApiModelProperty(value = "审批人ID")
     private String approvalPersonId;
 
     private PersonInfo personInfo;
 
     private WorkOver workOver;
+
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8")
+    @ApiModelProperty(value = "加班开始时间")
+    private Date beginTime;
+
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8")
+    @ApiModelProperty(value = "加班完成时间")
+    private Date finishTime;
 }

+ 2 - 0
common/src/main/java/com/jpsoft/shinestar/modules/base/service/WorkOverPersonService.java

@@ -27,4 +27,6 @@ public interface WorkOverPersonService {
     WorkOverPerson findByPersonIdAndDate(Long personId, Date attendanceDate);
 
     List<WorkOverPerson> findByPersonIdAndSEDate(Long personId, Date startDate,Date endDate);
+
+    WorkOverPerson findByPersonIdAndOffsetMinute(Long personId, Date recordTime, int earlyMinutes, int delayMinutes);
 }

+ 2 - 0
common/src/main/java/com/jpsoft/shinestar/modules/base/service/WorkOverService.java

@@ -30,4 +30,6 @@ public interface WorkOverService {
 
 	Date findTopCreateTimeByPersonId(Long personId,Date startDate, Date endDate);
 	Date findTopApprovalTimeByPersonId(Long personId,Date startDate, Date endDate);
+
+    boolean punchIn(String deviceNo, Long personId, Date recordTime);
 }

+ 5 - 0
common/src/main/java/com/jpsoft/shinestar/modules/base/service/impl/WorkOverPersonServiceImpl.java

@@ -88,4 +88,9 @@ public class WorkOverPersonServiceImpl implements WorkOverPersonService {
     public List<WorkOverPerson> findByPersonIdAndSEDate(Long personId, Date startDate,Date endDate){
         return workOverPersonDAO.findByPersonIdAndSEDate(personId,startDate,endDate);
     }
+
+    @Override
+    public WorkOverPerson findByPersonIdAndOffsetMinute(Long personId, Date recordTime, int earlyMinutes, int delayMinutes) {
+        return workOverPersonDAO.findByPersonIdAndOffsetMinute(personId,recordTime,earlyMinutes,delayMinutes);
+    }
 }

+ 52 - 0
common/src/main/java/com/jpsoft/shinestar/modules/base/service/impl/WorkOverServiceImpl.java

@@ -14,9 +14,11 @@ import com.jpsoft.shinestar.modules.workflow.entity.ProcinstActivity;
 import com.jpsoft.shinestar.modules.workflow.service.ProcinstActUserService;
 import com.jpsoft.shinestar.modules.workflow.service.ProcinstActivityService;
 import com.jpsoft.shinestar.modules.workflow.service.ProcinstService;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.poi.poifs.crypt.dsig.facets.XAdESXLSignatureFacet;
 import org.joda.time.DateTime;
+import org.joda.time.Minutes;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
@@ -26,6 +28,7 @@ import com.github.pagehelper.Page;
 import com.jpsoft.shinestar.modules.common.dto.Sort;
 import com.github.pagehelper.PageHelper;
 
+@Slf4j
 @Transactional
 @Component(value="workOverService")
 public class WorkOverServiceImpl implements WorkOverService {
@@ -62,6 +65,9 @@ public class WorkOverServiceImpl implements WorkOverService {
 	@Autowired
 	private ApprovalConfigService approvalConfigService;
 
+	@Autowired
+	private WorkOverService workOverService;
+
 	@Override
 	public WorkOver get(String id) {
 		// TODO Auto-generated method stub
@@ -447,4 +453,50 @@ public class WorkOverServiceImpl implements WorkOverService {
 	public Date findTopApprovalTimeByPersonId(Long personId,Date startDate, Date endDate){
 		return workOverDAO.findTopApprovalTimeByPersonId(personId,startDate, endDate);
 	}
+
+	@Override
+	public boolean punchIn(String deviceNo, Long personId, Date recordTime) {
+		boolean result = false;
+
+		try {
+			//查询当前打卡时间是否在加班时段内
+			WorkOverPerson workOverPerson = workOverPersonService.findByPersonIdAndOffsetMinute(personId, recordTime, -60, 180);
+			WorkOver workOver = workOverService.get(workOverPerson.getWorkOverId());
+
+			//记录加班人员加班完成时间
+			if (workOverPerson != null && workOver != null && "1".equals(workOver.getStatus())) {
+				if (workOverPerson.getBeginTime() == null) {
+					workOverPerson.setBeginTime(recordTime);
+				} else if (recordTime.before(workOverPerson.getBeginTime())) {
+					workOverPerson.setBeginTime(recordTime);
+				}
+
+				if (workOverPerson.getFinishTime() == null) {
+					workOverPerson.setFinishTime(recordTime);
+				} else if (recordTime.after(workOverPerson.getFinishTime())) {
+					workOverPerson.setFinishTime(recordTime);
+				}
+
+				if (workOverPerson.getBeginTime() != null && workOverPerson.getFinishTime() != null) {
+					int minutes = (int) Minutes.minutesBetween(new DateTime(workOverPerson.getBeginTime()), new DateTime(workOverPerson.getFinishTime())).getMinutes();
+					workOverPerson.setDuration(minutes);
+
+					int intHours = minutes / 60;
+					int intMinutes = minutes % 60;
+					workOverPerson.setDurationStr(intHours + "小时" + intMinutes + "分钟");
+				}
+
+				workOverPerson.setUpdateTime(new Date());
+				workOverPersonService.update(workOverPerson);
+			}
+
+			result  = true;
+		}
+		catch (Exception ex){
+			result = false;
+			log.error(ex.getMessage(),ex);
+		}
+
+		return result;
+	}
 }

+ 28 - 14
common/src/main/java/com/jpsoft/shinestar/modules/business/service/impl/WorkScheduleAttendanceServiceImpl.java

@@ -189,6 +189,7 @@ public class WorkScheduleAttendanceServiceImpl implements WorkScheduleAttendance
                 return false;
             }
 
+            workOverService.punchIn(deviceNo,personId,recordTime);
 //            List<String> sceneNameList = deviceInfoService.findSceneListByDeviceNo(deviceNo);
 //
 //            if (!sceneNameList.contains("考勤")) {
@@ -455,6 +456,9 @@ public class WorkScheduleAttendanceServiceImpl implements WorkScheduleAttendance
             endTime = endTime.plusMinutes(Minutes.minutesBetween(meetingStartTime, meetingEndTime).getMinutes());
         }
 
+        //下班结束时间延迟1分钟
+        endTime = endTime.plusMinutes(1);
+
         if (recordTime.compareTo(startTime.toDate()) >= 0 && recordTime.compareTo(endTime.toDate()) <= 0) {
             workEndShift = shiftInfo;
 
@@ -472,17 +476,17 @@ public class WorkScheduleAttendanceServiceImpl implements WorkScheduleAttendance
 
         if (workEndShift != null) {
             //记录加班人员加班完成时间
-            if(workOverPerson!=null && workOver!=null && "1".equals(workOver.getStatus())){
-                workOverPerson.setUpdateTime(recordTime);
-                workOverPerson.setFinishTime(recordTime);
-                Integer minuteLong = (int) DateUtil.between(workOver.getStartTime(),recordTime, DateUnit.MINUTE);
-                workOverPerson.setDuration(minuteLong);
-
-                int intHours = minuteLong / 60;
-                int intMinutes = minuteLong % 60;
-                workOverPerson.setDurationStr(intHours+"小时" + intMinutes + "分钟");
-                workOverPersonService.update(workOverPerson);
-            }
+//            if(workOverPerson!=null && workOver!=null && "1".equals(workOver.getStatus())){
+//                workOverPerson.setUpdateTime(recordTime);
+//                workOverPerson.setFinishTime(recordTime);
+//                Integer minuteLong = (int) DateUtil.between(workOver.getStartTime(),recordTime, DateUnit.MINUTE);
+//                workOverPerson.setDuration(minuteLong);
+//
+//                int intHours = minuteLong / 60;
+//                int intMinutes = minuteLong % 60;
+//                workOverPerson.setDurationStr(intHours+"小时" + intMinutes + "分钟");
+//                workOverPersonService.update(workOverPerson);
+//            }
 
             //查询该班次是否已有下班班打卡记录,打卡本身是按照升序传输
             List<WorkScheduleAttendance> attendanceList = findByPersonScheduleIdAndClassify(workPersonScheduling.getId(), workEndShift.getId(), "2");
@@ -946,12 +950,13 @@ public class WorkScheduleAttendanceServiceImpl implements WorkScheduleAttendance
             }
 
             WorkOverPerson workOverPerson = workOverPersonService.findByPersonIdAndDate(personInfo.getId(),attendanceTime.toDate());
+            WorkOver workOver = null;
 
             //加班时如果是下班则考勤截止时间顺延
             if ("2".equals(classify)){
                 if(workOverPerson!=null){
                     //说明下班后被安排了加班
-                    WorkOver workOver = workOverService.get(workOverPerson.getWorkOverId());
+                    workOver = workOverService.get(workOverPerson.getWorkOverId());
 
                     if(workOver!=null && workOver.getHours()!=null) {
                         endTime = endTime.plusHours(workOver.getHours());
@@ -1012,8 +1017,17 @@ public class WorkScheduleAttendanceServiceImpl implements WorkScheduleAttendance
                         }
                     }
 
-                    //查询人员单日是否有加班
-                    if(workOverPerson!=null){
+                    //查询人员考勤时段是否有加班
+                    if(workOverPerson!=null && workOver!=null){
+                        if("1".equals(classify)){
+                            //上班打卡考勤缺卡,则记录实际加班时间为安排加班时间
+                            workOverPerson.setBeginTime(workOver.getStartTime());
+                            workOverPerson.setFinishTime(workOver.getEndTime());
+                            workOverPerson.setUpdateTime(new Date());
+
+                            workOverPersonService.update(workOverPerson);
+                        }
+
                         saveWorkAttendance(personInfo.getId(), new BigDecimal(0), attendanceTime.toDate(), dateStr,
                                 personScheduleId, workShiftId, "1", 0, classify, "1",workOverPerson);
 

+ 40 - 16
common/src/main/resources/mapper/base/WorkOverPerson.xml

@@ -12,7 +12,6 @@
         <result property="updateBy" column="update_by" />
         <result property="updateTime" column="update_time" />
         <result property="delFlag" column="del_flag" />
-        <result property="finishTime" column="finish_time"/>
         <result property="duration" column="duration_"/>
         <result property="durationStr" column="duration_str"/>
         <result property="personName" column="person_name" />
@@ -22,6 +21,8 @@
         <result property="personId" column="person_id" />
         <result property="approvalPersonId" column="approval_person_id" />
         <result property="approvalPersonName" column="approval_person_name" />
+        <result property="beginTime" column="begin_time" />
+        <result property="finishTime" column="finish_time"/>
     </resultMap>
     <insert id="insert" parameterType="com.jpsoft.shinestar.modules.base.entity.WorkOverPerson">
         <!--
@@ -31,20 +32,22 @@
         -->
         <![CDATA[
 		insert into base_work_over_person
-	    (id_,person_popedom_id,work_over_id,create_by,create_time,update_by,update_time,del_flag,finish_time,duration_,duration_str)
+	    (id_,person_popedom_id,work_over_id,create_by,create_time,update_by,update_time,del_flag,finish_time,
+	    duration_,duration_str,begin_time)
 		values
 		(
-#{id,jdbcType=VARCHAR}
-,#{personPopedomId,jdbcType=VARCHAR}
-,#{workOverId,jdbcType=VARCHAR}
-,#{createBy,jdbcType=VARCHAR}
-,#{createTime,jdbcType= TIMESTAMP }
-,#{updateBy,jdbcType=VARCHAR}
-,#{updateTime,jdbcType= TIMESTAMP }
-,#{delFlag,jdbcType= NUMERIC }
-,#{finishTime,jdbcType=TIMESTAMP}
-,#{duration,jdbcType=INTEGER}
-,#{durationStr,jdbcType=VARCHAR}
+            #{id,jdbcType=VARCHAR}
+            ,#{personPopedomId,jdbcType=VARCHAR}
+            ,#{workOverId,jdbcType=VARCHAR}
+            ,#{createBy,jdbcType=VARCHAR}
+            ,#{createTime,jdbcType= TIMESTAMP }
+            ,#{updateBy,jdbcType=VARCHAR}
+            ,#{updateTime,jdbcType= TIMESTAMP }
+            ,#{delFlag,jdbcType= NUMERIC }
+            ,#{finishTime,jdbcType=TIMESTAMP}
+            ,#{duration,jdbcType=INTEGER}
+            ,#{durationStr,jdbcType=VARCHAR}
+            ,#{beginTime,jdbcType= TIMESTAMP }
 		)
 	]]>
     </insert>
@@ -84,6 +87,9 @@
             <if test="durationStr!=null">
                 duration_str=#{durationStr,jdbcType=VARCHAR }
             </if>
+            <if test="beginTime!=null">
+                begin_time=#{beginTime,jdbcType= TIMESTAMP },
+            </if>
         </set>
         where id_=#{id}
     </update>
@@ -176,8 +182,8 @@
 		        ( c.hours_ , 0 ) as hours_
             FROM
                 base_work_over_person a
-            inner join base_person_popedom b on a.person_popedom_id = b.id_
-            inner join base_work_over c on a.work_over_id = c.id_
+                inner join base_person_popedom b on a.person_popedom_id = b.id_
+                inner join base_work_over c on a.work_over_id = c.id_
             where
                 b.person_id = #{personId}
                 and c.start_time>=#{startDate}
@@ -187,5 +193,23 @@
                 and c.del_flag = 0
         ]]>
     </select>
-
+    <select id="findByPersonIdAndOffsetMinute" resultMap="WorkOverPersonMap">
+        <![CDATA[
+            SELECT
+                a.*,
+                c.start_time,
+                c.end_time
+            FROM
+                base_work_over_person a
+                inner join base_person_popedom b on a.person_popedom_id = b.id_
+                inner join base_work_over c on a.work_over_id = c.id_
+            where
+                b.person_id = #{personId}
+                and date_add(c.start_time,interval ${earlyMinutes} minute)<=#{recordTime}
+                and date_add(c.end_time,interval ${delayMinutes} minute)>=#{recordTime}
+                and (c.status_='1' or c.status_ = '4')
+                and a.del_flag=0
+                and c.del_flag = 0
+        ]]>
+    </select>
 </mapper>